diff --git a/.config/CredScanSuppressions.json b/.config/CredScanSuppressions.json index c384837b3..6afbaced4 100644 --- a/.config/CredScanSuppressions.json +++ b/.config/CredScanSuppressions.json @@ -18,11 +18,27 @@ "_justification": "Legitimate development X.509 Certificate Private Key" }, { - "file": "src/BenchmarksApps/TLS/HttpSys/testCert.pfx", + "file": "src/BenchmarksApps/TLS/Certificates/2048/testCert-2048.pfx", "_justification": "Legitimate development X.509 Certificate Private Key" }, { - "file": "src/BenchmarksApps/TLS/Kestrel/testCert.pfx", + "file": "src/BenchmarksApps/TLS/Certificates/2048/cert.pem", + "_justification": "Legitimate development X.509 Certificate Private Key" + }, + { + "file": "src/BenchmarksApps/TLS/Certificates/2048/key.pem", + "_justification": "Legitimate development X.509 Certificate Private Key" + }, + { + "file": "src/BenchmarksApps/TLS/Certificates/4096/testCert-4096.pfx", + "_justification": "Legitimate development X.509 Certificate Private Key" + }, + { + "file": "src/BenchmarksApps/TLS/Certificates/4096/cert.pem", + "_justification": "Legitimate development X.509 Certificate Private Key" + }, + { + "file": "src/BenchmarksApps/TLS/Certificates/4096/key.pem", "_justification": "Legitimate development X.509 Certificate Private Key" }, { diff --git a/scenarios/tls.benchmarks.yml b/scenarios/tls.benchmarks.yml index 8e7f50e20..2fb2b8f16 100644 --- a/scenarios/tls.benchmarks.yml +++ b/scenarios/tls.benchmarks.yml @@ -1,6 +1,7 @@ imports: - https://raw.githubusercontent.com/dotnet/crank/main/src/Microsoft.Crank.Jobs.Bombardier/bombardier.yml - https://raw.githubusercontent.com/dotnet/crank/main/src/Microsoft.Crank.Jobs.HttpClient/httpclient.yml + - https://github.com/dotnet/crank/blob/main/src/Microsoft.Crank.Jobs.Wrk/wrk.yml?raw=true - https://github.com/aspnet/Benchmarks/blob/main/scenarios/aspnet.profiles.yml?raw=true - https://github.com/aspnet/Benchmarks/blob/main/build/azure.profile.yml?raw=true @@ -18,11 +19,12 @@ jobs: # behavioral settings mTLS: false # enables settings on http.sys to negotiate client cert on connections tlsRenegotiation: false # enables client cert validation + certPublicKeyLength: 2048 # controls cert with such a length is used for the test # debug settings certValidationConsoleEnabled: false statsEnabled: false logRequestDetails: false - arguments: "--urls https://{{serverAddress}}:{{serverPort}} --mTLS {{mTLS}} --certValidationConsoleEnabled {{certValidationConsoleEnabled}} --statsEnabled {{statsEnabled}} --tlsRenegotiation {{tlsRenegotiation}} --logRequestDetails {{logRequestDetails}}" + arguments: "--urls https://{{serverAddress}}:{{serverPort}} --mTLS {{mTLS}} --certValidationConsoleEnabled {{certValidationConsoleEnabled}} --statsEnabled {{statsEnabled}} --tlsRenegotiation {{tlsRenegotiation}} --logRequestDetails {{logRequestDetails}} --certPublicKeyLength {{certPublicKeyLength}}" kestrelServer: source: @@ -35,11 +37,12 @@ jobs: mTLS: false tlsRenegotiation: false tlsProtocols: "tls12,tls13" + certPublicKeyLength: 2048 # controls cert with such a length is used for the test # debug settings certValidationConsoleEnabled: false statsEnabled: false logRequestDetails: false - arguments: "--urls https://{{serverAddress}}:{{serverPort}} --mTLS {{mTLS}} --certValidationConsoleEnabled {{certValidationConsoleEnabled}} --tlsProtocols {{tlsProtocols}} --statsEnabled {{statsEnabled}} --tlsRenegotiation {{tlsRenegotiation}} --logRequestDetails {{logRequestDetails}}" + arguments: "--urls https://{{serverAddress}}:{{serverPort}} --mTLS {{mTLS}} --certValidationConsoleEnabled {{certValidationConsoleEnabled}} --tlsProtocols {{tlsProtocols}} --statsEnabled {{statsEnabled}} --tlsRenegotiation {{tlsRenegotiation}} --logRequestDetails {{logRequestDetails}} --certPublicKeyLength {{certPublicKeyLength}}" dockerLinuxKestrelServer: sources: @@ -58,6 +61,19 @@ jobs: certValidationConsoleEnabled: false statsEnabled: false + dockerLinuxNginxServer: + sources: + dockerNginx: + repository: https://github.com/aspnet/benchmarks.git + branchOrCommit: main + dockerFile: dockerNginx/src/BenchmarksApps/TLS/Nginx/Dockerfile + dockerImageName: dockerNginx + dockerContextDirectory: dockerNginx/src/BenchmarksApps/TLS + port: 8080 + readyStateText: Application started. + environmentVariables: + urls: "https://*:8080" # any ip, port 8080 + scenarios: # HTTP.SYS @@ -65,6 +81,8 @@ scenarios: tls-handshakes-httpsys: application: job: httpSysServer + variables: + certPublicKeyLength: 2048 load: job: httpclient variables: @@ -78,14 +96,12 @@ scenarios: application: job: httpSysServer variables: + certPublicKeyLength: 2048 mTLS: true # enables settings on http.sys to negotiate client cert on connections tlsRenegotiation: true # enables client cert validation - certValidationConsoleEnabled: false # only for debug purposes - serverPort: 8080 # IMPORTANT: not to intersect with other tests in case http.sys configuration impacts other benchmarks load: job: httpclient variables: - serverPort: 8080 # in sync with server path: /hello-world presetHeaders: connectionclose connections: 32 @@ -98,9 +114,8 @@ scenarios: application: job: httpSysServer variables: - mTLS: false + certPublicKeyLength: 2048 tlsRenegotiation: true - certValidationConsoleEnabled: false # only for debug purposes load: job: httpclient variables: @@ -117,6 +132,8 @@ scenarios: tls-handshakes-kestrel: application: job: kestrelServer + variables: + certPublicKeyLength: 2048 load: job: httpclient variables: @@ -130,8 +147,8 @@ scenarios: application: job: kestrelServer variables: + certPublicKeyLength: 2048 mTLS: true - certValidationConsoleEnabled: false # only for debug purposes load: job: httpclient variables: @@ -147,9 +164,9 @@ scenarios: application: job: kestrelServer variables: + certPublicKeyLength: 2048 mTLS: false tlsRenegotiation: true - certValidationConsoleEnabled: false # only for debug purposes load: job: httpclient variables: @@ -221,6 +238,21 @@ scenarios: job: dockerLinuxKestrelServer # openssl version is already pre-installed with base image (latest) dockerFile: dockerKestrel/src/BenchmarksApps/TLS/Kestrel/Dockerfile.azurelinux + load: + job: httpclient + variables: + path: /hello-world + serverPort: 8080 + presetHeaders: connectionclose + connections: 32 + serverScheme: https + sslProtocol: tls12 + + tls-handshakes-docker-nginx: + application: + job: dockerLinuxNginxServer + buildArguments: + - CERT_KEY_LENGTH=2048 load: job: httpclient variables: diff --git a/src/BenchmarksApps/TLS/Certificates/2048/cert.pem b/src/BenchmarksApps/TLS/Certificates/2048/cert.pem new file mode 100644 index 000000000..cfd3b7981 --- /dev/null +++ b/src/BenchmarksApps/TLS/Certificates/2048/cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrTCCApWgAwIBAgIUHKdletylaQOCsLr2hYlAx7CtYNUwDQYJKoZIhvcNAQEL +BQAwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xFTATBgNVBAoMDEV4YW1wbGUgQ29ycDEWMBQGA1UECwwN +SVQgRGVwYXJ0bWVudDEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjUwNDAxMTE1 +MTU1WhcNMjYwNDAxMTE1MTU1WjB/MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs +aWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEVMBMGA1UECgwMRXhhbXBs +ZSBDb3JwMRYwFAYDVQQLDA1JVCBEZXBhcnRtZW50MRQwEgYDVQQDDAtleGFtcGxl +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtHEw2SKpAIBN/M +zYNHdeUBr/+rl70+NULPOCNtHLBWxgb5qkhUi+weU3Szyju6ahYWeWLSmll9pEA8 +dyrR0D6OHo39o6RqH4KNHBMyIM3b1zvYdQCoXWFIBaLMzgS4I6YorMmiaIdd/rjT +4IerkewQUidRUKD517dogWNwE8rP75joEGBPkTdA1g5EvqdrZFMEqfjvISr8VPns +05BVBjOLpFmipKh+kgDvvnqENJKKUN3U34LobYuq+eJHgQljvE5NCF7lq3GtaGsB +pVu1BnMmxA9mlxeEXbV7XcDbU4uYu03RG1b0zTNPf35YFTCj7ENe+xSwzpOEX7os +zuBco+kCAwEAAaMhMB8wHQYDVR0OBBYEFOI/5fWJQJ7i4FDRi6LcINvIbjQ+MA0G +CSqGSIb3DQEBCwUAA4IBAQA0MIxYSs3VI8DGQE/FLkNyDjVGK01LRliyTL6EEiAm +I9PiCq5WYH+29u8wJV6YeveQ00EUx0IbHOo1Ojki0oDByNjnEU2JKEr+FeSi320Q +GT9kn/tQuTTHZMIlqFOO+01f15ApaEyfOhDS1qC1zZWyjXSNC7/bVT1wVlH+hBGl +n/VnaarlE4IQjH7XlVplYNwN6Cpl4796ns5q9nfQIFyePxJmUptvsaLWkICcF8fL +oZfbxFLc8l/xT/vFpzHga096Ruhvqqolj7oGY2eFxAf/oUZqWPIa4zCP3WUaWPeU +sBIETpjNwtjcrScm6D+DQO4B5eixCtrK51ye5/2t0Jb7 +-----END CERTIFICATE----- diff --git a/src/BenchmarksApps/TLS/Certificates/2048/key.pem b/src/BenchmarksApps/TLS/Certificates/2048/key.pem new file mode 100644 index 000000000..d5870a3ce --- /dev/null +++ b/src/BenchmarksApps/TLS/Certificates/2048/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7RxMNkiqQCATf +zM2DR3XlAa//q5e9PjVCzzgjbRywVsYG+apIVIvsHlN0s8o7umoWFnli0ppZfaRA +PHcq0dA+jh6N/aOkah+CjRwTMiDN29c72HUAqF1hSAWizM4EuCOmKKzJomiHXf64 +0+CHq5HsEFInUVCg+de3aIFjcBPKz++Y6BBgT5E3QNYORL6na2RTBKn47yEq/FT5 +7NOQVQYzi6RZoqSofpIA7756hDSSilDd1N+C6G2LqvniR4EJY7xOTQhe5atxrWhr +AaVbtQZzJsQPZpcXhF21e13A21OLmLtN0RtW9M0zT39+WBUwo+xDXvsUsM6ThF+6 +LM7gXKPpAgMBAAECggEABxOKxcLVzDbGsF+AYyB/yj/DvbO8emXFBMQ9s8ul/4fC +gyBLQzZmnxe6QY5K6vItRgO4DHg2utZDhDsvVDU0sC3AkSREsFa44BRNkPAeSzOu +W1A02OnZCsRPlN+LkqQT5222sbEVpV/I2y+uVpIGDoHDXkGf+/p/ddUDZpV6j07h +bsJCmXsNGWgy3PvF/WvLPS1PQ4ktVku2k9MdDoTVxOB1WipFw5mnO8Pe0v24gJuK +QQLnQXUneRI53+2eU5iekdYp8RXxIsZIx37zysuUvKA5cfLCMztEcOgPor9/Zbph +8SnUrMgSnbQGtEQA+jILtiUX3zAzfxnqdZIENIG+8QKBgQD2G2A6RJ3CzoFbh3dK +C4ihGmHBR39w4eW9mpqzb9+a0bZzKdgPGML7dYeFz9Zr7WpJRKpsrvuOkm9m8h27 +T7rbVRNveKaJB35VwqEm+wFKg6z6ORWQmjYr0BObxF4wv41unmPN8BmliVVkQKQd +B89xhZmpcYg1d8aC/+8jcxVHPQKBgQDCzk0Uio113qNDROJxsbiVtAOFvcL9kFhs +EewRjc9dE6eujhO290ZoiEKz8V4zOpsz0mMJuS0/pM2wJNXWRzDN+UCmYboqpT0T +O1cXRDMt8NLb6RxAn66lhj66s1oTVflYhHHm9Ytxf960EsvtmCHIJvYldy4/YP9H +BPgM0wr6HQKBgHrcLczI5m0TBHb6CK45Vcr/TZ/cnp1u2G8wGFzN07YJTWjukcLv +nJ9GDBLcL/IPQsky81VwgXqqVdzxr7AL3H+UWDCE7bZovEP59tNr6TgWxirghoh6 +w+JZbQCNJmx1pBh+D9sGKvd9uNhkgMlRVdkZVh3F5La0hbBuLibnU88NAoGAPAjh +/lOYttuPCvseohU4IoKgl0Xc4tHqPhvj2aEPZ8rX4VaNwtQ/0ZU0oUngUv9bt0O+ +G9ACntuGPCON9wRniQKopt31RpE32kZuV5BACYdvJDCZ8VyEsSRHDriZKN5VAq+G +frvrZmYW1v339NfuiUVglDk/em7FHTjtzN35Qw0CgYBqc1Dcz7vOs7sHQr2cslEI +dGAwlV9F3D8bYgKt2cYtgbNIK6gfmZmJBbfVTtwataV9oV2o6cbeNK8SL7qScc3R +Pbu3UNpFk7cBlHi9OVJwdpZaYG8ITkQGvwa8V6+EwgzOKcrHgBC9Efso20v32SyN +9JJgBEYMrvx2awpN+af1iA== +-----END PRIVATE KEY----- diff --git a/src/BenchmarksApps/TLS/Certificates/2048/testCert-2048.pfx b/src/BenchmarksApps/TLS/Certificates/2048/testCert-2048.pfx new file mode 100644 index 000000000..3137a521b Binary files /dev/null and b/src/BenchmarksApps/TLS/Certificates/2048/testCert-2048.pfx differ diff --git a/src/BenchmarksApps/TLS/Certificates/4096/cert.pem b/src/BenchmarksApps/TLS/Certificates/4096/cert.pem new file mode 100644 index 000000000..19fb060b4 --- /dev/null +++ b/src/BenchmarksApps/TLS/Certificates/4096/cert.pem @@ -0,0 +1,35 @@ +Bag Attributes + localKeyID: 6A 28 3F AA A7 FF FC 12 9D F2 4C C0 E7 52 11 86 C7 92 62 19 +subject=CN = localhost + +issuer=CN = localhost + +-----BEGIN CERTIFICATE----- +MIIFCzCCAvOgAwIBAgIUAi7DqcEn4EsBm1lN4UcmmuxWPq0wDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTIxMDIyNjE4MzI0OVoYDzIxMjEw +MjAyMTgzMjQ5WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDI5+DbDLpVmRFFB9YR1NwAbdPzf7cV8RB32pNVHzLj +iJ9LNSq8yvI/k6xD3p8XHVJEC3TGMuOVK4Cn277nX9KSU/7lELMlz+yGikwli3aI +u4A7NE84ACfR6ZFelAGcGr2nMze6K2YDwhhqG8SUBIhAjzjIXSf2+cv0Cq38cEX1 +WKy1h5xJm7FwuKlZsHmJw5Osk+8mFgHJ5TmKqJYtVd7b/ytAmeM2ByZ4eVCZ31rR +ELKZ2uEWoCImLCtCfohxEnhrLm09yB7JrbbT/3JXHXyQUn3kGMczgwL/IZZwqtAf +E4SiHVLI3cFwO3VJjpRfAbg3xFbxwzhmdlri3WsKT3iEp3P08WPi6dL7WF+PjpMl +d9RZ587NBSqCmVfgBjY05wEcONSPyPY1gi5ZBDBm6J23feAOgZ8AZu/RKdAVgYBu +Kr6o6ZKqsJ+U+M5cwrXw/Rv78YQyr9ZlfKALbybMKMrYuc9DqbPGBbryLxklh9kN +wMJvt8FHEcmlbT5BsZJmm7JztPouN7mxMy1ZVJlGreyPD0mxET+O4DCz7UsA2CvB +pKzLcRRHKKNbCwaeV/1UJKiyg4QWDGltlIKkIEhppv2vspl0Gh7xpZISJuWtmWiJ +o03zSr7NUNvXRY3pmNQXad7PHanVyTCopCCpTiAQljDTTb803NGyKBHx3cz17HU9 +xQIDAQABo1MwUTAdBgNVHQ4EFgQUGyQOi+8yPBZziF7ruCfQB4ooTMUwHwYDVR0j +BBgwFoAUGyQOi+8yPBZziF7ruCfQB4ooTMUwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAHf+FN6rHdZJPdmUO1skpS9iVgXrKWGwo20Qrd3MttKfk +xzFpOZLBEyn/qWmZe1YQqdcm4Yd7OjnKRb62zwE8gyTJlaA30qXGoJZrouWEAsWZ +2//2h/Ju6XNy47p5F2UKAKqqGcSaDy9HEQF0wNwRz45LKYlJE7v7eDqo2TOampoH +UXNRF9lKI4o+CKkSRquoqGXfw6GJmnxrozTzWl00igSXrX3+HkiKHNOgzaOoS+pP +nFl/HI/jOFYh8AG/18U5iFBSTjXiyXmFvkb4309c188fJd1UMOVY1tbcfFWSftnL +Ybk8UmGagtI9S8ExuQvk34TGDwj0vdKGiTBdL/qQ1vzxqLo2U7fHRcktSo27Ogtp +JCzfyXKb41Cu4VOmzllTlhbg/p68rEeYcVIeZl86Yh3bFZNVpvHW9vzn8iLIXpGf +nyt/XXG0cgkTPeWZ+zTPHLx/9YZBXViUuXobXLeUhueCaWGHYPkzKcV1c1B9oJjc +/3JWbJVERFxMGgJpQUrTMerUCmY3C2lfPBm48ZmPCjmUUdWsh5vu2pVe+3hBIFeb +Y/kkOuRqAmiW+EmjFNQNdcxsDstd1AeipapPSH0TLWTqvAs8MndoNmfHyOFomV38 +Els5LL5Pomm27oVq6JM1geF1jKShAnO/w/dlRXcB0PFJIlpWKpw7OE5qqPpoiZY= +-----END CERTIFICATE----- diff --git a/src/BenchmarksApps/TLS/Certificates/4096/key.pem b/src/BenchmarksApps/TLS/Certificates/4096/key.pem new file mode 100644 index 000000000..a1b7ce67f --- /dev/null +++ b/src/BenchmarksApps/TLS/Certificates/4096/key.pem @@ -0,0 +1,55 @@ +Bag Attributes + localKeyID: 6A 28 3F AA A7 FF FC 12 9D F2 4C C0 E7 52 11 86 C7 92 62 19 +Key Attributes: +-----BEGIN PRIVATE KEY----- +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 +lOZIsIthM9vRTfPNs6cuapFulsL0qWM= +-----END PRIVATE KEY----- diff --git a/src/BenchmarksApps/TLS/Certificates/4096/testCert-4096.pfx b/src/BenchmarksApps/TLS/Certificates/4096/testCert-4096.pfx new file mode 100644 index 000000000..8c1c24b63 Binary files /dev/null and b/src/BenchmarksApps/TLS/Certificates/4096/testCert-4096.pfx differ diff --git a/src/BenchmarksApps/TLS/Certificates/README.md b/src/BenchmarksApps/TLS/Certificates/README.md new file mode 100644 index 000000000..fbd0a8ca0 --- /dev/null +++ b/src/BenchmarksApps/TLS/Certificates/README.md @@ -0,0 +1,5 @@ +# Certificates + +Certificate public-key length contributes to performant significantly, therefore there are 2 sets of certificates in corresponding directories ([2048 bit](./2048/) and [4096 bit](./4096/)). + +Both directories have a `testCert.pfx` and `cert.pem`/`key.pem` (different certs, but same key-length). diff --git a/src/BenchmarksApps/TLS/HttpSys/NetShWrapper.cs b/src/BenchmarksApps/TLS/HttpSys/NetSh/NetShWrapper.cs similarity index 92% rename from src/BenchmarksApps/TLS/HttpSys/NetShWrapper.cs rename to src/BenchmarksApps/TLS/HttpSys/NetSh/NetShWrapper.cs index 99b0ddf71..fc1d457ea 100644 --- a/src/BenchmarksApps/TLS/HttpSys/NetShWrapper.cs +++ b/src/BenchmarksApps/TLS/HttpSys/NetSh/NetShWrapper.cs @@ -1,9 +1,8 @@ using System.Diagnostics; using System.Security.Cryptography.X509Certificates; using System.Text.RegularExpressions; -using HttpSys.NetSh; -namespace HttpSys +namespace HttpSys.NetSh { public class NetShWrapper { @@ -41,20 +40,16 @@ public void DeleteBindingIfExists(string ipPort) { DeleteBinding(ipPort); } - catch + catch (Exception ex) { - // ignore + Console.WriteLine($"Failed to delete binding on port {ipPort}: " + ex); } } public void DeleteBinding(string ipPort) { - Console.WriteLine("Disabling mTLS for http.sys"); - - string command = $"http delete sslcert ipport={ipPort}"; + var command = $"http delete sslcert ipport={ipPort}"; ExecuteNetShCommand(command); - - Console.WriteLine("Disabled http.sys settings for mTLS"); } public bool TryGetSslCertBinding(string ipPort, out SslCertBinding result) @@ -168,23 +163,23 @@ public void SetTestCertBinding(string ipPort, bool enableClientCertNegotiation) store.Close(); } - string certThumbprint = certificate.Thumbprint; + var certThumbprint = certificate.Thumbprint; AddCertBinding(ipPort, certThumbprint, clientCertNegotiation: enableClientCertNegotiation ? NetShFlag.Enable : NetShFlag.Disabled); Console.WriteLine("Configured binding for testCert for http.sys"); } - public bool TrySelfSignCertificate(string ipPort, out string certThumbprint) + public bool TrySelfSignCertificate(string ipPort, int certPublicKeyLength, out string certThumbprint) { certThumbprint = string.Empty; try { // Extract the IP address from ipPort - string ipAddress = ipPort.Split(':')[0]; + var ipAddress = ipPort.Split(':')[0]; // Generate a self-signed certificate using PowerShell - string command = $"New-SelfSignedCertificate -CertStoreLocation cert:\\LocalMachine\\My -DnsName {ipAddress}"; - string output = ExecutePowershellCommand(command); + var command = $"New-SelfSignedCertificate -CertStoreLocation cert:\\LocalMachine\\My -DnsName {ipAddress} -KeyAlgorithm RSA -KeyLength {certPublicKeyLength}"; + var output = ExecutePowershellCommand(command); // Extract the thumbprint from the output var lines = output.Split("\r\n", StringSplitOptions.RemoveEmptyEntries); @@ -241,7 +236,7 @@ private void CertBindingCore( var clientcertnegotiationFlag = GetFlagValue(clientcertnegotiation); var disablesessionidFlag = GetFlagValue(disablesessionid); var enablesessionticketFlag = GetFlagValue(enablesessionticket); - string command = $"http {httpOperation} sslcert ipport={ipPort} certstorename=MY certhash={certThumbprint} appid={{{appId}}}"; + var command = $"http {httpOperation} sslcert ipport={ipPort} certstorename=MY certhash={certThumbprint} appid={{{appId}}}"; if (clientcertnegotiationFlag != null) { @@ -280,7 +275,7 @@ private static string ExecuteNetShCommand(string command, bool ignoreErrorExit = private static string ExecuteCommand(string fileName, string command, bool ignoreErrorExit = false, bool logOutput = false) { - ProcessStartInfo processInfo = new ProcessStartInfo(fileName, command) + var processInfo = new ProcessStartInfo(fileName, command) { RedirectStandardOutput = true, RedirectStandardError = true, @@ -289,8 +284,8 @@ private static string ExecuteCommand(string fileName, string command, bool ignor }; Console.WriteLine($"Executing command: `{fileName} {command}`"); - using Process process = Process.Start(processInfo)!; - string output = process.StandardOutput.ReadToEnd(); + using var process = Process.Start(processInfo)!; + var output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); if (logOutput) diff --git a/src/BenchmarksApps/TLS/HttpSys/NetSh/NetshConfigurator.cs b/src/BenchmarksApps/TLS/HttpSys/NetSh/NetshConfigurator.cs new file mode 100644 index 000000000..172f50986 --- /dev/null +++ b/src/BenchmarksApps/TLS/HttpSys/NetSh/NetshConfigurator.cs @@ -0,0 +1,76 @@ +namespace HttpSys.NetSh +{ + public static class NetshConfigurator + { + private static readonly NetShWrapper _netshWrapper = new(); + private static string _certThumbprint; + + private static string _resetCertThumbprint; + + public static SslCertBinding PreConfigureNetsh( + string httpsIpPort, + int certPublicKeyLength = 2048, + NetShFlag clientCertNegotiation = NetShFlag.Disabled, + NetShFlag disablesessionid = NetShFlag.Enable, + NetShFlag enableSessionTicket = NetShFlag.Disabled) + { + // we will anyway reconfigure the netsh certificate binding, so we can delete it firstly + // and also delete a certificate which is bound to the netsh + if (_netshWrapper.TryGetSslCertBinding(httpsIpPort, out var sslCertBinding)) + { + SslCertificatesConfigurator.RemoveCertificate(sslCertBinding.CertificateThumbprint); + _netshWrapper.DeleteBindingIfExists(httpsIpPort); + } + + if (!_netshWrapper.TrySelfSignCertificate(httpsIpPort, certPublicKeyLength, out _certThumbprint)) + { + throw new ApplicationException($"Failed to setup ssl binding for '{httpsIpPort}'."); + } + + _netshWrapper.AddCertBinding( + httpsIpPort, + _certThumbprint, + disablesessionid: disablesessionid, + enablesessionticket: enableSessionTicket, + clientCertNegotiation: clientCertNegotiation); + + if (!_netshWrapper.TryGetSslCertBinding(httpsIpPort, out sslCertBinding)) + { + throw new NetshException($"Failed to setup ssl binding for '{httpsIpPort}'. Please unblock the VM."); + } + + return sslCertBinding; + } + + public static void LogCurrentSslCertBinding(string httpsIpPort) + => _netshWrapper.LogSslCertBinding(httpsIpPort); + + public static void PrepareResetNetsh(string httpsIpPort, int certPublicKeyLength = 4096) + { + if (!_netshWrapper.TrySelfSignCertificate(httpsIpPort, certPublicKeyLength, out _resetCertThumbprint)) + { + throw new ApplicationException($"Failed to self-sign a cert for '{httpsIpPort}'."); + } + } + + public static void ResetNetshConfiguration(string httpsIpPort) + { + // delete cert binding and cert itself. We want it to be as clean and deterministic as possible (even if more actions are performed) + _netshWrapper.DeleteBindingIfExists(httpsIpPort); + SslCertificatesConfigurator.RemoveCertificate(_certThumbprint); + + if (string.IsNullOrEmpty(_resetCertThumbprint)) + { + throw new ApplicationException($"Reset certificate is not prepared for '{httpsIpPort}'."); + } + + // reset certificate was prepared in advance - just bind it at this moment + _netshWrapper.AddCertBinding( + httpsIpPort, + _resetCertThumbprint, + disablesessionid: NetShFlag.NotSet, + enablesessionticket: NetShFlag.NotSet, + clientCertNegotiation: NetShFlag.NotSet); + } + } +} diff --git a/src/BenchmarksApps/TLS/HttpSys/NetSh/NetshException.cs b/src/BenchmarksApps/TLS/HttpSys/NetSh/NetshException.cs new file mode 100644 index 000000000..f17e1d2d0 --- /dev/null +++ b/src/BenchmarksApps/TLS/HttpSys/NetSh/NetshException.cs @@ -0,0 +1,18 @@ +namespace HttpSys.NetSh +{ + public class NetshException : Exception + { + public NetshException(string message) : base(message) + { + } + public NetshException(string message, Exception innerException) : base(message, innerException) + { + } + public NetshException(string message, string command) : base($"{message} Command: {command}") + { + } + public NetshException(string message, string command, Exception innerException) : base($"{message} Command: {command}", innerException) + { + } + } +} diff --git a/src/BenchmarksApps/TLS/HttpSys/NetSh/SslCertificatesConfigurator.cs b/src/BenchmarksApps/TLS/HttpSys/NetSh/SslCertificatesConfigurator.cs new file mode 100644 index 000000000..f87dded28 --- /dev/null +++ b/src/BenchmarksApps/TLS/HttpSys/NetSh/SslCertificatesConfigurator.cs @@ -0,0 +1,35 @@ +using System.Security.Cryptography.X509Certificates; + +namespace HttpSys.NetSh +{ + public static class SslCertificatesConfigurator + { + public static void RemoveCertificate(string thumbprint) + { + try + { + using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine)) + { + store.Open(OpenFlags.ReadWrite); + + var certs = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, validOnly: false); + if (certs.Count == 0) + { + Console.WriteLine("Certificate not found."); + } + + foreach (var cert in certs) + { + store.Remove(cert); + Console.WriteLine($"Deleted certificate (store LocalMachine/My): {cert.Subject}"); + } + store.Close(); + } + } + catch (Exception ex) + { + Console.WriteLine($"Remove certificate (thumbprint='{thumbprint}') error: {ex.Message}"); + } + } + } +} diff --git a/src/BenchmarksApps/TLS/HttpSys/Program.cs b/src/BenchmarksApps/TLS/HttpSys/Program.cs index febb261f2..ad2007b1a 100644 --- a/src/BenchmarksApps/TLS/HttpSys/Program.cs +++ b/src/BenchmarksApps/TLS/HttpSys/Program.cs @@ -10,6 +10,10 @@ // behavioral var mTlsEnabled = bool.TryParse(builder.Configuration["mTLS"], out var mTlsEnabledConfig) && mTlsEnabledConfig; var tlsRenegotiationEnabled = bool.TryParse(builder.Configuration["tlsRenegotiation"], out var tlsRenegotiationEnabledConfig) && tlsRenegotiationEnabledConfig; +var certPublicKeySpecified = int.TryParse(builder.Configuration["certPublicKeyLength"], out var certPublicKeyConfig); +var certPublicKeyLength = certPublicKeySpecified ? certPublicKeyConfig : 2048; + +// endpoints var listeningEndpoints = builder.Configuration["urls"] ?? "https://localhost:5000/"; var httpsIpPort = listeningEndpoints.Split(";").First(x => x.Contains("https")).Replace("https://", ""); @@ -18,45 +22,15 @@ var statsEnabled = bool.TryParse(builder.Configuration["statsEnabled"], out var connectionStatsEnabledConfig) && connectionStatsEnabledConfig; var logRequestDetails = bool.TryParse(builder.Configuration["logRequestDetails"], out var logRequestDetailsConfig) && logRequestDetailsConfig; -var mTLSNetShFlag = mTlsEnabled ? NetShFlag.Enable : NetShFlag.Disabled; - -var netshWrapper = new NetShWrapper(); - -// verify there is an netsh http sslcert binding for specified ip:port -if (!netshWrapper.TryGetSslCertBinding(httpsIpPort, out var sslCertBinding)) -{ - Console.WriteLine($"No binding existed. Need to self-sign it and bind to '{httpsIpPort}'"); - if (!netshWrapper.TrySelfSignCertificate(httpsIpPort, out var originalCertThumbprint)) - { - throw new ApplicationException($"Failed to setup ssl binding for '{httpsIpPort}'. Please unblock the VM."); - } - netshWrapper.AddCertBinding( - httpsIpPort, - originalCertThumbprint, - disablesessionid: NetShFlag.Enable, - enablesessionticket: NetShFlag.Disabled, - clientCertNegotiation: mTLSNetShFlag); -} +var sslCertConfiguration = NetshConfigurator.PreConfigureNetsh( + httpsIpPort, + certPublicKeyLength: certPublicKeyLength, + clientCertNegotiation: mTlsEnabled ? NetShFlag.Enable : NetShFlag.Disabled, + disablesessionid: NetShFlag.Enable, + enableSessionTicket: NetShFlag.Disabled); -Console.WriteLine("Current netsh ssl certificate binding: \n" + sslCertBinding); - -if ( - // those flags can be set only on later versions of HTTP.SYS; so only considering mTLS here - (netshWrapper.SupportsDisableSessionId && sslCertBinding.DisableSessionIdTlsResumption != NetShFlag.Enable) - || (netshWrapper.SupportsEnableSessionTicket && (sslCertBinding.EnableSessionTicketTlsResumption == NetShFlag.Enable)) - || sslCertBinding.NegotiateClientCertificate != mTLSNetShFlag) -{ - Console.WriteLine($"Need to prepare ssl-cert binding for the run."); - Console.WriteLine($"Expected configuration: mTLS={mTLSNetShFlag}; disableSessionId={NetShFlag.Enable}; enableSessionTicket={NetShFlag.Disabled}"); - - netshWrapper.UpdateCertBinding( - httpsIpPort, - sslCertBinding.CertificateThumbprint, - appId: sslCertBinding.ApplicationId, - disablesessionid: NetShFlag.Enable, - enablesessionticket: NetShFlag.Disabled, - clientCertNegotiation: mTLSNetShFlag); -} +// because app shutdown is on a timeout, we need to prepare the reset (pre-generate certificate) +NetshConfigurator.PrepareResetNetsh(httpsIpPort, certPublicKeyLength: 4096); #pragma warning disable CA1416 // Can be launched only on Windows (HttpSys) builder.WebHost.UseHttpSys(options => @@ -143,7 +117,7 @@ await app.StartAsync(); -netshWrapper.LogSslCertBinding(httpsIpPort); +NetshConfigurator.LogCurrentSslCertBinding(httpsIpPort); Console.WriteLine("Application Info:"); if (mTlsEnabled) @@ -165,11 +139,6 @@ await app.WaitForShutdownAsync(); Console.WriteLine("Application stopped."); -if (netshWrapper.TryGetSslCertBinding(httpsIpPort, out sslCertBinding) && mTLSNetShFlag == NetShFlag.Enable) -{ - // update the sslCert binding to disable "negotiate client cert" (aka mTLS) to not break other tests. - Console.WriteLine($"Rolling back mTLS setting for sslCert binding at '{httpsIpPort}'"); - - sslCertBinding.NegotiateClientCertificate = NetShFlag.Disabled; - netshWrapper.UpdateCertBinding(httpsIpPort, sslCertBinding); -} \ No newline at end of file +Console.WriteLine("Starting netsh rollback configuration..."); +NetshConfigurator.ResetNetshConfiguration(httpsIpPort); +Console.WriteLine($"Reset netsh (ipport={httpsIpPort}) completed."); \ No newline at end of file diff --git a/src/BenchmarksApps/TLS/HttpSys/testCert.pfx b/src/BenchmarksApps/TLS/HttpSys/testCert.pfx deleted file mode 100644 index e03e6d539..000000000 Binary files a/src/BenchmarksApps/TLS/HttpSys/testCert.pfx and /dev/null differ diff --git a/src/BenchmarksApps/TLS/Kestrel/Kestrel.csproj b/src/BenchmarksApps/TLS/Kestrel/Kestrel.csproj index 418d7adf5..de39cbecb 100644 --- a/src/BenchmarksApps/TLS/Kestrel/Kestrel.csproj +++ b/src/BenchmarksApps/TLS/Kestrel/Kestrel.csproj @@ -20,4 +20,15 @@ + + + + + PreserveNewest + + + PreserveNewest + + + diff --git a/src/BenchmarksApps/TLS/Kestrel/Program.cs b/src/BenchmarksApps/TLS/Kestrel/Program.cs index bd5a29645..e81ec832f 100644 --- a/src/BenchmarksApps/TLS/Kestrel/Program.cs +++ b/src/BenchmarksApps/TLS/Kestrel/Program.cs @@ -19,6 +19,10 @@ // behavioral var mTlsEnabled = bool.TryParse(builder.Configuration["mTLS"], out var mTlsEnabledConfig) && mTlsEnabledConfig; var tlsRenegotiationEnabled = bool.TryParse(builder.Configuration["tlsRenegotiation"], out var tlsRenegotiationEnabledConfig) && tlsRenegotiationEnabledConfig; +var certPublicKeySpecified = int.TryParse(builder.Configuration["certPublicKeyLength"], out var certPublicKeyConfig); +var certPublicKeyLength = certPublicKeySpecified ? certPublicKeyConfig : 2048; + +// endpoints var listeningEndpoints = builder.Configuration["urls"] ?? "https://localhost:5000/"; var supportedTlsVersions = ParseSslProtocols(builder.Configuration["tlsProtocols"]); @@ -49,8 +53,11 @@ void ConfigureListen(KestrelServerOptions serverOptions, IConfigurationRoot conf serverOptions.Listen(endpoint, listenOptions => { + var certificatePath = Path.Combine("certificates", $"testCert-{certPublicKeyLength}.pfx"); + Console.WriteLine($"Using certificate: {certificatePath}"); + // [SuppressMessage("Microsoft.Security", "CSCAN0220.DefaultPasswordContexts", Justification="Benchmark code, not a secret")] - listenOptions.UseHttps("testCert.pfx", "testPassword", options => + listenOptions.UseHttps(certificatePath, "testPassword", options => { if (supportedTlsVersions is not null) { diff --git a/src/BenchmarksApps/TLS/Kestrel/testCert.pfx b/src/BenchmarksApps/TLS/Kestrel/testCert.pfx deleted file mode 100644 index e03e6d539..000000000 Binary files a/src/BenchmarksApps/TLS/Kestrel/testCert.pfx and /dev/null differ diff --git a/src/BenchmarksApps/TLS/Nginx/Dockerfile b/src/BenchmarksApps/TLS/Nginx/Dockerfile new file mode 100644 index 000000000..00ba95d87 --- /dev/null +++ b/src/BenchmarksApps/TLS/Nginx/Dockerfile @@ -0,0 +1,21 @@ +FROM nginx:latest + +# or 4096 key length +ARG CERT_KEY_LENGTH=2048 + +# Copy configuration +COPY Nginx/config/nginx.conf /etc/nginx/nginx.conf +COPY Nginx/config/start-nginx.sh /start-nginx.sh + +# Copy SSL certificates +COPY Certificates/${CERT_KEY_LENGTH}/cert.pem /etc/nginx/certs/cert.pem +COPY Certificates/${CERT_KEY_LENGTH}/key.pem /etc/nginx/certs/key.pem + +# Make the script executable +RUN chmod +x /start-nginx.sh + +# Expose port 8080 for HTTPS traffic +EXPOSE 8080 + +# Run the startup script +CMD ["/start-nginx.sh"] \ No newline at end of file diff --git a/src/BenchmarksApps/TLS/Nginx/config/nginx.conf b/src/BenchmarksApps/TLS/Nginx/config/nginx.conf new file mode 100644 index 000000000..059ca69fe --- /dev/null +++ b/src/BenchmarksApps/TLS/Nginx/config/nginx.conf @@ -0,0 +1,44 @@ +worker_processes 4; +worker_cpu_affinity 0001 0010 0100 1000; + +events { + worker_connections 1024; +} + + +http { + # uncomment the following to enable SSL data logging (protocol + cipher) + + # log_format ssl_logs '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for" ' + # '[$ssl_protocol] [$ssl_cipher]'; + + # access_log /var/log/nginx/access.log ssl_logs; + access_log off; + + server { + listen 8080 ssl; + listen [::]:8080 ssl; + server_name YOUR_IP; + + ssl_certificate /etc/nginx/certs/cert.pem; + ssl_certificate_key /etc/nginx/certs/key.pem; + + # Disable TLS session resumption + ssl_session_cache off; + ssl_session_tickets off; + + # returns default nginx page + location / { + root /usr/share/nginx/html; + index index.html; + } + + # returns plain text response + location /hello-world { + return 200 'Hello World!'; + add_header Content-Type text/plain; + } + } +} \ No newline at end of file diff --git a/src/BenchmarksApps/TLS/Nginx/config/start-nginx.sh b/src/BenchmarksApps/TLS/Nginx/config/start-nginx.sh new file mode 100644 index 000000000..c0b63c9c7 --- /dev/null +++ b/src/BenchmarksApps/TLS/Nginx/config/start-nginx.sh @@ -0,0 +1,3 @@ +#!/bin/bash +echo "$(date) - Application started." +nginx -g "daemon off;" # start nginx \ No newline at end of file diff --git a/src/BenchmarksApps/TLS/Nginx/invoke.ps1 b/src/BenchmarksApps/TLS/Nginx/invoke.ps1 new file mode 100644 index 000000000..75ae8bdb8 --- /dev/null +++ b/src/BenchmarksApps/TLS/Nginx/invoke.ps1 @@ -0,0 +1 @@ +curl -v https://127.0.0.1:8080 --insecure \ No newline at end of file