doc/ssl_keylog/ssl_keylog_user_guide.md
SSL/TLS key logging is a debugging feature that allows ProxySQL to write TLS encryption secrets to a file. These secrets can be used by network analysis tools like Wireshark to decrypt and inspect TLS traffic.
This feature is primarily useful for:
WARNING: The key log file contains cryptographic secrets that can decrypt ALL TLS traffic. Anyone with access to this file can decrypt your encrypted communications.
Only enable this feature for debugging purposes. Disable it in production environments.
ProxySQL variables belong to modules. When referencing a variable from the SQL interface, you must prefix it with the module name.
From the ProxySQL admin interface, use the module prefix:
-- Correct: uses admin- prefix for admin module variables
SET admin-ssl_keylog_file = '/var/log/proxysql/sslkeys.txt';
-- Also correct
SET admin-ssl_keylog_file = 'sslkeys.txt';
-- Disable key logging
SET admin-ssl_keylog_file = '';
-- Apply to runtime
LOAD ADMIN VARIABLES TO RUNTIME;
In the configuration file (e.g., /etc/proxysql.cnf), variables are grouped by module section:
# Configuration file format
admin_variables=
{
admin_credentials="admin:admin"
mysql_ifaces="0.0.0.0:6032"
# NO prefix needed in config file - already in admin section
ssl_keylog_file='/var/log/proxysql/sslkeys.txt'
}
mysql_variables=
{
threads=4
max_connections=2048
# ... other mysql variables
}
Key Points:
SET admin-ssl_keylog_file = '...' (with prefix)ssl_keylog_file='...' (no prefix, inside admin_variables section)Connect to the ProxySQL admin interface (default port 6032):
mysql -h 127.0.0.1 -P 6032 -u admin -padmin
Then set the variable:
-- Enable key logging with absolute path
SET admin-ssl_keylog_file = '/var/log/proxysql/sslkeys.txt';
-- Apply to runtime immediately
LOAD ADMIN VARIABLES TO RUNTIME;
-- Verify it's set
SELECT * FROM global_variables WHERE variable_name = 'admin-ssl_keylog_file';
Edit your ProxySQL configuration file (typically /etc/proxysql.cnf):
admin_variables=
{
admin_credentials="admin:admin"
mysql_ifaces="0.0.0.0:6032"
# Add this line
ssl_keylog_file='/var/log/proxysql/sslkeys.txt'
}
Then restart ProxySQL:
sudo systemctl restart proxysql
# or
sudo service proxysql restart
The ssl_keylog_file variable accepts two types of paths:
| Path Type | Format | Example | Resolved To |
|---|---|---|---|
| Absolute | Starts with / | /var/log/proxysql/keys.txt | /var/log/proxysql/keys.txt |
| Relative | No leading / | sslkeys.txt | $DATADIR/sslkeys.txt |
Example:
-- If ProxySQL data directory is /var/lib/proxysql
SET admin-ssl_keylog_file = 'debug/sslkeys.txt';
-- Resolves to: /var/lib/proxysql/debug/sslkeys.txt
After enabling key logging and generating TLS traffic, verify the key log file:
# Check if file exists
ls -la /var/log/proxysql/sslkeys.txt
# View contents (should contain secrets!)
cat /var/log/proxysql/sslkeys.txt
The file should contain lines like:
CLIENT_RANDOM 3a4b5c6d7e8f0123456789abcdef... 48_byte_secret_here...
-- Set to empty string to disable
SET admin-ssl_keylog_file = '';
-- Apply to runtime
LOAD ADMIN VARIABLES TO RUNTIME;
Remove or comment out the ssl_keylog_file line in your config file and restart ProxySQL.
ProxySQL supports rotating the SSL key log file using the PROXYSQL FLUSH LOGS command:
PROXYSQL FLUSH LOGS;
This command:
Note: The file is reopened in append mode, so existing contents will be preserved. If you want to start with a fresh file, rename/move the old file manually before running FLUSH LOGS.
# 1. Rename the current key log file
mv /var/log/proxysql/sslkeys.txt /var/log/proxysql/sslkeys.txt.old
# 2. Tell ProxySQL to create a new file
mysql -h 127.0.0.1 -P 6032 -u admin -padmin -e "PROXYSQL FLUSH LOGS;"
# 3. Secure the old file
chmod 600 /var/log/proxysql/sslkeys.txt.old
In production environments, you typically don't run Wireshark directly on the server. Instead, you:
tcpdumpOn the ProxySQL server, capture network traffic to a pcap file:
# Capture MySQL frontend traffic (client → ProxySQL)
sudo tcpdump -i eth0 -w /tmp/proxysql_debug.pcap port 6033
# Capture PgSQL frontend traffic (client → ProxySQL)
sudo tcpdump -i eth0 -w /tmp/proxysql_debug.pcap port 6133
# Capture PgSQL backend traffic (ProxySQL → PostgreSQL server)
sudo tcpdump -i eth0 -w /tmp/proxysql_debug.pcap port 5432
# Capture traffic between specific hosts
sudo tcpdump -i eth0 -w /tmp/proxysql_debug.pcap host client_ip and host proxysql_ip
# Run for a specific duration
sudo timeout 60 tcpdump -i eth0 -w /tmp/proxysql_debug.pcap port 6033
Notes:
-i any to capture on all interfaces if unsure-w flag writes to pcap format (binary)df -hCopy both the pcap file and the key log file to your analysis system:
# On the ProxySQL server
scp /tmp/proxysql_debug.pcap user@analysis-system:/path/to/analysis/
scp /var/log/proxysql/sslkeys.txt user@analysis-system:/path/to/analysis/
# Or archive them together
tar czf proxysql_debug.tar.gz /tmp/proxysql_debug.pcap /var/log/proxysql/sslkeys.txt
Security: Use secure copy (scp/sftp) and ensure the key log file is transmitted securely, as it contains cryptographic secrets.
On your analysis system with Wireshark installed:
Configure TLS key log:
Open the pcap file:
proxysql_debug.pcapFilter decrypted traffic:
# Show only MySQL packets
mysql
# Show only PostgreSQL packets
pgsql
# Show TLS handshake
tls.handshake.type == 1
# Show decrypted application data
tls.app_data
View decrypted content:
tshark is Wireshark's command-line counterpart - useful for servers or headless analysis.
# Read pcap with TLS decryption using key log file
tshark -r /tmp/proxysql_debug.pcap \
-o tls.keylog_file:/path/to/sslkeys.txt \
-Y "tls" \
-V
# Show only MySQL packets
tshark -r /tmp/proxysql_debug.pcap \
-o tls.keylog_file:/path/to/sslkeys.txt \
-Y "mysql"
# Export decrypted TLS payloads to JSON
tshark -r /tmp/proxysql_debug.pcap \
-o tls.keylog_file:/path/to/sslkeys.txt \
-T json \
-Y "tls.app_data" \
> decrypted.json
# Show summary of decrypted connections
tshark -r /tmp/proxysql_debug.pcap \
-o tls.keylog_file:/path/to/sslkeys.txt \
-q -z tls,tree
Common tshark filters for ProxySQL debugging:
# Show TLS handshake details
tshark -r proxysql_debug.pcap -o tls.keylog_file:sslkeys.txt -Y "tls.handshake"
# Show all TLS app data (decrypted MySQL queries/responses)
tshark -r proxysql_debug.pcap -o tls.keylog_file:sslkeys.txt -Y "tls.app_data" -V
# Convert to readable text format
tshark -r proxysql_debug.pcap -o tls.keylog_file:sslkeys.txt -T fields \
-e frame.time -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport \
-e tls.app_data.data
# Statistics: TLS sessions by cipher suite
tshark -r proxysql_debug.pcap -o tls.keylog_file:sslkeys.txt -q -z tls,ctext
If you need to monitor traffic in real-time (not recommended for production debugging):
# Live capture with TLS decryption
sudo tshark -i eth0 -f "port 6033" \
-o tls.keylog_file:/var/log/proxysql/sslkeys.txt \
-Y "tls.app_data" \
-V
Note: This still requires running on the ProxySQL server. For production, prefer the tcpdump → offline analysis workflow.
# /etc/proxysql.cnf
datadir="/var/lib/proxysql"
admin_variables=
{
admin_credentials="admin:admin"
mysql_ifaces="0.0.0.0:6032"
# Enable SSL key logging for debugging
ssl_keylog_file='/var/log/proxysql/sslkeys.txt'
}
mysql_variables=
{
threads=4
max_connections=2048
interfaces="0.0.0.0:6033"
default_schema="information_schema"
# ... other mysql variables
}
Problem: ERROR 1045 (28000): Unknown variable 'admin-ssl_keylog_file'
Solution:
admin-ssl_keylog_fileProblem: The key log file is not being created.
Solutions:
ls -la /var/log/proxysql
SELECT * FROM global_variables WHERE variable_name = 'admin-ssl_keylog_file';
Problem: File exists but is empty or has no secrets.
Solutions:
-- Check MySQL backend connections
SELECT * FROM stats_mysql_connection_pool;
-- Check PgSQL backend connections
SELECT * FROM stats_pgsql_connection_pool;
use_ssl=1 is set on the servers:
SELECT hostgroup_id, hostname, port, use_ssl FROM pgsql_servers;
LOAD PGSQL SERVERS TO RUNTIME;
admin-ssl_keylog_file is loaded into runtime:
LOAD ADMIN VARIABLES TO RUNTIME;
Problem: tcpdump: snaplen: ioctl: Permission denied
Solution: Run tcpdump with sudo:
sudo tcpdump -i eth0 -w /tmp/capture.pcap port 6033
chmod 600 /var/log/proxysql/sslkeys.txt
chown proxysql:proxysql /var/log/proxysql/sslkeys.txt
shred -u /var/log/proxysql/sslkeys.txt.old
| Context | Variable Name | Example |
|---|---|---|
| SQL commands | admin-ssl_keylog_file | SET admin-ssl_keylog_file = '/path/file.txt'; |
| Config file | ssl_keylog_file | ssl_keylog_file='/path/file.txt' (in admin_variables section) |
| Command | Description |
|---|---|
SET admin-ssl_keylog_file = '/path/to/file.txt'; | Enable key logging |
SET admin-ssl_keylog_file = ''; | Disable key logging |
LOAD ADMIN VARIABLES TO RUNTIME; | Apply changes |
PROXYSQL FLUSH LOGS; | Rotate key log file |
SELECT * FROM global_variables WHERE variable_name = 'admin-ssl_keylog_file'; | Check current setting |
| Tool | Use Case |
|---|---|
tcpdump | Capture traffic to pcap file (production) |
tshark | Analyze pcap files with key log (command-line) |
Wireshark | Analyze pcap files with key log (GUI) |
When admin-ssl_keylog_file is configured, TLS secrets are captured from all SSL/TLS connection types:
| Connection Type | Direction | Protocol |
|---|---|---|
| Frontend (client) | Client → ProxySQL | MySQL |
| Frontend (client) | Client → ProxySQL | PostgreSQL |
| Backend | ProxySQL → MySQL server | MySQL |
| Backend | ProxySQL → PostgreSQL server | PostgreSQL |
| Monitor | ProxySQL → MySQL server | MySQL |
| Monitor | ProxySQL → PostgreSQL server | PostgreSQL |
| Cluster | ProxySQL → ProxySQL peer | MySQL |
No additional configuration is needed per connection type — the single admin-ssl_keylog_file variable enables logging for all types.
man tshark or https://www.wireshark.org/docs/man-pages/tshark.html