Veel websites gebruiken Let's Encrypt certificaten om hun website via HTTPS aan te bieden. Die certificaten zijn 90 dagen geldig en worden automatisch verlengd. Tenminste, vaak. Maar soms gaat er iets fout. Let's Encrypt stuurde je mailtjes als de verloopdatum eraan komt (of als die datum verlopen was?), maar is daar in 2025 mee gestopt (artikel op de website). Dus je moet zelf iets regelen om die monitoring uit te voeren, want als er wat fout gaat en je klant belt dat de website al 2 weken niet meer via HTTPS bereikbaar is, dat kun je niet maken. En ook omdat we vaak HSTS-headers sturen: heb je de site 1x via HTTPS bezocht, dan wordt een bezoek via HTTP altijd geweigerd. En we willen juist dat mensen de site via HTTPS bezoeken, dus dat wordt ook altijd vanaf de server afgedwongen.
Als je zelf Zabbix-monitoring hebt, dan is het redelijk simpel om het ook zelf te monitoren. Het script is volgens mij door mijn oud-collega Dirk-Jan en/of Jan Reilink uitgewerkt, dus ik neem het zo over, zoals het er staat, want het werkt al jaren:
# ik noem dit bestand check_ssl.sh
output=$(echo | timeout 1 openssl s_client -servername $1 -connect $1:443 2>/dev/null)
expire_date=$( echo "$output" | openssl x509 -noout -dates | grep '^notAfter' | cut -d'=' -f2 )
expire_date_epoch=$(date -d "$expire_date" +%s) || error "Failed to get expire date"
current_date_epoch=$(date +%s)
days_left=$(( ($expire_date_epoch - $current_date_epoch)/(3600*24) ))
echo $days_left
Nu had ik zelf een Zabbix-omgeving met Docker opgezet, dus ook ik wilde dit script beschikbaar maken.
Ik heb hier niet de "luxe" van Docker Desktop, daar kun je namelijk zo in de terminal komen.
Het is nu een kwestie van via SSH op je VPS inloggen.
Daarna het volgende commando uitvoeren:
docker ps
Hierdoor zie je alle containers. Het gaat mij om de zabbix-agent-mysql.
Deze heeft CONTAINER ID fxxxxfxxxxxx
docker exec -it -u 0 fxxxxfxxxxxx /bin/bash
Ik ga naar /etc/zabbix en maak hier een map scripts aan.
Daar maak ik het bovenstaande bestand aan.
En ik test het bestand even uit, dus ik roep het aan met ./check_ssl.sh techblog.dirkhornstra.nl
De eerste foutmelding die ik krijg is dat commando openssl niet gevonden wordt. Die is niet geïnstalleerd, dat kun je doen door het volgende commando uit te voeren:
apk add openssl
Hierna werkt het.
Nu moeten we het script nog toevoegen aan de User parameters.
Ik heb in /etc/zabbix/zabbix_agentd_user_parameters.conf de volgende regel toegevoegd:
UserParameter=sslexpiration[*],/etc/zabbix/scripts/check_ssl.sh $1
Hierna in bash het volgende commando uitgevoerd:
zabbix_agentd -R userparameter_reload
Daar krijg ik een foutmelding op:
ERROR: StartAgents is not 0, parameter "Server" must be defined
Dus in Plesk dan de zabbix-agent container maar geherstart.
Daarmee heb je de functie beschikbaar gesteld aan de Agent.
Vervolgens ga je in Zabbix server aan de slag, bij een template voeg je een item toe:
Item Type: Zabbix Agent
Type: Numeric(float)
Key: sslexpiration[{HOST.NAME}]
Daarmee kun je gaan testen om te kijken of er netjes een waarde binnen komt. Dan moet je nog 1 of meerdere triggers aanmaken, afhankelijk van hoe vaak je van tevoren al wilt melden dat er "een probleem is". Omdat wij een certificaat 60 dagen laten draaien en 'm dan vernieuwen, hebben we rond de 30 dagen de tijd. Als een certificaat "nog maar" 2 weken geldig is, dan moet je wel een melding krijgen. Als ie nog 7 dagen geldig is, hetzelfde. En "morgen" is dan de last-call-to action.
De expressie die je aanmaakt is simpel:
last(/[TEMPLATE_NAME]/sslexpiration[{HOST.NAME}])<= 14
Deze is voor de 2 weken, voor de andere 2 triggers zet je daar een 7 of 1 in.
Extra informatie - instellen op server in plaats van agent
Ik had het eerst verkeerd aangepakt, ik had namelijk de Docker container van Zabbix server gebruikt. Maar die voert geen User parameters uit.
Dus als je het daar doet, dan doe je het op de verkeerde plek.
Heb je het toch nodig op die plek, dan kom je misschien dezelfde fouten tegen als die ik tegengekomen ben.
En ook opgelost heb. Daarom heb ik deze informatie hier nog even toegevoegd, want dat scheelt jou weer uitzoekwerk :)
Ik krijg wat foutmeldingen, dat komt door de datumnotatie.
date: invalid date 'Apr 1 11:01:52 2026 GMT'
Dus in mijn Docker-container pas ik het script aan naar dit:
output=$(echo | timeout 1 openssl s_client -servername $1 -connect $1:443 2>/dev/null)
expire_date=$( echo "$output" | openssl x509 -noout -dates | grep '^notAfter' | cut -d'=' -f2 )
expire_date=$( echo "$expire_date" | cut -d'GMT' -f1 | xargs )
expire_date_epoch=$(date -d "$expire_date" +%s) || error "Failed to get expire date"
current_date_epoch=$(date +%s)
days_left=$(( ($expire_date_epoch - $current_date_epoch)/(3600*24) ))
echo $days_left
Hierna werkt het.
Extra informatie - deze configuratie bewaren
Na een licht gecrashte update van Plesk heb ik de VPS herstart. Maar... daardoor waren deze zaken in de Docker container "weg". Ik moet er nog even naar kijken, ik zag een optie om een "snapshot" te maken, voor de agent-container zou dat wel een goede optie zijn.
Mogelijk dat ik zelf nog wat ga doen met de basis-image, als daar zaken al in staan, heb je die ook direct in de container beschikbaar. Daar kom ik in een latere blogpost nog op terug. Maar als dit voor jou een zeer belangrijk item is, kun je er het beste nu mee aan de slag gaan, voordat zaken weg zijn en je alles opnieuw moet doen.