How to Debug Keylog Issues in iroh Connections
Enable TLS key logging in iroh by setting the SSLKEYLOGFILE environment variable and calling .keylog(true) on the EndpointBuilder, which writes pre-master secrets to the specified file via rustls.
The iroh networking library uses rustls for TLS encryption, providing a built-in mechanism to log cryptographic keys for debugging QUIC connections. When you need to inspect encrypted traffic with tools like Wireshark, enabling the keylog feature is essential. This guide explains how to debug keylog issues in iroh connections by examining the source code in the n0-computer/iroh repository.
How Key Logging Works in iroh
Iroh implements key logging through a coordinated chain between the endpoint builder and the TLS configuration layer. Understanding this flow helps diagnose why keys might not appear in your log file.
Endpoint Configuration
The keylog behavior is controlled by the EndpointBuilder in iroh/src/endpoint.rs. At lines 730–734, the builder maintains a keylog: bool field that defaults to false. You must explicitly enable it using the .keylog(true) method before constructing the endpoint.
let endpoint = Endpoint::builder()
.keylog(true) // Enables TLS key logging
.bind(([0, 0, 0, 0], 0))?;
When the endpoint builds the QUIC client or server configuration, it passes this boolean flag to the TLS configuration helpers.
TLS Configuration
The actual key logging implementation resides in iroh/src/tls.rs at lines 74–107. The functions make_server_config and make_client_config accept the keylog argument. When set to true, they configure rustls to emit key material:
if keylog {
cfg.key_log = Arc::new(rustls::KeyLogFile::new());
}
This delegates to rustls's KeyLogFile, which checks the SSLKEYLOGFILE environment variable and writes the TLS pre-master secret in the standard NSS key log format.
Common Symptoms and Root Causes
When debugging keylog issues in iroh connections, identify your specific symptom to isolate the root cause:
- No keylog file created: The
SSLKEYLOGFILEenvironment variable is unset or points to a non-writable directory. Verify withecho $SSLKEYLOGFILEand check filesystem permissions. - Empty keylog file: The
keylogflag was not passed to the endpoint builder. Search your code for.keylog(true)and ensure it appears before.bind(). - Stale or missing entries: The connection reused a cached session ticket before keylog was enabled. Clear the client's session cache or restart the endpoint to force a full handshake.
- Application crashes: The
rustlscrate was compiled without thedangerous_configurationfeature, which is required for key logging. Check yourCargo.tomlforfeatures = ["dangerous_configuration"].
Step-by-Step Debugging Procedure
Follow these steps to verify and fix key logging functionality:
-
Set the environment variable
Ensure
SSLKEYLOGFILEis exported before your process starts:export SSLKEYLOGFILE=$HOME/iroh_keylog.txt touch $SSLKEYLOGFILE -
Enable keylog in your code
Confirm the builder calls
.keylog(true)as shown iniroh/examples/0rtt.rsat line 68:let endpoint = Endpoint::builder() .keylog(true) .bind(([0, 0, 0, 0], 0))?; -
Verify the TLS configuration
Inspect
iroh/src/tls.rsto confirmmake_server_configormake_client_configcontains the key logging logic:if keylog { cfg.key_log = Arc::new(rustls::KeyLogFile::new()); } -
Validate the rustls version
Check your
Cargo.lockto ensure you are using a rustls version that supportsKeyLogFile. If necessary, update yourCargo.toml:[dependencies] rustls = { version = "0.22", features = ["dangerous_configuration"] } -
Inspect the output
After running a connection, verify the file contains entries starting with
CLIENT_RANDOMorSERVER_HANDSHAKE:head -n 5 $SSLKEYLOGFILE
Working Code Example
Below is a complete example combining environment setup and endpoint configuration:
use iroh::endpoint::Endpoint;
fn main() -> anyhow::Result<()> {
// Set before any connections are established
std::env::set_var("SSLKEYLOGFILE", "/tmp/iroh_keys.log");
let endpoint = Endpoint::builder()
.keylog(true) // Critical: enables key logging
.bind(([0, 0, 0, 0], 0))?;
// Proceed with connection logic...
Ok(())
}
Key Source Files Reference
When debugging keylog issues in iroh connections, examine these specific files in the repository:
iroh/src/endpoint.rs: Contains thekeylogfield and builder method (lines 730–734).iroh/src/tls.rs: Implementsmake_server_configandmake_client_config; enables rustls key logging when the flag is true (lines 74–107).iroh/examples/0rtt.rs: Reference implementation showing.keylog(true)usage (line 68).Cargo.toml: Declares therustlsdependency; must include thedangerous_configurationfeature.
Summary
- Set the
SSLKEYLOGFILEenvironment variable to a writable path before starting your application. - Enable the
.keylog(true)method on theEndpointBuilderto pass the flag through to the TLS layer. - Verify the
rustlsdependency includes thedangerous_configurationfeature in yourCargo.toml. - Check
iroh/src/tls.rsto confirmKeyLogFileis instantiated when the flag is enabled. - Clear session caches if keys appear stale, as resumed connections may predate the keylog setting.
Frequently Asked Questions
Why is my keylog file empty even though SSLKEYLOGFILE is set?
The file remains empty when the .keylog(true) method is omitted from the EndpointBuilder or when the connection reuses a cached session ticket without performing a full handshake. Verify that your code explicitly calls .keylog(true) and restart the endpoint to ensure a fresh handshake occurs.
Does enabling key logging require special rustls features?
Yes, key logging requires the dangerous_configuration feature to be enabled in your Cargo.toml for the rustls crate. Without this feature flag, the KeyLogFile API is unavailable and the application may fail to compile or panic at runtime when key logging is attempted.
Is it safe to enable keylog in production applications?
No, enabling key logging exposes the pre-master secrets and compromises the confidentiality of all encrypted connections. According to the iroh source code, this feature is intended for debugging only, as demonstrated in example files like iroh/examples/0rtt.rs. Never enable .keylog(true) in production environments.
How can I verify the keylog is capturing the correct connection?
Inspect the keylog file for entries beginning with CLIENT_RANDOM or SERVER_HANDSHAKE. Each line corresponds to a specific TLS handshake. If you see entries but cannot decrypt traffic in Wireshark, ensure you are capturing the entire QUIC handshake from the initial Client Hello packet, as keys are only logged during the handshake phase.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →