How to debug broken SSL

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the web-development category.

Last Updated: 2024-04-23

The SSL on my AWS server with jitsi video conferencing wasn't working, and I wanted to figure out exactly where the issue lied (e.g. was it the network firewall, the machine's firewall, docker on the host?)

Step 1. From the perspective of the host, is the port listening?

In practice, listening to a port means a process has bound to it. It has nothing to do with firewalls.

We'll use the lsof command, which lists information about files opened by processes. Since a file may be a network file (such as an internet socket, NFS file or UNIX domain socket), this will tell us what we want to know.

$ sudo lsof -i -P -n
# lsof needs root permissions to run
# -i selects all internet files and network connections

# OPTIONAL:
# -P inhibits the conversion of port numbers to port names for network files.  Inhibiting the conversion may make lsof run a little faster.  It is also useful when port name lookup is not working properly.
# -n inhibits the conversion of network numbers to host names for network files.  Inhibiting conversion may make lsof run faster.  It is also useful when host name lookup is not working properly.

COMMAND     PID            USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
sshd        837            root    3u  IPv4    16587      0t0  TCP *:22 (LISTEN)
sshd        837            root    4u  IPv6    19013      0t0  TCP *:22 (LISTEN)
systemd-n  8409 systemd-network   17u  IPv4 10022846      0t0  UDP 172.31.1.128:68
systemd-r  8430 systemd-resolve   12u  IPv4   350590      0t0  UDP 127.0.0.53:53
systemd-r  8430 systemd-resolve   13u  IPv4   350591      0t0  TCP 127.0.0.53:53 (LISTEN)
sshd      14894            root    3u  IPv4 10034806      0t0  TCP 172.31.1.128:22->88.72.175.230:52306 (ESTABLISHED)
sshd      14988          ubuntu    3u  IPv4 10034806      0t0  TCP 172.31.1.128:22->88.72.175.230:52306 (ESTABLISHED)
docker-pr 27964            root    4u  IPv6   514255      0t0  TCP *:443 (LISTEN)
docker-pr 27993            root    4u  IPv6   513701      0t0  TCP *:80 (LISTEN)
docker-pr 28423            root    4u  IPv6   516152      0t0  UDP *:10000
docker-pr 28459            root    4u  IPv6   516216      0t0  TCP *:4443 (LISTEN)

This seems promising as the 443 port is listening. To be extra sure, let's curl it from within the host machine:

$ curl https://localhost:443
curl: (51) SSL: no alternative certificate subject name matches target host name 'localhost'

Does this error mean it is listening? Yes it does. I know this because shutting down the corresponding docker container instead gives curl: (7) Failed to connect to localhost port 443: Connection refused.

Step 2: Can you reach the website from the outside?

I used nmap to scan the 443 (HTTPS) port of the host in question.

This will tell me the state of the port, which can either be:

$ nmap pandemie.thecodenottaken.com -p 443

Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-14 17:25 CET
Nmap scan report for pandemie.thecodenottaken.com (192.64.119.19)
Host is up (0.41s latency).

PORT    STATE    SERVICE
443/tcp filtered https

Here we see it is "filtered". Given that we know it is running on the server, this suggest firewall activity.

3. Trace the route and figure out if another device is blocking the connection

The reason for this step is to figure out what system is responsible (e.g. because it is mis-configured or has a firewall)

Run tcptraceroute (trace route with ports) and compare HTTP to HTTPS results to figure out if some router before your computer blocks it

# Use ip addresses, not DNS, so as to simplify situation

# Format: tcptraceroute IP PORT
sudo tcptraceroute 1.2.3.4 80
sudo tcptraceroute 1.2.3.4 443

The port 80 went all the way and the command returned normally. However, port 443 failed with "destination not reached". So something on the way was blocking it. At this point I thought to check my AWS network settings (which solved the issue)

Aside on SSL and sub-domains

I realized through doing this that I could connect to https://thecodenottaken.com but not https://pandemie.thecodenottaken.com. Standard SSL certs are for one domain only! Otherwise you need wildcards.