-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Support SSLKEYLOGFILE in SslStream #37915
Comments
Tagging subscribers to this area: @dotnet/ncl |
Triage: Useful for diagnostics to be able to view the traffic unencrypted. |
Just as an aside, I foolishly assumed that given
|
While SSLKEYLOGFILE may be problematic because of forward secrecy and platform dependency, I was experimenting with alternative approach. https://github.com/wfurt/PcapStream gives you option to create decrypted captures with HttpClient, Kestrel and perhaps other scenarios. It is in early stage but any feedback would be appreciated. The MSQL use case is still problematic AFAIK as the client frames encrypted bits to TDS. I don't know Wireshark can deal with that. I did not have luck. |
Native support in the runtime would be great. In the meantime, I've created a solution for Linux with OpenSSL 1.1.1+ (i.e. Ubuntu 18.04 up on amd64 or 20.04 all archs) that works by wrapping |
I understand this is a sensitive topic, but as TLSs is a common interface between organizations this feature is used to resolve disputes. IE: "See we are sending X but your are responding with Y and we expect Z. You can reproduce this collection procedure at your end as well to verify." The idea that both parties can collect a common pcap, decrypt with their own SSLKEYLOGFILE, and reach consensus is commonplace. |
Is there any ongoing work on this? |
not really. We agreed to support it in DEBUG build in way similar to #83001. But the urgency is lower IMHO as there are other alternatives. |
@wfurt I am very concerned about letting this option available only for debug builds. There is a very high risk of seeing debug code being deployed in production which is problematic for other reasons. Also, the provided workarounds are briliant but do not provide a solution for all the cases and require rebuilding which is something that can be hard to ask in large organizations. |
When I said DEBUG I mean debug build for runtime. That is not published to usual feeds so there should be no confusion IMHO. Of course, somebody can work hard and mess it up anyway but it seems like this is what browsers do so we would be on par. (for Linux) The rebuild is somewhat intentional. To limit risk you mentioned we down't want to make it too simple. You can always build it always and have App specific overrides to enable it - if that meets policy of give organization. |
@wfurt just to be sure:
I understand the concerns, but if I think to the container workloads, should the environment variables be defeated, security is already gone. |
The PR is just for Quic, SslStream change can mimic that for TLS in future. And there are no debug binary bits available for download AFAIK. (but you can grab them for example from PR runs) So the goal is to make it possible for somebody who is determined and knows what to do. Ease of access and wide availability is not priority at the moment. |
Got it, thank you |
Is there any update on this? This feature is also very meaningful for gRPC on .NET. In most enterprise scenario, the gRPC traffic should be encrypted by TLS. A method to decrypt the TLS traffic is necessary for analyzing the streaming data. Whilst according to WireShark Wiki , currently C#/dotnet does not support TLS session secret key from either client or server side, while other languages like Java/Golang do support it. It's better for .NET Core to support an easier way of decrypting HTTPS traffic, like exporting the TLS session secret key or any other method. |
@hannadeng I don't think that this would be helpful in your case (gRPC). |
Thanks @raffaeler . Maybe my question is not quite clear. Let me explain more. I understand #83001. is only for QUIC and will not be applicable in my case (gRPC - HTTP2 protocol). Whilst I thought the original issue requested by bgrainger is a kind of general request for supporting decrypting TLS, including HTTP/2 protocol. Appreciate @JamesNK could help input more insights. |
@hannadeng I am totally with you. I would love to have the opportunity to monitor the SSL convesation with the required level of precautions needed to avoid misues. |
Got it. Thanks again! |
When #83001 is done I plan to do it for SslStream as well - Debug build on Linux only. But I don't have much time for either one at the moment. If there a reason why https://github.com/wfurt/PcapStream does not work for you @hannadeng ? It should give you ability to decode and debug HTTP/2 and gRPC. |
Tentatively re-opening to discuss the requirement for DEBUG build (as this no longer applies to browsers - Firefox, Chromiun, nor CLI tools - cUrl) |
I would like to know if there is any chance to discuss supporting SSLKEYLOGFILE in release builds of the CLR, using an environment variable to enable easier diagnostics.
If this is out of discussion for .NET 9, please make a statement so that we avoid 'noise' in this comments. |
That's the intent here.
No, I'd like to solve this in .NET 9. And thank you for describing your scenario, that will help make my case. |
Any updates? |
Thanks for the remainder, I just kicked off an internal discussion about this. |
Can you elaborate on why the SslStream cannot emit the Traffic or Handshake secret?
|
There is no API on Windows to extract the secrets @upsampled . |
If Windows client is your only one option thee are other ways how to peek inside - something like Fiddler or PcapStream should still work. |
The underlying OS library (Schannel) does not give out secrets to the application. In fact, the secrets are not kept in the app process memory at all, but instead reside in lsass.exe process and there is IPC between the two under the hood. https://b.poc.fun/decrypting-schannel-tls-part-1/ may be an interesting read (although the method described may not be practical). Schannel added support for exporting TLS 1.3 secrets specifically in order to support implementing QUIC (QUIC requires access to encryption secrets because it interleaves TLS + other protocol data + application data and applies custom encryption using the secrets derived by TLS layer). That support is intentionally limited to very specific use case where Schannel gives out unencrypted TLS messages and encryption secrets separately. IIRC, this mode does not work for TLS 1.2. We could theoretically use that mode and apply TLS framing+encryption in .NET, but that has few problems:
All-in-all, the implementation cost far outweighs possible benefits and it might be better to use other tools like wfurt mentioned. |
Are those same exporting mechanisms available for TLSv13 over TCP? I am assuming this is to support 0-RTT or the PSK-binder mechanisms in TLSv13 and both also are possible over TCP. I guess I am asking if the below is true
|
No, let me clarify. The secrets are exported only if the TLS version is 1.3 and it is operating in "recordless mode" (where it strips outer encryption and provides unencrypted TLS messages). SChannel does not know about TCP, it is simply exchanging data via buffers and sending data is up to other code. Putting the stripped encryption back in .NET code is the complex and problematic part which is the main reason we won't invest into that, for reasons listed in my previous comment. |
In windows maybe you can consider using some OpenSSL wrapper instead of SslStream. Like OpenSSL Net does |
we could. But that has massive implications for certifications, performance, security and integration with OS functions like Cert store. As I mentioned above, there are other ways how to solve debugging TLS traffic @nathan130200 |
It makes sense, and it ends up becoming unfeasible to do this at the moment, especially when we talk about performance. |
PcapStream looks nice, but it is only usable if you are the app developer (not always the case, you might want to debug a third-party app/component). Fiddler is only usable if the app supports proxies and does not implement SSL pinning or similar mechanisms. It does not help with non-HTTP connections as far as I know. Imagine you are an app developer using a third-party component that implements some protocol (e.g. BACnet SC, SNMPv3, SRTP...) and you'd want to debug an issue in the communication in between your app using that component and an actual device. For this example let's consider a scenario when the third-party component does not expose the underlying streams to the developer directly, meaning we have to go through some API and we cannot use PcapStream. I think there should be some easy opt-in mechanism like the one in OpenSSL to allow developers to peek inside the TLS encrypted stream and see the decrypted traffic, provided they fully control at least one side of the connection. But I understand from the previous comments that maybe it's not an issue of .NET, but Windows API in general. Is my understanding correct? |
SSLKEYLOGFILE
is a feature provided by Chrome and Firefox that logs the pre-master secret to a file (specified by theSSLKEYLOGFILE
environment variable) during TLS negotiation. The format of the file is documented here: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.This allows encrypted data in a packet capture to be decrypted by Wireshark (without having to know the server's private key): https://wiki.wireshark.org/TLS#Using_the_.28Pre.29-Master-Secret.
As HTTPS and HTTP/2 become more popular, it will be increasingly more useful to be able to decrypt packet captures for network analysis; as per http://gary-nebbett.blogspot.com/2018/06/tracing-https-traffic-on-microsoft.html. (This use case also seems to be implied by #35369.)
It would be great if TLS negotiation performed by
SslStream
could also log these secrets so that tools like Wireshark could be used to decrypt packet captures involving .NET clients. (Note that I'm not necessarily asking for theSSLKEYLOGFILE
environment variable to be specifically supported, but just some opt-in way of dumping the same data;SSLKEYLOGFILE
seemed like the most concise way to describe the feature.)Besides HTTPS, another use case would be TLS negotiation in a different protocol; for example, the MySQL protocol upgrades from plain text to TLS, and being able to decrypt the packets in Wireshark would make diagnosing issues easier: mysql-net/MySqlConnector#780 (comment)
One potential problem is that Schannel doesn't support exporting this information, which could make it difficult to implement this feature on all platforms: https://social.technet.microsoft.com/Forums/en-US/4041d78a-21bb-44fd-9a96-6579ea8129d1/obtaining-sslkeylogfilelike-data-from-edge-et-al-schannel-clients?forum=messageanalyzer
The text was updated successfully, but these errors were encountered: