Mailserver mx.studio60.cz
⚠️ NEZAMĚŇOVAT s
s60-mail.s60-mailje kontejner (NestJS + BullMQ, port 3010) běžící na hubu a produkci, který odesílá transakční maily přes Resend. Tohle je samostatný stroj — plnohodnotný mailserver pro firemní poštu. Vizservices/mail/INDEX.mdpro tu druhou věc.
| Owner stroje | infra |
| Owner monitoringu | sentinel (rozhodl Libor 2026-08-26) |
| Stack | mailcow 2026-07b, 18 kontejnerů, Hetzner CX33 |
| Veřejná IP | 178.104.15.77 ⚠️ (dřív cortex — viz níž) |
| Tailscale | 100.121.32.32, tag:postmaster, DNS postmaster (HostName stroje je mail) |
| Compose | /opt/mailcow-dockerized |
| Runbook (infra) | s60-infra/docs/runbooks/mailcow-mailserver.md |
🔴 Kritičnost: HIGH
Od 2026-08-25 tudy chodí příchozí pošta domén aetv.cz, alteredu.cz
a byznys-partak.cz (MX 10 mx.studio60.cz, ověřeno reálnou poštou:
spf/dkim/dmarc pass). Výpadek není jen nedostupný webmail — odesílatelé
opakují doručení běžně 24–72 h a pak zprávu vzdají, takže delší výpadek
znamená skutečně ztracenou poštu, ne odloženou. Alerty eskalovat i v noci.
Odesílání jde přes Amazon SES relay (Hetzner blokuje odchozí 25 i 465), příjem je vlastní MX.
Monitoring (sentinel)
scripts/monitoring/mail-monitor.py — cron */10, SSH read-only ze
sentinelu, Telegram + denní mail digest, cooldown 30 min.
| kontrola | práh | proč |
|---|---|---|
| postfix fronta | >20 zpráv, nebo cokoli starší 60 min | nejdůležitější — „běží, ale nedoručuje" |
| relay chyby na SES | jakýkoli deferred/bounced/SASL za 15 min |
SASL = neplatné SES credentials |
| počet kontejnerů | ≠ 18 | po zkušební obnově zůstal watchdog-mailcow Exited a nic to nenahlásilo |
| stáří zálohy | >26 h od posledního hotovo: |
cron 02:30 denně |
| Storage Box | reálný zápis, ne jen mountpoint |
sshfs umí viset připojený a nezapisovat |
| disk | ≥80 % | vmail poroste s migrací z Gmailu |
Kuma monitory (95–98): TCP :25, :587, :993 přes Tailscale IP
+ HTTP webmail.studio60.cz s hlídáním expirace certifikátu.
Proč porty přes Tailscale a ne přes veřejnou IP
mailcow netfilter při opakovaných neúspěšných přihlášeních zahodí z dané IP
úplně všechno — včetně HTTPS a ICMP. Vypadá to přesně jako výpadek stroje
a v nginx logu po oběti nezůstane stopa. Tailnet (100.64.0.0/10) je
ve whitelistu, takže sondy odtud jsou v bezpečí.
Kontrola banu (API na aktivní bany neodpovídá, vrací konfiguraci):
⚠️ Past: health check přes API nefunguje
GET /api/v1/get/domain/all vrací bez API klíče HTTP 200 s prázdným tělem
(ověřeno 2026-08-26). Jako health check je tedy bezcenný — hlídal by kód,
který o zdraví služby nevypovídá. V monitoringu se schválně nepoužívá.
Pozn.: volání na 127.0.0.1 z hosta Docker přepíše na gateway bridge
(172.22.1.1) a API ho odmítne — volat přes Tailscale IP i lokálně:
--resolve mx.studio60.cz:443:100.121.32.32.
⚠️ Veřejná IP byla dřív cortex
178.104.15.77 patřila zaniklému cortexu. Po jeho vyřazení ji Hetzner
přiřadil tomuhle stroji, čímž se na něj tiše přenesly přístupy cortexu —
pg_hba na všechny databáze, UFW 5432/6432 na pg-alfě, hub UFW 443.
Odstraněno 2026-08-26. Viz [[feedback_ip_reuse_stale_allowlists]].
Zatím nehlídáno
Prahy účtu SES (sesv2.get_account(): SendQuota, EnforcementStatus,
ProductionAccessEnabled). Credentials jsou na cerebru
(/root/secrets/aws-ses.env, správcovský klíč s explicitním DENY na odesílání).
SES shodí účet bez varování při bounce rate ≥ 4 % nebo complaint ≥ 0,08 %;
při objemu jednotek mailů měsíčně stačí pár odražených zpráv. K doplnění.