Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: integrate mutual TLS scenario with underlying http.sys server #2044

Merged
merged 18 commits into from
Jan 15, 2025

Conversation

DeagleGross
Copy link
Contributor

mTLS (mutual TLS) requires a separate setup from the server side. mTLS is valid, when clientCert is negotiated on the connection establishment, meaning when ASP.NET code calls context.Connection.ClientCertificate: it should be already available and there must not be any need to invoke context.Connection.GetClientCertificateAsync()

in case of Kestrel setup is extremely easy - just set a specific enum value:

options.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
options.ClientCertificateValidation = AllowAnyCertificateValidationWithLogging;

however in case of HTTP.SYS the only option is to execute a netsh command netsh http add sslcert.

I have added a code in ASP.NET application, which on start binds the test certificate using netsh command, and then using an applicationLifetime ApplicationStopping callback it deletes the cert binding from the machine. It can be seem from the logs (below).

Basically the order is the following:

  1. bind the test cert to http.sys with clientcertnegotiation=enable to enable client cert negotiation
    optionally) netsh http show sslcert can show the ssl cert bindings on a machine. Important property is "Negotiate Client Certificate : Enabled"
  2. execute the benchmark (in other words process the traffic). If verbose logging of cert validation is enabled, you should see message "client certificate (...) already exists on the connection", meaning that client cert negotiation happened on the connection establishment
  3. in the end of the benchmark run during a graceful shutdown of an app a rollback of http.sys configuration will happen - we will execute netsh http delete sslcert
args: --urls https://10.0.0.110:5000 --mTLS true --certValidationConsoleEnabled true --statsEnabled false --tlsRenegotiation true --httpSysLogs true

Setting up mTLS for http.sys
Loaded testCert.pfx from local file system
Added testCert.pfx to localMachine cert store
Executing command: netsh http add sslcert ipport=10.0.0.110:5000 certstorename=MY certhash=6A283FAAA7FFFC129DF24CC0E7521186C7926219 appid={75e4f5b6-776f-448f-8a36-64e964bf2147} clientcertnegotiation=enable
Configured http.sys settings for mTLS
Registered client cert validation middleware
Executing command: netsh http show sslcert

SSL Certificate bindings:

IP:port                      : 10.0.0.110:5000
Certificate Hash             : 6a283faaa7fffc129df24cc0e7521186c7926219
Application ID               : {75e4f5b6-776f-448f-8a36-64e964bf2147}
Certificate Store Name       : MY
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check                  : Enabled
Revocation Freshness Time    : 0
URL Retrieval Timeout        : 0
Ctl Identifier               : (null)
Ctl Store Name               : (null)
DS Mapper Usage              : Disabled
**Negotiate Client Certificate : Enabled**
Reject Connections           : Disabled
Disable HTTP2                : Not Set
Disable QUIC                 : Not Set
Disable TLS1.2               : Not Set
Disable TLS1.3               : Not Set
Disable OCSP Stapling        : Not Set
Enable Token Binding         : Not Set
Log Extended Events          : Not Set
Disable Legacy TLS Versions  : Not Set
Enable Session Ticket        : Not Set

Application Info:

mTLS is enabled (client cert is required)
enabled logging certificate validation events to console
listening endpoints: https://10.0.0.110:5000

Application started.
client certificate (6A283FAAA7FFFC129DF24CC0E7521186C7926219) already exists on the connection -648518319766231673
client certificate (6A283FAAA7FFFC129DF24CC0E7521186C7926219) already exists on the connection -216172777013495157
client certificate (6A283FAAA7FFFC129DF24CC0E7521186C7926219) already exists on the connection -144115161500731759
client certificate (6A283FAAA7FFFC129DF24CC0E7521186C7926219) already exists on the connection -576460747203134805
client certificate (6A283FAAA7FFFC129DF24CC0E7521186C7926219) already exists on the connection -432345559127283053
...
...
...
Disabling mTLS for http.sys
Executing command: netsh http delete sslcert ipport=10.0.0.110:5000
Disabled http.sys settings for mTLS

Copy link
Member

@BrennanConroy BrennanConroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I am slightly worried if netsh fails to delete the configuration and leaves the machine in a setup state.

src/BenchmarksApps/TLS/HttpSys/NetShWrapper.cs Outdated Show resolved Hide resolved
src/BenchmarksApps/TLS/HttpSys/Program.cs Outdated Show resolved Hide resolved
@DeagleGross
Copy link
Contributor Author

Nice, I am slightly worried if netsh fails to delete the configuration and leaves the machine in a setup state.

I am as well. I am thinking about 2 approaches:

  1. leave it as is relying on re-running benchmark again eventually on same machine, which will bring machine back to a proper setup. I need to make an additional verification check in the startup then
  2. add the after-script to perform sslcert binding deletion.

i will try to do №2 a bit later today - it should be more robust

@DeagleGross
Copy link
Contributor Author

decided to change the port to 8080 so that other tests are not impacted by http.sys configuration changes (if there would be) - just for safety.

@DeagleGross DeagleGross merged commit 55b23b5 into aspnet:main Jan 15, 2025
2 checks passed
@DeagleGross DeagleGross deleted the dmkorolev/tls-httpsys-fixes branch January 15, 2025 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants