From time to time you may want to debug TLS, Now this is not as easy as you might think, Because of the nature of TLS, you don’t really want to have anyone (even if they technically may have the key on the server itself) to decrypt what was sent or received.
If you are looking for a quick way to debug and peek inside what is being exchanged inside HTTPS connections then there are a few forces into play that we need to remove first.
Before we start we need to layout the requirements that you will need.
Root on the machine that is doing the traffic (or anything that the SSL traffic passes through) Access to the SSL key itself
In this guide I will be using SSLDump. Unfortunately that tool has not aged hugely well to modern ciphers and key exchanges. So we have a few things that are against us for looking at this traffic.
First of all, We need to lower our security to remove two things. ECDSA (Not supported in SSLDump), and DH or EDH exchanges since they mean that you cannot passively decrypt the communications going back and forward.
To do this in Apache 2 (assuming Apache/2.2.16 on Debian 6 with OpenSSL 0.9.8o) you need to add the following lines in the same places that you have your SSL certificate path’s:
SSLProtocol ALL -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite "AES256-SHA"
And for nginx you use:
ssl_ciphers "RSA+AES256:!MD5";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
Once you have rebooted your web server. You can either capture live off the server, in that case you just want to do
ssldump -ndk /path/to/you/ssl/key port 443
or if you want to capture somewhere else or capture traffic and replay it back later (in fear of losing stuff to terminal scrollback limits etc)
tcpdump -nvv -s 65535 -w ssl_debug.pcap port 443
Then
ssldump -ndk /path/to/you/ssl/key -r ssl_debug.pcap
After that you should start seeing output like the following:
root@gumdrop:/etc/apache2$ ssldump -r essessell.pcap -k mysitename.key -d
New TCP connection #1: 192.168.14.199(63260) <-> gumdrop.benjojo.co.uk(443)
1 1 0.0048 (0.0048) C>S Handshake
ClientHello
Version 3.3
resume [32]=
54 d3 4a fd 86 33 16 bb b1 d6 d1 33 49 ad 11 55
17 fc bf ab 7f da fe e4 05 5d 95 a7 a6 c9 62 1e
cipher suites
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Unknown value 0xc013
Unknown value 0xc009
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Unknown value 0xc011
Unknown value 0xc007
Unknown value 0x9c
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_3DES_EDE_CBC_SHA
Unknown value 0xff
compression methods
NULL
1 2 0.0102 (0.0053) S>C Handshake
ServerHello
Version 3.1
session_id[0]=
cipherSuite TLS_RSA_WITH_AES_256_CBC_SHA
compressionMethod NULL
1 3 0.0102 (0.0000) S>C Handshake
Certificate
1 4 0.0102 (0.0000) S>C Handshake
ServerHelloDone
1 5 0.0108 (0.0005) C>S Handshake
ClientKeyExchange
1 6 0.0108 (0.0000) C>S ChangeCipherSpec
1 7 0.0108 (0.0000) C>S Handshake
Finished
1 8 0.0293 (0.0185) S>C Handshake
TLS_RSA_WITH_RC4_128_MD51 9 0.0293 (0.0000) S>C ChangeCipherSpec
1 10 0.0293 (0.0000) S>C Handshake
Finished
1 0.0302 (0.0009) C>S TCP FIN
1 11 0.0350 (0.0047) S>C Alert
level warning
value close_notify
1 0.0350 (0.0000) S>C TCP FIN
New TCP connection #2: 192.168.14.199(63261) <-> gumdrop.benjojo.co.uk(443)
2 1 0.0047 (0.0047) C>S Handshake
ClientHello
Version 3.3
cipher suites
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Unknown value 0xc013
Unknown value 0xc009
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Unknown value 0xc011
Unknown value 0xc007
Unknown value 0x9c
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_3DES_EDE_CBC_SHA
Unknown value 0xff
compression methods
NULL
2 2 0.0118 (0.0071) S>C Handshake
ServerHello
Version 3.1
session_id[0]=
cipherSuite TLS_RSA_WITH_AES_256_CBC_SHA
compressionMethod NULL
2 3 0.0118 (0.0000) S>C Handshake
Certificate
2 4 0.0118 (0.0000) S>C Handshake
ServerHelloDone
2 5 0.0123 (0.0005) C>S Handshake
ClientKeyExchange
2 6 0.0123 (0.0000) C>S ChangeCipherSpec
2 7 0.0123 (0.0000) C>S Handshake
Finished
2 8 0.0312 (0.0188) S>C Handshake
TLS_RSA_WITH_RC4_128_MD52 9 0.0312 (0.0000) S>C ChangeCipherSpec
2 10 0.0312 (0.0000) S>C Handshake
Finished
2 11 0.0319 (0.0007) C>S application_data
---------------------------------------------------------------
---------------------------------------------------------------
2 12 0.0319 (0.0000) C>S application_data
---------------------------------------------------------------
GET /Test HTTP/1.1
Host: gumdrop.benjojo.co.uk
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
---------------------------------------------------------------
2 13 0.0371 (0.0052) S>C application_data
---------------------------------------------------------------
HTTP/1.1 404 Not Found
Date: Thu, 05 Feb 2015 17:35:03 GMT
Server: Apache/2.2.16 (Debian)
Vary: Accept-Encoding
Content-Encoding: gzip
If you find that ssldump does not print anything either when letting it capture traffic itself, or when feeding in a tcpdump. You are most likely in a virtual machine where you cannot capture on the adapter normally, and have to use Linux Cooked Sockets. SSLDump cannot read this type of setup, but very unhelpfully does not tell you and will simply not output anything. The same applies if you are using tcpdump on OSX. That will use PKTAP, also not compatible with SSLDump.
You can test this by just running tcpdump, and the first thing it should output is a line like this:
tcpdump: data link type PKTAP
tcpdump: listening on pktap, link-type PKTAP (Packet Tap), capture size 65535 bytes
or in the case of Linux with OpenVZ or other HV’s
tcpdump: listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes