20
votes

I have a server to which many clients connect using SSL. Recently I'm observing SSL handshake errors in the server logs (ex SSL MAC error). The error itself is not important, but I want to see why some clients are able to connect while others are failing, and also need to identify which clients are failing.

For debugging this issue, I want to capture all SSL handshakes happening at server and since I don't know when the problematic clients connect, I don't want to capture all the traffic till that happens. I just want to capture all the SSL handshakes and later analyze them with Wireshark. Assume that I only have access to tcpdump and no other tools for capturing.

3
You can mention the SSL port in tcpdump for capture isn't?Prabhu
@Prabhu yes, but it will capture all data of that port. I just want to capture data till the SSL/TLS handshake completes for each request.sadiq.ali

3 Answers

45
votes

I don't know what exactly you are calling handshake, but I propose this command that will probably capture more than 95% of what you can want:

tcpdump -ni eth0 "tcp port 443 and (tcp[((tcp[12] & 0xf0) >> 2)] = 0x16)"

Now what does it do:

  • eth0: is my network interface, change it if you need
  • tcp port 443: I suppose this is the port your server is listening on, change it if you need
  • tcp[((tcp[12] & 0xf0) >> 2)] = 0x16: a bit more tricky, let's detail this below

tcp[12] means capturing the 13th byte of the tcp packet, corresponding to first half being the offset, second half being reserved. The offset, once multiplied by 4 gives the byte count of the TCP header, meaning ((tcp[12] & 0xf0) >> 2) provides the size of the TCP header.

The first byte of a TLS packet define the content type. The value 22 (0x16 in hexadecimal) has been defined as being "Handshake" content.

As a consequence, tcp[((tcp[12] & 0xf0) >> 2)] = 0x16 captures every packet having the first byte after the TCP header set to 0x16.

More filtering can be performed, but this strictly answers your question.

1
votes

I think the accepted answer is a premature optimization with a fragile solution.

SSL handshake occurs as soon at the connection is established.

Easy approach: start the capture before the client connects to the remote host, and capture the first, full N packets.

For example, for 300 packets:

/usr/sbin/tcpdump -i eth0 -p -s 65535 -c 300 "tcp and host 1.2.3.4 and port 443"

This way wireshark has the full payload of the SSL handshake, can decode it and show you all the bits.

1
votes

If you also want to grab SQL Server encryption then you also need to look at +8.

tcp[((tcp[12] & 0xf0) >> 2)] = 0x16  or (tcp port 1433 and tcp[((tcp[12] & 0xf0) >> 2) + 8] = 0x16)