27 juillet 2024

Tuto monitoring Prometheus, partie V : BlackBox Exporter

Cinquième partie de la série de tutoriels consacrés au monitoring avec Prometheus. Nous allons mettre en place Blackbox Exporter, un outil permettant de faire du monitoring  en « boite noire ».

Les sondes sont « externes » au système à monitorer et se contente de vérifications qu’un utilisateur lambda pourrait faire à la main. C’est en quelque sorte le contraire du monitoring en boite blanche (ce que fait Node Exporter), où l’on accède à toutes les métriques du serveur directement.

Blackbox Exporter permet d’utiliser quatre types de sondes (probe) : ICMP, HTTP(s), DNS et TCP.

Ici, il sera installé sur le serveur Prometheus. On pensera éventuellement à ouvrir les ports sur le FW si besoin.

 

I – Installation

La routine :

# wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.14.0/blackbox_exporter-0.14.0.linux-amd64.tar.gz
# tar xvf blackbox_exporter-0.14.0.linux-amd64.tar.gz
# cd blackbox_exporter-0.14.0.linux-amd64.tar.gz/
# cp blackbox_exporter /usr/local/bin/
# mkdir /etc/blackbox_exporter

 

II – Configuration

A – Blackbox

Pour la configuration, cela se passe dans /etc/blackbox_exporter/blackbox.yml :

modules:
  http_check:
    prober: http
    timeout: 5s
    http:
      valid_status_codes: [] # par defaut, 2XX
      method: GET
      fail_if_body_matches_regexp:
        - "Erreur lors de la connexion"
  icmp_check:
    prober: icmp
    timeout: 5s
    icmp:
      preferred_ip_protocol: ip4
  dns_check_soa:
    prober: dns
    timeout: 5s
    dns:
      preferred_ip_protocol: ip4
      query_name: "debugo.fr"
      query_type: "SOA"
  smtp_check:
    prober: tcp
    timeout: 5s
    tcp:
      preferred_ip_protocol: "ip4"
      query_response:
        - expect: "^220 ([^ ]+) ESMTP (.+)$"
        - send: "EHLO ProberCheck"
        - expect: "^250-STARTTLS"
        - send: "STARTTLS"
        - expect: "^220"
        - starttls: true
        - send: "EHLO ProberCheck"
        - expect: "^250-AUTH"
        - send: "QUIT"
 imap_check:
    prober: tcp
    timeout: 5s
    tcp:
      tls: true
      preferred_ip_protocol: "ip4"
      query_response:
        - expect: "CAPABILITY IMAP4rev1"
        - send: "QUIT"

Un module correspond à un ensemble de paramètres que vous allez configurer et qui définissent les « options » du prober choisi.

Pour l’exemple, j’ai en fait un avec chaque probe (sauf Tcp ou je l’utilise deux fois).

Pour chaque module, on trouve son nom (http_check, icmp_check,etc…), la probe utilisée (http,icmp,dns ou tcp)  et la configuration associée.

Http : l’astuce consiste ici a faire échouer la sonde si le message « Erreur lors de la connexion » est présent.
En effet, si mon WordPress ne communique plus avec la base, pour la probe, on reçoit bien le code HTTP 200, mais pour autant, le site ne fonctionne pas.

Icmp : on force juste en IPv4.

Dns : le check va simplement vérifier le champ SOA.
Par exemple pour regarde si la propagation DNS est correcte en interrogeant votre serveur autoritaire et d’autres et en comparant les réponses.
On peut bien évidement interroger d’autres champs, regarder les réponses, etc…

Tcp : surement le module le plus intéressant, celui ci va nous permettre d’établir une connexion sur un service et de vérifier les réponses.

Ici, je m’en sers pour vérifier deux serveur : SMTP et IMAP. Le ping n’est pas suffisant pour cela, la machine peut encore tourner et Postfix et/ou Dovecot peuvent être dans les choux
Rien de sorcier, on donne des commandes, on regarde les retours.

Pour l’imap, comme je fais du Imaps et non pas du imap puis ensuite du ssl…, la configuration active le tls des le début de la connexion.

Envie d’ailleurs de monter votre serveur mail complet ? Je vous invite à regarder la série de tutoriels (oui, je me fais de la pub…)

Libre à vous d’imaginer des sondes pour des serveurs IRC, SSH, LDAP, etc…

 

Pour plus d’infos : https://github.com/prometheus/blackbox_exporter et un exemple assez complet : https://github.com/prometheus/blackbox_exporter/blob/master/example.yml

Pour recharger BlackBox en cas de modification de la configuration :

# curl -X POST http://localhost:9115/-/reload

 

C – Droit de Ping

Le ping pose un petit soucis de droit si blackbox n’est pas executé en root.

Ça se règle simplement avec :

# apt-get install libcap2-bin
# setcap cap_net_raw+ep /usr/local/binblackbox_exporter

Et on peut vérifier avec

# getcap /usr/local/binblackbox_exporter

A priori, on peut aussi ajouter ce qui suit dans le fichier de service :

[Service]
User=...
Group=...
AmbientCapabilities=CAP_NET_RAW

Bref, peu importe mais faite un truc 😉

 

III – Mise en place

A – A la mimine

On teste :

# blackbox_exporter --config.file /etc/blackbox_exporter/blackbox.yml

Ras, ça se lance.

B – En Service

Encore la routine :

# useradd --no-create-home --shell /bin/false blackbox_exporter
# chown blackbox_exporter:blackbox_exporter /etc/blackbox_exporter/ -R
# chown blackbox_exporter:blackbox_exporter /usr/local/bin/blackbox_exporter

Puis un fichier /etc/systemd/system/blackbox_exporter.service :

[Unit]
Description=Blackbox Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=blackbox_exporter
Group=blackbox_exporter
Type=simple
ExecStart=/usr/local/bin/blackbox_exporter \
    --config.file /etc/blackbox_exporter/blackbox.yml

[Install]
WantedBy=multi-user.target

Et pour terminer :

# systemctl daemon-reload
# systemctl enable blackbox_exporter.service
# service blackbox_exporter start

Puis :

# service blackbox_exporter status

C – Du ménage

# cd
# rm blackbox_exporter-0.14.0.linux-amd64 -r
# rm blackbox_exporter-0.14.0.linux-amd64.tar.gz

IV – Utilisation

On va tester :

# curl -s "localhost:9115/probe?module=http_check&target=https://mondomaine.fr"

Et comme c’est bavard, on peut faire :

# curl -s "localhost:9115/probe?module=http_check&target=https://mondomaine.fr" | grep -v \#

Et l’on observe toutes les informations relevées par la sonde.

Pour les autres modules :

# curl -s "localhost:9115/probe?module=dns_check&target=XXX.XXX.XXX.XXX" | grep -v \#
# curl -s "localhost:9115/probe?module=smtp_check&target=XXX.XXX.XXX.XXX:25" | grep -v \#
# curl -s "localhost:9115/probe?module=imap_check&target=XXX.XXX.XXX.XXX:993" | grep -v \#
# curl -s "localhost:9115/probe?module=icmp_check&target=XXX.XXX.XXX.XXX" | grep -v \#

On peut activer le debug (dont je parlais plus haut) avec :

# curl -s "localhost:9115/probe?debug=true&module=http_check&target=https://mondomaine.fr"

 

V – Jobs dans Prometheus

A – Configuration

On va maintenant créer les jobs correspondants dans Prometheus.

Dans la partie scrape_configs du fichier /etc/prometheus/prometheus.yml :

scrape_configs:
  [...]
  - job_name: 'CheckUrl'
    metrics_path: /probe
    params:
      module: [http_check]
    static_configs:
      - targets:
        - https://mondomaine.fr
        - https://monautredomaine.fr
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: localhost:9115
  - job_name: 'Ping'
    metrics_path: /probe
    params:
      module: [icmp_check]
    static_configs:
      - targets:
        - XXX.XXX.XXX.XXX
        - YYY.YYY.YYY.YYY
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: localhost:9115
  - job_name: 'SMTP'
    metrics_path: /probe
    params:
      module: [smtp_check]
    scrape_interval: 60s
    static_configs:
      - targets:
        - smtp.mondomaine.fr:25
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: localhost:9115
  - job_name: 'DNS'
    metrics_path: /probe
    params:
      module: [dns_check_soa]
    static_configs:
      - targets:
        - XXX.XXX.XXX.XXX
        - 8.8.4.4
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: localhost:9115
  - job_name: 'IMAP'
    metrics_path: /probe
    params:
      module: [imap_check]
    scrape_interval: 60s
    static_configs:
      - targets:
        - imap.mondomaine.fr:993
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: localhost:9115

Pensez à remplacer les URLs et les IPs. et bien évidement, vous pouvez en mettre autant que desirés.

Pour les modules qui utilisent la probe TCP (smtp_checl et imap_check), il faut penser à indiquer le port.

Vous remarquerez aussi que pour ces deux la, je change le temps de scrap pour ne le faire qu’une fois par minute.

Le relabelling permet de garder les choses aux propres.

On recharge Prometheus :

# curl -X POST http://localhost:9090/-/reload

B – Attention

Attention, pour les checks croisant des certificats en chemin : si vos certificats sont enregistrés pour un FQDN (typiquement ceux de Let’s Encrypt) , renseigner l’IP conduira à une erreur :

msg= »TLS Handshake (client) failed » err= »x509: cannot validate certificate for XXX.XXX.XXX.XXX because it doesn’t contain any IP SANs »

On peut toujours rajouter cela dans la configuration de Black Exporter :

  tcp:
    tls: true
    tls_config:
      insecure_skip_verify: true
    preferred_ip_protocol: "ip4"

Ce qui permettra de passer par l’IP. Mais on passerait à coté d’un éventuel autre probleme de certificat.

Il faut donc mieux passer par le FQDN……. Ce qui peut conduire à un autre problème si la machine qui héberge le service externe (proxy web par exemple) est sur le même réseau que votre machine qui va sonder.

En effet, au niveau du routeur, il va être embêté. Que faire de ces paquets à destination de son IP externe mais en provenance de l’interne ?

La solution : il faut mettre en place le Nat Loopback.

 

C – Interface Web Prometheus

Passons ensuite dans l’interface Web de Prometheus.

Tout d’abord, dans Status/Targets, on peut voir nos nouvelles entrées et tout doit être Up.

Puis dans la partie Graph, on peut lancer par exemple :

probe_success

On obtient alors le retour de cette métrique pour chaque sonde.

 

VI – Grafana

La, on va pouvoir se faire de jolis Dashboards avec plein de choses vertes 😉

Je donne juste un exemple :

Dans Grafana, créez un nouveau Dashboard, puis Add Query.

Ajoutez cette requête:

probe_success{job="CheckUrls",instance="https://mondomaine.fr"}

Puis dans Visualization, remplacez Graph par SingleStat.
Dans la partie Coloring, activez le Background, Thresholds réglé à 0,1.
Dans Colors, cliquez Invert.
Et pour terminer, dans Value Mappings, indiquez pour 0 : Oups et pour 1: Yeah !.

On sauvegarde et on admire !

Facile non ?

Vous voulez afficher le SOA d’une prob DNS ?

Ce sera :

probe_dns_serial

A vous d’imaginer ensuite vos propres panels.

 

 

 

VII – Vérification des certificats SSL

Vous être chez Let’s Encrypt pour vos certificats ? Vous n’êtes donc pas sans savoir qu’ils ont une durée de 90 jours et doivent donc être renouvelé régulièrement.

Par défaut, Acme.sh (que j’utilise) créé la tâche cron qui va bien et tout roule.

Mais je me suis déjà fait avoir en modifiant une config dans un coin, qui a eu pour effet de bord de modifier un truc qui a modifié un truc, etc… Bref, la renouvellement avait échoué,  comme un idiot, je ne l’avais pas vu et je m’en suis rendu compte bêtement en allant sur mon site et en voyant une belle erreur !

Bref, ce serait bien d’avoir un moyen de vérifier cela.

Et ça tombe bien, car à chaque fois qu’une probe de Black Exporter croise un certificat sur son chemin, elle lui pose une question …intime…

Allez dans Grafana, faites une nouvelles requête avec :

probe_ssl_earliest_cert_expiry

Tiens, intéressant ! C’est la date de fin de validité de nos certificats, exprimée en temps Unix.

On va par exemple filtrer sur

probe_success{instance="https://blog.debugo.fr"}

On va passer en mode de visualisation single stat pour avoir la valeur exacte.

On peut connaitre le nombre de seconde restante avec :

probe_ssl_earliest_cert_expiry{instance="https://blog.debugo.fr"} - time()

Pour formater ça de manière lisible, dans Units, sélectionnez Time puis Duration (s). En decimals, vous en mettez 2, et voila !

 

Ce champ étant disponible à chaque certificat présent, avec la probe SMTP, on obtient donc aussi sa date de fin de validité.

probe_ssl_earliest_cert_expiry{instance="XXX.XXX.XXX.XXX:25",job="SMTP"}

 

VIII – Alertes

Bien évidement, on peut faire des alertes sur toutes ces informations.

Par exemple, dans un fichier /etc/prometheus/rules/black_alerts.yml :

groups:
- name: black
  rules:
  - alert: BlackProbe
    expr: probe_success == 0
    for: 10s
    labels:
      severity: "critical"
    annotations:
      summary: "Sur le Job {{ $labels.job }}, il semble que {{ $labels.instance }} ne reponde pas"
  - alert: HTTP200
    expr: probe_http_status_code != 200
    for: 10s
    labels:
      severity: "critical"
    annotations:
      summary: "Sur le Job {{ $labels.job }}, il semble que {{ $labels.instance }} ne fonctionne pas correctement"
- name: ssl_expiry
  rules:
  - alert: SSLCertExpiration
    expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30
    for: 1m
    labels:
      severity: "critical"
    annotations:
      summary: "Le certificat de {{ $labels.instance }} va expirer dans un mois."

 

On peut vérifier le fichier avec :

# promtool check rules /etc/prometheus/rules/black_alerts.yml

On peut remettre les permissions :

# chown prometheus:prometheus /etc/prometheus/ -R

Puis on recharge Prometheus :

# curl -X POST http://localhost:9090/-/reload

 

IX – Conclusion

Et voila pour cette rapide présentation de Blackbox Exporter et de ses possibilités.

L’outil est simple mais  se révèle cependant très utile pour monitorer la réponse de services.

 

Dans la partie suivante, nous allons parler de Text Collector, un module de Node Exporter.

 


Envie de me soutenir et de me payer un café ? C’est sur la page Don !

 

3 réflexions sur « Tuto monitoring Prometheus, partie V : BlackBox Exporter »

  1. Chouette tuto que je vais rajouter dans mes « à faire un jour ». 🙂
    Ça serait chouette d’avoir un screenshot de ton interface finale pour mieux imaginer à quoi ça ressemble.

  2. Salut et merci !
    Je ne pensais pas qu’il serait lu si vite apres mise en ligne, mais tant mieux !
    Bon, j’vais être honnête, mon interface est loin d’être terminée (et la série aussi), mais j’y penserais !

  3. Hello,
    Toute la série est mise en place chez moi sur un serveur de prod, avec les alertes configurées et quelques dashboard.

    Quelques difficultés cependant pour trouver des exporter pour nginx, lorsque celui-ci est déjà compilé sans les bons modules, c’est quasiment impossible. Pour MariaDB, il ne semble pas exister d’exporter, celui pour MySQL ne fonctionne pas.

    Belle solution mais encore perfectible malgré les nombreux exporter déjà disponibles. Concernant l’alert manager, ce qui m’intéresse le plus, il faut que je comprenne en détail comment il fonctionne. J’utilise Nagios sur d’autres plateformes depuis très longtemps et j’en suis très satisfait sur son intelligence de notification. Je souhaite retrouver cette même souplesse avec la suite Prometheus.

    Hâte de lire la suite de cette série et éventuellement un retour d’expérience de ton côté (+/- 1 an que tu utilises cette stack apparemment)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *