Monitor an SSL certificate from outside your network
Check certificate expiry from a second machine
The local check returned the expiry date
Self-signed certificate on a disposable test VM, set to expire in 2 days. I served it on port 8443 with openssl s_server. The s_client check from 127.0.0.1 returned the expiry date on the first try:
notAfter=Oct 22 15:52:45 2026 GMT
I enabled UFW and allowed only port 22. ss -ltn confirmed the server was still listening on 8443, and the local check returned the same notAfter line.
Why did the local check ignore the firewall?
openssl s_client -connect 127.0.0.1:8443 connects through loopback. UFW does not apply to loopback traffic, so the packet never hits the firewall rules. A monitoring script running on the server it monitors will not see a blocked port.
From the second VM, the same port timed out
From a Debian 13 test VM I tried to open a TCP connection to port 8443 of the first machine, with a 10-second limit. After 10.002 seconds with no response the check returned exit code 124. Nothing came back. No TLS handshake, no certificate data. At that same moment, the local check on the first VM still returned notAfter=Oct 22 15:52:45 2026 GMT.
The verify error on a self-signed certificate
With verification turned on, the local check printed Verify return code: 18 (self-signed certificate). Expected. The certificate is not in the system trust store. A certificate from a public CA like Let's Encrypt would return verification code 0; the outside check works the same way regardless.
The days-left number was off by 1
I assumed days_left would show 2 for a certificate created with -days 2. The script printed days_left=1. The calculation subtracts the current epoch from the expiry epoch and divides by 86400, and because the check ran a short time after creation the remaining time was under 172800 seconds, so integer division truncated it to 1.
I think this is where alert thresholds go wrong quietly. Fire when days_left < 2 and it triggers the same day you issued a 2-day certificate. Fire when days_left < 1 and you get less than 24 hours of notice.
The full command
This reads the notAfter date from a remote machine. One line out.
echo | openssl s_client -connect 203.0.113.10:8443 \
-servername shop.example.test 2>/dev/null \
| openssl x509 -noout -enddate
echo sends an empty line so s_client does not wait for keyboard input. The -servername flag sets the SNI header, which matters when one IP serves more than one certificate. Port reachable: one notAfter= line. Port blocked: the command hangs. Wrap it in timeout to cap the wait, as the 10-second limit did on the Debian 13 test VM.