Caddy, HSTS a security.txt
Modul 7: Doména, webový server a https · Doba čtení: 12 min.
Cíl lekce: Po této lekci budete umět používat Caddy jako jednoduchý webový server s automatickým https, nastavit HSTS a nejdůležitější bezpečnostní hlavičky (v Caddy i nginx), aniž by se Váš web stal nedostupným, a zveřejnit platný soubor security.txt.
Klíčové pojmy: Caddy, Caddyfile, automatické https, reverse_proxy, file_server, header, HSTS (Strict-Transport-Security), max-age, includeSubDomains, preload, X-Content-Type-Options, frame-ancestors, Referrer-Policy, security.txt, Contact, Expires, /.well-known/
Caddy: https bez starostí
V lekci 7.2 a 7.3 jste pomocí nginx a certbotu postavili web s https. To jsou dva programy, několik souborů a časovač. Caddy to zvládne sám: je to webový server s vestavěným klientem ACME. Pokud je v konfiguraci uvedeno jméno, které ukazuje na server, a porty 80 a 443 jsou dostupné, Caddy si sám získá certifikát, včas ho obnoví a přesměruje http na https.
Caddy je v repozitáři balíčků Debianu i Ubuntu (v trochu starší verzi); autoři nabízejí také vlastní zdroj apt s nejnovější verzí, s vlastním klíčem a Signed-By jako v lekci 4.1. V modulu 9 poběží Caddy jako kontejner pro Vaše služby v Dockeru (lekce 9.4). Zde ho použijete jako běžnou službu.
anna@web1:~$ sudo apt install caddy
anna@web1:~$ systemctl status caddyNa portech 80 a 443 používejte buď nginx, nebo Caddy, ne oba současně: na jednom portu může naslouchat jen jeden program.
Soubor Caddyfile
Konfigurace je uložena v /etc/caddy/Caddyfile. Statický web a aplikace za reverzní proxy:
example.com, www.example.com {
root * /var/www/example.com
file_server
encode zstd gzip
}
app.example.com {
reverse_proxy 127.0.0.1:3000
}To je vše. Caddy sám naslouchá na IPv4 i IPv6, požádá o certifikáty pro všechna tři jména, přesměruje http na https a u reverse_proxy automaticky předává hlavičky X-Forwarded-For a X-Forwarded-Proto (což jste v nginx dělali ručně, lekce 7.2).
Test a opětovné načtení probíhá stejně jako u nginx:
anna@web1:~$ caddy validate --config /etc/caddy/Caddyfile
Valid configuration
anna@web1:~$ sudo systemctl reload caddy
anna@web1:~$ sudo journalctl -u caddy -fV journalu uvidíte získávání certifikátů. Pokud se něco nepovede, najdete tam důvod: obvykle stejný jako u certbotu (port 80 je zavřený, jméno ukazuje jinam, nefunkční IPv6; lekce 7.3).
HSTS: ať si prohlížeč pamatuje, že jde o https
Přesměrování z http na https má jedno slabé místo: úplně první požadavek přes http jde ještě nešifrovaně. Někdo ve stejné síti ho může zachytit a udržet návštěvníka na http. HSTS (HTTP Strict Transport Security, RFC 6797) tento problém řeší. Váš web posílá přes https tuto hlavičku:
Strict-Transport-Security: max-age=31536000Prohlížeč si pak po dobu jednoho roku (31.536.000 sekund) pamatuje, že toto jméno smí používat jen přes https. Když návštěvník později napíše http://, prohlížeč z toho sám udělá https ještě předtím, než cokoli odejde do sítě. Hlavičku HSTS, která přijde přes http, prohlížeč ignoruje; platí jen přes https.
Má to i stinnou stránku. Pokud si prohlížeč HSTS zapamatoval a narazí na chybu certifikátu (vypršel, nesprávné jméno), návštěvník nedostane tlačítko, kterým by mohl přesto pokračovat. Váš web je pak pro tyto návštěvníky nedostupný, dokud nebude certifikát v pořádku. Proto:
- HSTS zapněte až ve chvíli, kdy https funguje všude a obnova probíhá automaticky (lekce 7.3).
- Začněte s krátkou hodnotou
max-age, například jeden den (86400), a postupně ji zvyšujte až na jeden rok. - Buďte opatrní s
includeSubDomains: platí pro každou subdoménu, i pro starou subdoménu se zařízením nebo službou bez platného certifikátu. preloadžádá o zařazení do seznamu, který je zabudovaný přímo v prohlížečích (hstspreload.org). K tomu se mimo jiné vyžadujemax-agealespoň jeden rok,includeSubDomainsa https na všech subdoménách. Odstranění ze seznamu trvá měsíce. Udělejte to jen tehdy, když víte jistě, že celá doména bude navždy na https.
Další bezpečnostní hlavičky
Kromě HSTS existuje několik hlaviček, které s malým úsilím hodně pomohou:
| Hlavička | Proti čemu | Hodnota na začátek |
|---|---|---|
X-Content-Type-Options | prohlížeč začne hádat, o jaký soubor jde, takže nahraný "obrázek" se může spustit jako skript | nosniff |
Content-Security-Policy: frame-ancestors (nebo starší X-Frame-Options) | clickjacking: jiný web neviditelně načte Vaši stránku do rámce | frame-ancestors 'self' (nebo X-Frame-Options: SAMEORIGIN) |
Referrer-Policy | adresa Vaší stránky (s hledanými výrazy nebo čísly objednávek) uniká na jiné weby | strict-origin-when-cross-origin |
Úplná Content-Security-Policy (které skripty a styly se smějí načítat) se nastavuje na míru pro každý web a přesahuje rámec tohoto kurzu; začněte jen s frame-ancestors.
V Caddy je nastavíte direktivou header v bloku daného webu:
example.com, www.example.com {
root * /var/www/example.com
file_server
header {
Strict-Transport-Security "max-age=31536000"
X-Content-Type-Options "nosniff"
Content-Security-Policy "frame-ancestors 'self'"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
}Caddy HSTS ani tyto hlavičky sám nenastavuje; musíte je tam tedy opravdu doplnit. -Server odstraní hlavičku Server. V lekci 9.4 přidáte do stejného typu bloku vlastní hlavičku X-Weboke-Cursus pro úkol.
V nginx vložíte stejná pravidla do bloku server pro port 443:
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Content-Security-Policy "frame-ancestors 'self'" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;always zajistí, že se posílají i u chybových stránek. Pozor na známou past v nginx: pokud v bloku location stojí byť jen jedno vlastní add_header, pravidla add_header z bloku server pro tuto location už neplatí. Proto výsledek vždy zkontrolujte:
anna@laptop:~$ curl -sI https://example.com | grep -iE 'strict|nosniff|frame|referrer'
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
content-security-policy: frame-ancestors 'self'
referrer-policy: strict-origin-when-cross-originsecurity.txt: jak Vám někdo může nahlásit zranitelnost
Představte si, že někdo na Vašem serveru najde bezpečnostní díru, například otevřenou složku nebo zastaralou službu. Jak má ten člověk vědět, koho upozornit? K tomu slouží security.txt (RFC 9116): malý textový soubor na pevně daném místě, https://<jouwdomein>/.well-known/security.txt.
Contact: mailto:security@example.com
Expires: 2027-10-31T23:00:00Z
Preferred-Languages: nl, en
Canonical: https://example.com/.well-known/security.txtPravidla:
Contactje povinné: adresamailto:,https://nebotel:, kam hlášení dorazí. Použijte adresu, kterou někdo opravdu čte.Expiresje povinné a smí se vyskytnout jen jednou: datum, po kterém se soubor považuje za zastaralý. RFC doporučuje datum do jednoho roku. Díky tomu nezůstane viset soubor s dávno zapomenutou adresou. Zapište si do kalendáře, kdy ho musíte prodloužit.Preferred-Languages,CanonicalaPolicy(odkaz na Vaše zásady pro hlášení) jsou volitelné.- Soubor musí být dostupný přes https jako prostý text (
text/plain, UTF-8). Staré umístění/security.txtmůžete použít navíc, ale/.well-known/má přednost.
Umístění u statického webu:
anna@web1:~$ sudo mkdir -p /var/www/example.com/.well-known
anna@web1:~$ sudoedit /var/www/example.com/.well-known/security.txt
anna@laptop:~$ curl -sI https://example.com/.well-known/security.txt | grep -i content-type
content-type: text/plain; charset=utf-8Pokud v nginx používáte záchytné pravidlo location ~ /\. { deny all; } z lekce 7.2, vložte před něj výjimku: location ^~ /.well-known/ { }. U aplikace za reverzní proxy můžete v Caddy nechat cestu /.well-known/security.txt ukazovat na soubor pomocí bloku handle a file_server.
Častá chyba: web nebo aplikace, která na každou neznámou cestu odpoví úvodní stránkou se stavem 200. Pak security.txt sice "existuje", ale je to HTML. Kontrolujte proto i obsah.
Na AlmaLinux a Rocky Linux
Caddy tam získáte ze zdroje autorů nebo z EPEL/COPR. Stejně jako u nginx musí SELinux povolit reverzní proxy (setsebool -P httpd_can_network_connect 1). Caddyfile i hlavičky jsou stejné.
Shrnutí
- Caddy sám zajišťuje certifikáty, jejich obnovu a přesměrování na https;
reverse_proxyautomaticky předává správné hlavičky. - HSTS nechá prohlížeče zapamatovat si, že Váš web běží jen na https;
max-agezvyšujte postupně, buďte opatrní sincludeSubDomainsa velmi opatrní spreload. - Nastavte navíc
X-Content-Type-Options: nosniff,frame-ancestors 'self'aReferrer-Policy; v Caddy pomocíheader, v nginx pomocíadd_header ... always, a kontrolujte pomocícurl -I. - security.txt leží na
/.well-known/security.txt, přes https, jako prostý text, s povinnýmContacta jednímExpiresdo jednoho roku.
Kvíz
Úkol
Úkol Z7.4: HSTS, hlavičky a security.txt. Nastavte pro svůj web HSTS (alespoň 180 dní, až https nějakou dobu spolehlivě funguje), X-Content-Type-Options: nosniff a frame-ancestors 'self' (nebo X-Frame-Options) a zveřejněte security.txt s Contact a Expires do jednoho roku. Vyplňte název svého hostitele. Program stáhne https://<hostnaam>/ a zkontroluje hlavičky, dále stáhne https://<hostnaam>/.well-known/security.txt a zkontroluje pole. Neukládá nic kromě výsledku a data Expires.
Doporučujeme k přečtení
- HSTS a bezpečnostní hlavičky pro Váš web
- Caddy, Automatic HTTPS: https://caddyserver.com/docs/automatic-https
- Caddy, direktiva header: https://caddyserver.com/docs/caddyfile/directives/header
- RFC 6797, HTTP Strict Transport Security: https://www.rfc-editor.org/rfc/rfc6797.html
- Seznam HSTS preload a jeho požadavky: https://hstspreload.org/
- RFC 9116, security.txt: https://www.rfc-editor.org/rfc/rfc9116.html
- securitytxt.org (vytvoření a kontrola): https://securitytxt.org/
