Ce rulez în docker – editia de primavara 2022

Versiunea de primavara a postului asta.

Pe scurt:

Pe lung:

  • nut-influxdb-exporter – exporter de metrici pentru NUT. Metricile se citesc dintr-un server de NUT si se trimit in InfluxDB, apoi din InfluxDB le vad in Grafana cu dashboard-ul asta.
  • grafana – Grafana. Metrici. Grafice. Chestii. O sa fac o gluma si o sa zic “lasati Grafana si invatati Cacti!” (cine stie cunoaste)
  • prometheus – time series database. Data source pentru Grafana. (vezi mai jos)
  • influxdb – time series database. Data source pentru Grafana. Colectez datele cu telegraf si le salvez in influx.
  • chronograf – dashboard pentru Influx dar poate fi folosit ca un client de Influx de unde poti gestiona datele. (eu pentru asta l-am instalat)
  • observium – Observium. Se conecteaza la observium_db si salveaza datele acolo. Grafice. Metrici. Niciodata nu sunt destule. Daca Grafana este utila si personalizabila dupa bunul plac, Observium e mai mult indreptat catre retelari. 
  • portainer_agent – agentul de Portainer.io, pentru ca lene si pentru ca imi place docker dar nu prea. Nu am chef sa stau sa invat si sa fac retete de docker cand pot sa dau 3 click-uri si sa am un container.
  • mikrotik-exporter – exporter de metrici pentru device-urile Mikrotik. Datele se scriu in Prometheus si le vad in Grafana cu dashboard-ul asta.
  • pihole-exporter – exporter de metrici pentru PiHole. Datele se scriu in Prometheus si le vad in Grafana cu dashboard-ul asta.
  • cerebro – web admin tool pentru Elasticsearch.
  • watchtower – autoupdater pentru imaginile de docker.

Se mai adaugă:

  • pihole – Pihole. Server de DNS cu adblocker. Îl rulam pe un VM dar mi-am dat seama ca e ușor de migrat în docker.
  • Nginx-proxy – proxy pentru unele containere ce trebuiesc accesate
  • piair_php și piair_web și piair_mysql – practic site-ul asta. Sursa e aicisa.
  • cupsd – cupid în docker. Îmi trebuie ca am un cron care declanșează o data la 5 zile un print color și alb negru sa nu se usuce cerneala în imprimanta. (Nu o folosesc zilnic)
  • unbound – Unbound – server DNS. Îl folosesc ca upstream pentru Pihole.
  • smokeping – un fel de observium, dar mai rudimentar și știe doar ping.
  • autoheal – dacă crapă ceva ce are health check activat, se restarteaza automat containerul.
  • yeelight – un cron care pornește un bec în funcție de apusul soarelui. Sursa aici.
  • unifi-controller – controllerul de Unifi. Îl rulam separat într-un VM, la fel ca Pihole, dar l-am mutat în docker.
  • unbound-exporter – statistici pentru unbound, sa le văd în Grafana
  • openweather-exporter – statistici pentru vreme, sa le văd în Grafana

Bonus:

Am instalat de ~o săptămână Mailcow în docker. Pare o soluție de mail destul de completa, e foarte interesanta și vine destul de OK configurată by default. Sunt câteva chestii care nu îmi convin, sunt unele care îmi plac, dar per total recomand.

Manual auto SSL pe Synology

Pentru ca sunt sărac și nu vreau sa dau o grămadă de bani pe un certificat wildcard pe un an, folosesc o struto-camila intre Cloudflare și Letsencrypt. Chiar dacă Cloudflare oferă certificat gratuit timp de un an (care se reinoieste gratuit o data la un an), nu poți să-l descarci de undeva ca să-l pui și pe alte servere, așa ca am rămas cu Letsencrypt pentru anumite servicii. Problema cu LE este ca certificatul trebuie schimbat la 3 luni, așa ca am încercat sa “automatizez” chestia asta cum am putut eu mai bine.

Disclaimer: Probabil exista și o alta metoda mult mai buna, dar pentru mine funcționează, deci I’m happy with it.

Ca sa înțelegeți putin infrastructura: 1 server web, 1 server de mail, 1 server de docker cu nginx care face reverse proxy și 1 server de “storage” pe un Synology. Singurul lucru comun între “servere”/locații e un certificat SSL.

Am început lejer, cu serverul de mail. Pe serverul de mail rulez un script care verifica atunci când certificatul a expirat și atunci când condiția se întâmplă, face un SSH pe serverul web și copiază certificatele noi, apoi da restart la servicii (postfix și dovecot). Bine, de fapt pe toate rulez același script, diferă doar ce se întâmplă în condiția logica atunci când certificatul expira. Trebuie sa menționez ca serverul web face reînnoire automata prin API-ul DNS Cloudflare cu ajutorul lui certbot. Asta e serverul principal, ca sa zic așa, de la el pornește tot, el deține adevarul.

Pe celălalt server de web/docker se întâmplă același lucru ca pe cel de mail, excepție fiind faptul ca dau restart la nginx și diferă calea unde e pus certificatul.

Iar acum vine durerea mare: NAS-ul Synology. A fost un fel de PITA sa mă prind pe unde isi arunca jegul certificatele, am căutat informații pe Google și am încercat tot felul de chestii pana m-am prins ce și cum. Se pare ca Syno nu folosește locația certificatului dintr-un loc predefinit, ci din mai multe locuri pentru diferite aplicații. Stupid, poate. Eu așa o văd. Te-ai gândi ca ai o locație de unde isi citește certificatele instalate în sistem, dar se pare ca nu, Syno e mai cu mot. Certificatul “principal” se afla în /usr/syno/etc/certificate/system. Certificatele pentru restul de aplicații sunt răspândite prin sistem. În fine, long story short, am ajuns la o varianta a scriptului așa:

#!/bin/bash

NOW=$(date +%s)
CERT_EXPIRY_DATE=$(echo | openssl s_client -servername subdomeniu.linux365.ro -connect subdom.linux365.ro:port 2>/dev/null | openssl x509 -noout -enddate | cut -d "=" -f 2)
CERT_EXPIRY_DATE_UNIX=$(date -d "$CERT_EXPIRY_DATE" +%s)

if [[ $NOW -gt $CERT_EXPIRY_DATE_UNIX ]]; then
    rsync -a --copy-links user@IP:/etc/letsencrypt/live/linux365.ro/ /tmp/certs/ && echo -e "Subject: Syno certs\n\nL365 syno certs sync'ed" | ssmtp [email protected]
	sudo cp -r /tmp/certs/* /usr/syno/etc/certificate/_archive/kVlb4z/
	sudo cp -r /tmp/certs/* /usr/local/etc/certificate/LogCenter/pkg-LogCenter/
	sudo cp -r /tmp/certs/* /usr/local/etc/certificate/ScsiTarget/pkg-scsi-plugin-server/
	sudo cp -r /tmp/certs/* /usr/local/etc/certificate/SynologyDrive/SynologyDrive/
	sudo chown -R root:root /usr/syno/etc/certificate/_archive/kVlb4z/
	sudo chown -R root:root /usr/local/etc/certificate/LogCenter/pkg-LogCenter/
	sudo chown -R root:root /usr/local/etc/certificate/ScsiTarget/pkg-scsi-plugin-server/
	sudo chown -R root:root /usr/local/etc/certificate/SynologyDrive/SynologyDrive/
	sudo chmod u=r -R /usr/syno/etc/certificate/_archive/kVlb4z/*.pem
	sudo chmod u=r -R /usr/local/etc/certificate/LogCenter/pkg-LogCenter/*.pem
	sudo chmod u=r -R /usr/local/etc/certificate/ScsiTarget/pkg-scsi-plugin-server/*.pem
	sudo chmod u=r -R /usr/local/etc/certificate/SynologyDrive/SynologyDrive/*.pem
	rm -rf /tmp/certs/
	sudo reboot
fi

Partea buna la Syno e ca folosește certificatele exact cu numele de la LE, deci nu mai trebuie redenumite. Partea proasta e ca trebuie împrăștiate prin sistem. În principiu /usr/syno/etc/certificate/_archive este calea comuna pentru toate Syno, apoi avem un folder cu un ID generat unde sunt puse efectiv certificatele. Partea de web (nginx) citește din calea aia cu ID certificatul SSL. Restul serviciilor, nu chiar, din câte vedeți. Aș fi putut sa fac symlink către certificatele din folderul _archive, dar mă gândesc ca poate o sa fie rescrise de către DSM la un moment dat, plus ca nu mă deranjează sa copiez certificatele “automat” în restul de foldere.

La final am ales sa dau reboot din mai multe motive. Nu știu toate serviciile ce necesita SSL și care trebuie sa fie restartate după schimbarea certificatului, plus ca sigur o sa rămână vreunul cu certificatul vechi. Dacă vrea cineva să-și bată capul, comanda de restart este synosystemctl restart pkgctl-Synology<MUMU>.service pe DSM 7, sau ceva de genul.

O alta chestie mai cu mot la Syno este faptul ca nu folosește comanda mail cam ca toate sistemele Linux, ci ssmtp. Mă rog, nu e un deal-braker, dar nah, a trebuit sa caut care era problema lui când nu găseam comanda mail, mai ales ca nici în Entware nu exista pachetul.

Dacă interesează pe cineva restul de scripturi o sa le postez, dar probabil no one cares.

Ah, am uitat partea cea mai importanta: cum funcționează de fapt scriptul.

  1. Se setează niște variabile care verifica timpul în Unix Time (timpul actual și cel de expirare al certificatului)
  2. Dacă timpul de acum e mai mare decât timpul de expirare al certificatului, atunci “fa chestii”
  3. ???
  4. Profit.

Încă o chestie, scriptul trebuie pus în cron, sa ruleze din minut în minut.

Q&A:
Se putea face altfel scriptul sau se putea scrie mai frumos? Probabil ca da.
Merge? Merge.
Are sens să-mi bat capul să-l modific? Nope. Dacă merge, atunci care e problema?

Referințe:

1. https://gist.github.com/catchdave/69854624a21ac75194706ec20ca61327
2. https://markvanlent.dev/2020/10/02/replacing-the-tls-certificate-on-a-synology-nas-via-the-command-line/
3. https://dokuwiki.bitaranto.ch/doku.php?id=synologyimportcertfrompfsense