Skip to content

Commit f0649f9

Browse files
docs(s2n-quic): Add debugging guide (#2449)
* docs(s2n-quic): Add debugging guide * update issue template
1 parent adc7ba9 commit f0649f9

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

.github/ISSUE_TEMPLATE/s2n-quic-issue.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ AWS Security via our [vulnerability reporting page](http://aws.amazon.com/securi
1414

1515
### Problem:
1616

17-
<!--A short description of what the problem is and why we need to fix it. Add reproduction steps if necessary.-->
17+
<!--A short description of what the problem is and why we need to fix it. Add reproduction steps if necessary.
18+
19+
Include a trace log and packet capture (with embedded key log) if possible. See https://aws.github.io/s2n-quic/user-guide/debugging.html for instructions on how to capture these. -->
1820

1921
### Solution:
2022

docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- [Introduction]()
88
- [Installation](user-guide/installation.md)
9+
- [Debugging](user-guide/debugging.md)
910

1011
# Developer Guide
1112

docs/user-guide/debugging.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Debugging s2n-quic
2+
3+
Before [opening an issue](https://github.com/aws/s2n-quic/issues/new?template=s2n-quic-issue.md) regarding `s2n-quic`, you may be able to solve the issue on your own (or at least collect useful debugging information) by performing the actions contained within this section. Attaching the output from these actions to the issue increases our ability to address your issue in a timely manner.
4+
5+
## Tracing logs
6+
7+
`s2n-quic` includes an Event framework that emits debugging information everytime a connection is started, a packet is received, a datagram is dropped, and [many other situations](https://docs.rs/s2n-quic/latest/s2n_quic/provider/event/trait.Subscriber.html#provided-methods). When the `provider-event-tracing` feature is enabled, the default behavior of `s2n-quic` is to emit these events via [tracing](https://docs.rs/tracing). Configuring a `tracing-subscriber` will allow for the events to be emitted to a log file or stdout. Follow these steps to emit a tracing log to stdout:
8+
9+
### 1. Enable the `provider-event-tracing` feature
10+
This feature is not enabled by default in `s2n-quic`, so specify it in your `Cargo.toml` in the `s2n-quic` dependency:
11+
```toml
12+
[dependencies]
13+
s2n-quic = { version = "1", features = ["provider-event-tracing"]}
14+
```
15+
16+
### 2. Add a dependency on `tracing-subscriber`
17+
`tracing-subscriber` is used for collecting the event data emitted by `s2n-quic` and outputting it to stdout. The `env-filter` feature is used for turning logging off and on based on the `RUST_LOG` environment variable.
18+
```toml
19+
[dependencies]
20+
s2n-quic = { version = "1", features = ["provider-event-tracing"]}
21+
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
22+
```
23+
24+
### 3. Configure and initialize a global `tracing-subscriber`
25+
In your application code, prior to starting an `s2n-quic` server or client, include the following code to initialize a global `tracing-subscriber`. This configuration allows for the `RUST_LOG` environment variable to determine the logging level.
26+
27+
```rust
28+
let format = tracing_subscriber::fmt::format()
29+
.with_level(false) // don't include levels in formatted output
30+
.with_timer(tracing_subscriber::fmt::time::uptime())
31+
.with_ansi(false)
32+
.compact(); // Use a less verbose output format.
33+
34+
tracing_subscriber::fmt()
35+
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
36+
.event_format(format)
37+
.init();
38+
```
39+
40+
### 4. [Optional] Specify the `tracing::Subscriber` Event provider to `s2n-quic` server or client
41+
When the `provider-event-tracing` feature is enabled, the default behavior of `s2n-quic` is to emit these events via [tracing](https://docs.rs/tracing). If your application already makes use of a custom event subscriber, you may need to explicitly specify the default `event::tracing::Subscriber` by composing it with your existing event subscriber (`MyCustomEventSubscriber` in this example):
42+
43+
```rust
44+
let mut server = Server::builder()
45+
.with_tls((CERT_PEM, KEY_PEM))?
46+
.with_io("127.0.0.1:4433")?
47+
.with_event((
48+
MyCustomEventSubscriber,
49+
s2n_quic::provider::event::tracing::Subscriber::default(),
50+
))?
51+
.start()?;
52+
```
53+
54+
### 5. Run your application with the `RUST_LOG` environment variable
55+
Now that everything has been configured, you can set the `RUST_LOG` environment variable to `debug` to start emitting debugging information:
56+
```bash
57+
$ RUST_LOG=debug cargo run --bin my_application
58+
0.032760542s s2n_quic:server: platform_feature_configured: configuration=Gso { max_segments: 1 }
59+
0.032954042s s2n_quic:server: platform_feature_configured: configuration=BaseMtu { mtu: 1228 }
60+
0.032964625s s2n_quic:server: platform_feature_configured: configuration=InitialMtu { mtu: 1228 }
61+
0.032971583s s2n_quic:server: platform_feature_configured: configuration=MaxMtu { mtu: 1228 }
62+
0.032978167s s2n_quic:server: platform_feature_configured: configuration=Gro { enabled: false }
63+
0.032987833s s2n_quic:server: platform_feature_configured: configuration=Ecn { enabled: true }
64+
0.033881250s s2n_quic:server: platform_event_loop_started: local_address=127.0.0.1:4433
65+
...
66+
```
67+
Capture this output and attach it to your issue to aid with debugging.
68+
69+
## Packet capture
70+
71+
A packet capture allows for inspecting the contents of every packet transmitted or received by `s2n-quic`. Along with tracing logs, this can be very helpful for diagnosing issues. Follow these steps to record a packet capture.
72+
73+
### 1. Enable key logging on the TLS provider
74+
75+
Since QUIC is an encrypted transport protocol, the payload of each packet is not readable in a standard packet capture. `s2n-quic` supports exporting the TLS session keys used by each QUIC connection so that the packet capture may be decrypted. Both the `s2n-tls` and `rustls` TLS providers support key logging through their associated builders:
76+
77+
```rust
78+
let tls = s2n_quic::provider::tls::default::Serverhell::builder()
79+
.with_certificate(CERT_PEM, KEY_PEM)?
80+
.with_key_logging()? // enables key logging
81+
.build()?;
82+
83+
let mut server = Server::builder()
84+
.with_tls(tls)?
85+
.with_io("127.0.0.1:4433")?
86+
.start()?;
87+
```
88+
89+
#### 2. Start capturing packets
90+
91+
Popular tools for capture packets include the command line tools [tcpdump](https://www.tcpdump.org/) and [tshark](https://www.wireshark.org/docs/man-pages/tshark.html), as well as [Wireshark](https://www.wireshark.org/). Determine the network interface you are using for communicating with `s2n-quic` and provide it to the packet capture tool you prefer. The following example uses `tcpdump` to capture on the loopback interface and write the capture to a file:
92+
93+
```bash
94+
$ sudo tcpdump -i lo0 -w /var/tmp/mycapture.pcap
95+
```
96+
97+
#### 3. Run your application with the `SSLKEYLOGFILE` environment variable
98+
99+
Set the `SSLKEYLOGFILE` environment variable to a file path to create a file containing the TLS session keys:
100+
101+
```bash
102+
$ SSLKEYLOGFILE=/var/tmp/keys.log cargo run --bin my_application
103+
```
104+
105+
#### 4. [Optional] Embed the key log in the packet capture file
106+
107+
To simplify analysis of the packet capture, it can be helpful to embed the key log from the previous step into the packet capture file itself. [editcap](https://www.wireshark.org/docs/man-pages/editcap.html) is a utility for editing packet captures and can perform this embedding:
108+
109+
```bash
110+
$ editcap --inject-secrets tls,/var/tmp/keys.log /var/tmp/mycapture.pcap /var/tmp/capturewithkeys.pcapng
111+
```
112+
113+
Attach `capturewithkeys.pcapng` to your issue to aid with debugging. If you skipped step 4, also attach `keys.log`.

0 commit comments

Comments
 (0)