Files
zabbix-ssl-checker/README.md
T
2026-05-21 20:05:02 +02:00

8.9 KiB

Zabbix SSL Checker

Centrale SSL/TLS- en HTTPS-monitoring voor homelab- en kleine infra-omgevingen met Zabbix 7.x.

Architectuur

Deze checker gebruikt één centrale Zabbix host, bijvoorbeeld Zabbix SSL Checker. Op die host draaien external scripts vanuit /usr/lib/zabbix/externalscripts/.

De Zabbix-template gebruikt Low-Level Discovery om targets uit /etc/zabbix/ssl_targets.json te ontdekken. Per ontdekt target draait één master item:

ssl_check.py["--config","{$SSL_CONFIG}","--host","{#SSL_HOST}","--port","{#SSL_PORT}"]

Dat master item geeft één JSON-object terug met TLS-, certificaat- en HTTP-informatie. Alle andere items zijn dependent items met JSONPath preprocessing.

Er is dus géén Zabbix agent-interface nodig op je losse homelab-hosts. Dat voorkomt rode ZBX agent availability op systemen waar je helemaal geen agent wilt of kunt installeren. Zabbix bewaakt alleen de centrale checker-host; de echte HTTPS-targets worden agentloos vanaf die plek gecontroleerd.

Bestanden

zabbix-ssl-checker/
  README.md
  config/
    ssl_targets.json.example
  scripts/
    ssl_discovery.py
    ssl_check.py
  zabbix/
    template_ssl_checker_relaxed_zabbix_7.yaml
    MANUAL_TEMPLATE_STEPS.md
  tests/
    test_config_validation.py
    test_ssl_check_basic.py

Requirements

  • Python 3.11+
  • Zabbix server of proxy met external scripts enabled
  • Geen verplichte Python dependencies buiten de standaardbibliotheek

Optioneel:

  • cryptography voor betere parsing van SAN, issuer, subject, public key type, key size en signature algorithm.

Zonder cryptography blijft de checker werken. Velden die niet betrouwbaar te bepalen zijn, worden null en er komt een melding in warnings.

Installatie

Voer dit uit op de Zabbix server, proxy of checker-host:

sudo install -o zabbix -g zabbix -m 0755 scripts/ssl_discovery.py /usr/lib/zabbix/externalscripts/
sudo install -o zabbix -g zabbix -m 0755 scripts/ssl_check.py /usr/lib/zabbix/externalscripts/
sudo install -o zabbix -g zabbix -m 0640 config/ssl_targets.json.example /etc/zabbix/ssl_targets.json

Controleer dat de Zabbix user de config kan lezen:

sudo chown zabbix:zabbix /etc/zabbix/ssl_targets.json
sudo chmod 0640 /etc/zabbix/ssl_targets.json

Pas daarna /etc/zabbix/ssl_targets.json aan voor je eigen targets.

Installatie met Docker

Gebruik je de officiële Zabbix Docker-images, dan is het meestal praktischer om external scripts en de target-config in het persistente Zabbix data-volume te zetten. Met jouw volumeconfig:

volumes:
  - /media/zabbix/zabbix-server-data:/var/lib/zabbix
  - /media/zabbix/zabbix-snmptraps-data:/var/lib/zabbix/snmptraps
  - /media/zabbix/zabbix-export-data:/var/lib/zabbix/export

kun je op de Docker-host deze paden gebruiken:

sudo install -d -o 1997 -g 1995 -m 0755 /media/zabbix/zabbix-server-data/externalscripts
sudo install -o 1997 -g 1995 -m 0755 scripts/ssl_discovery.py /media/zabbix/zabbix-server-data/externalscripts/
sudo install -o 1997 -g 1995 -m 0755 scripts/ssl_check.py /media/zabbix/zabbix-server-data/externalscripts/
sudo install -o 1997 -g 1995 -m 0640 config/ssl_targets.json.example /media/zabbix/zabbix-server-data/ssl_targets.json

In de container worden deze bestanden dan zichtbaar als:

/var/lib/zabbix/externalscripts/ssl_discovery.py
/var/lib/zabbix/externalscripts/ssl_check.py
/var/lib/zabbix/ssl_targets.json

Zet op de host {$SSL_CONFIG} in de gelinkte template of host-macro daarom op:

/var/lib/zabbix/ssl_targets.json

Test daarna vanuit de Zabbix server-container. Vervang zabbix-server door de naam van jouw container:

docker exec -u zabbix zabbix-server /var/lib/zabbix/externalscripts/ssl_discovery.py --config /var/lib/zabbix/ssl_targets.json
docker exec -u zabbix zabbix-server /var/lib/zabbix/externalscripts/ssl_check.py --config /var/lib/zabbix/ssl_targets.json --host home.blockje.nl --port 443

Als jouw image external scripts niet uit /var/lib/zabbix/externalscripts leest, mount dan expliciet naar de directory die in de container als ExternalScripts is ingesteld. Vaak is dat bij niet-Docker installaties /usr/lib/zabbix/externalscripts. Controleer bij twijfel de Zabbix server/proxy configuratie in de container.

Let op met UID/GID: officiële Zabbix containers gebruiken vaak de zabbix gebruiker binnen de container. De numerieke 1997:1995 komt veel voor, maar kan per image verschillen. Als de testcommando's permission errors geven, controleer dan met:

docker exec zabbix-server id zabbix
docker exec zabbix-server ls -l /var/lib/zabbix/externalscripts /var/lib/zabbix/ssl_targets.json

Configuratie

Voorbeeld:

[
  {
    "name": "Blockje Home",
    "host": "home.blockje.nl",
    "port": 443,
    "owner": "blockje",
    "profile": "relaxed",
    "expected_issuer_contains": "Let's Encrypt",
    "expected_hostname": "home.blockje.nl",
    "http_check": true,
    "expected_http_status": [200, 301, 302, 401, 403],
    "timeout": 10
  }
]

Verplichte velden:

  • name
  • host
  • port
  • owner
  • profile

Toegestane profiles:

  • relaxed
  • serious
  • internal
  • external

Als expected_hostname ontbreekt, gebruikt de checker automatisch host.

Dubbele targets op dezelfde host:port worden één keer meegenomen in discovery.

Testcommando's

Als gebruiker zabbix:

sudo -u zabbix /usr/lib/zabbix/externalscripts/ssl_discovery.py --config /etc/zabbix/ssl_targets.json
sudo -u zabbix /usr/lib/zabbix/externalscripts/ssl_check.py --config /etc/zabbix/ssl_targets.json --host home.blockje.nl --port 443

Zonder config kan ook:

./scripts/ssl_check.py --host home.blockje.nl --port 443 --expected-hostname home.blockje.nl --http-check

De scripts schrijven meetdata naar stdout en fouten/debugmeldingen naar stderr. ssl_check.py geeft bij TLS- of bereikbaarheidsproblemen nog steeds JSON terug, zodat dependent items stabiel blijven.

Zabbix import

  1. Ga naar Data collection -> Templates -> Import.
  2. Importeer zabbix/template_ssl_checker_relaxed_zabbix_7.yaml.
  3. Maak een nieuwe host:
    • Host name: Zabbix SSL Checker
    • Interfaces: geen externe homelab-agent interfaces nodig
    • Link template: Template SSL Checker Relaxed
    • Macro {$SSL_CONFIG}: /etc/zabbix/ssl_targets.json
  4. Laat discovery draaien of klik op Execute now bij de discovery rule.

Als import faalt door YAML-verschillen tussen Zabbix 7.x minor releases, gebruik dan zabbix/MANUAL_TEMPLATE_STEPS.md.

Wat wordt gecontroleerd

TLS/certificaat:

  • bereikbaarheid
  • hostname match
  • chain validity via de default trust store
  • self-signed detectie waar mogelijk
  • geldigheid nu, not before, not after en days left
  • issuer CN/org, subject CN, SAN names
  • SHA256 fingerprint
  • negotiated TLS version
  • TLS 1.0, 1.1, 1.2 en 1.3 support waar Python/OpenSSL dat toestaat

HTTP:

  • HTTPS request met maximaal 5 redirects
  • response time
  • final URL
  • statuscode en verwachte status
  • Server header
  • HSTS
  • X-Content-Type-Options
  • X-Frame-Options
  • Content-Security-Policy
  • Referrer-Policy
  • simpele security header score van 0 tot 5

Debugtips

Unsupported items:

  • Controleer of de scripts executable zijn.
  • Controleer of ze in de Zabbix ExternalScripts directory staan.
  • Run exact dezelfde key als zabbix user.
  • Kijk in zabbix_server.log of zabbix_proxy.log.

Script permissies:

  • Scripts: 0755, owner zabbix:zabbix
  • Config: 0640, owner zabbix:zabbix

Python dependencies:

  • De basis gebruikt alleen standaardbibliotheken.
  • Installeer optioneel cryptography als je rijkere key- en signaturevelden wilt.

DNS/firewall:

  • Test DNS vanaf de checker-host, niet vanaf je laptop.
  • Test of de checker-host TCP 443 naar het target mag openen.

CA trust store:

  • Chain-validatie gebruikt de default trust store van Python/OpenSSL.
  • Voor interne CA's moet de CA op de checker-host trusted zijn.

SNI:

  • De checker gebruikt SNI met expected_hostname.
  • Bij shared hosting moet expected_hostname overeenkomen met de certificaatnaam die je verwacht.

Security

  • Het configbestand bevat geen secrets.
  • Maak het toch niet world-writable.
  • Hostnamen, poorten en profiles worden gevalideerd.
  • Er wordt geen shell=True gebruikt.
  • Er wordt geen ruwe input in shellcommando's gestopt.
  • De checker gebruikt geen openssl subprocess; TLS loopt via Python ssl en socket.
  • Timeouts worden op netwerkverbindingen toegepast zodat checks niet blijven hangen.

Tuning

Standaard in de template:

  • Discovery interval: 1h
  • Check interval: 15m
  • History raw JSON: 7d
  • History dependent items: 30d
  • Trends numerieke dependent items: 365d

De profiles relaxed, serious, internal en external zijn nu vooral metadata en tags. Je kunt later per profile extra triggers of strengere policies toevoegen.

Tests

Lokaal:

python -m pytest

De tests controleren configuratievalidatie, discovery output en JSON-output bij een onbereikbaar target.