diff --git a/doc/ssl_keylog/ssl_keylog_developer_guide.md b/doc/ssl_keylog/ssl_keylog_developer_guide.md new file mode 100644 index 000000000..51822579a --- /dev/null +++ b/doc/ssl_keylog/ssl_keylog_developer_guide.md @@ -0,0 +1,425 @@ +# SSL/TLS Key Log Feature - Developer Guide + +## Overview + +ProxySQL implements SSL/TLS key logging to enable decryption of encrypted traffic for debugging purposes. This feature writes TLS secrets to a file in the NSS Key Log Format, which can be used by tools like Wireshark to decrypt and analyze TLS traffic. + +**PR Reference:** #4236 - "Added support for SSLKEYLOGFILE" + +--- + +## Variable Naming Convention + +ProxySQL variables belong to **modules**. This is important for understanding how variables are referenced: + +| Context | Variable Name | Module | +|---------|---------------|--------| +| **Internal code** | `ssl_keylog_file` | Admin | +| **SQL interface** | `admin-ssl_keylog_file` | Admin (with prefix) | +| **Config file** | `ssl_keylog_file` | Admin (in `admin_variables` section) | + +**Code Location:** `include/proxysql_admin.h` - the variable is defined as `char* ssl_keylog_file` within the admin variables struct. + +**SQL Registration:** `lib/ProxySQL_Admin.cpp` - registered as `"ssl_keylog_file"` in the `admin_variables` array. + +When users set this variable via SQL, they must use the module prefix: +```sql +SET admin-ssl_keylog_file = '/path/to/file.txt'; +``` + +--- + +## Architecture + +### Component Diagram + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ ProxySQL Process │ +│ │ +│ ┌────────────────┐ ┌─────────────────────────────────┐ │ +│ | ProxySQL_Admin |────────>| Global Variables │ │ +│ | │ | .ssl_keylog_file = "/path/..." │ │ +│ └────────────────┘ └─────────────────────────────────┘ │ +│ │ │ +│ | SET admin-ssl_keylog_file='/path/keylog.txt' │ +│ v │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ | proxysql_sslkeylog module │ │ +│ │ │ │ +│ │ ┌──────────────┐ ┌──────────────────┐ ┌───────────────┐ │ │ +│ │ | keylog_init | | keylog_open | | keylog_close │ │ │ +│ │ └──────────────┘ └──────────────────┘ └───────────────┘ │ │ +│ │ │ │ +│ │ ┌──────────────────────────────────────────────────────────┐│ │ +│ │ | proxysql_keylog_attach_callback(SSL_CTX*) ││ │ +│ │ | ││ │ +│ │ | SSL_CTX_set_keylog_callback(ctx, write_line_callback) ││ │ +│ │ └──────────────────────────────────────────────────────────┘│ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ │ Callback invoked by OpenSSL │ +│ v │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ proxysql_keylog_write_line_callback(ssl, line) │ │ +│ │ │ │ +│ │ - Validate line length │ │ +│ │ - Acquire read lock (rwlock) │ │ +│ │ - Write to keylog file │ │ +│ │ - Release lock │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ v │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ keylog_file_fp (FILE*) │ │ +│ │ "/var/log/proxysql/sslkeys.txt" │ │ +│ │ │ │ +│ │ CLIENT_RANDOM 3a4b5c... <48-byte-secret> │ │ +│ │ CLIENT_HANDSHAKE_TRAFFIC_SECRET 3a4b... <32-byte-secret> │ │ +│ │ SERVER_HANDSHAKE_TRAFFIC_SECRET 3a4b... <32-byte-secret> │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +### Thread Safety Model + +The keylog subsystem uses a **pthread read-write lock** for concurrent access. + +**Key Points:** +- Multiple threads can write to the keylog file simultaneously during TLS handshakes +- File rotation (open/close) acquires exclusive lock +- Double-checked locking in `write_line_callback()` for performance + +--- + +## NSS Key Log Format + +### File Structure + +Each line in the keylog file has the following format: + +``` +