Modulul 7 · 7.4
Caddy, HSTS și security.txt
Modulul 7: Domeniu, server web și https · Timp de citire: 12 minute
Obiectivul lecției: După această lecție veți putea folosi Caddy ca server web simplu cu https automat, veți putea seta HSTS și cele mai importante antete de securitate (în Caddy și nginx) fără ca site-ul dumneavoastră să devină inaccesibil și veți putea publica un security.txt valid.
Noțiuni cheie: Caddy, Caddyfile, https automat, 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 fără grijă
În lecțiile 7.2 și 7.3 ați construit cu nginx și certbot un site cu https. Asta înseamnă două programe, câteva fișiere și un timer. Caddy le face pe toate într-unul singur: este un server web cu un client ACME integrat. Dacă un nume apare în configurație, indică spre server, iar porturile 80 și 443 sunt accesibile, Caddy obține singur un certificat, îl reînnoiește la timp și redirecționează http către https.
Caddy se află în sursa de pachete a Debian și Ubuntu (o versiune ceva mai veche); dezvoltatorii oferă și o sursă apt proprie cu cea mai nouă versiune, cu o cheie proprie și Signed-By, ca în lecția 4.1. În modulul 9, Caddy rulează ca container pentru serviciile dumneavoastră Docker (lecția 9.4). Aici îl folosiți ca serviciu obișnuit.
anna@web1:~$ sudo apt install caddy
anna@web1:~$ systemctl status caddyFolosiți fie nginx, fie Caddy pe porturile 80 și 443, nu pe amândouă: un singur program poate asculta pe un port.
Fișierul Caddyfile
Configurația se află în /etc/caddy/Caddyfile. Un site static și o aplicație în spatele unui reverse 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
}Asta este tot. Caddy ascultă automat pe IPv4 și IPv6, solicită certificate pentru cele trei nume, redirecționează http către https și, la reverse_proxy, transmite automat antetele X-Forwarded-For și X-Forwarded-Proto (ceea ce în nginx ați făcut manual, lecția 7.2).
Testarea și reîncărcarea se fac la fel ca la nginx:
anna@web1:~$ caddy validate --config /etc/caddy/Caddyfile
Valid configuration
anna@web1:~$ sudo systemctl reload caddy
anna@web1:~$ sudo journalctl -u caddy -fÎn jurnal vedeți obținerea certificatelor. Dacă ceva nu merge, motivul apare acolo: de obicei același ca la certbot (portul 80 închis, numele indică altundeva, IPv6 defect; lecția 7.3).
HSTS: browserul ține minte că este https
Redirecționarea de la http la https are un singur moment slab: prima cerere prin http pleacă încă necriptată. Cineva din aceeași rețea o poate intercepta și îl poate ține pe vizitator pe http. HSTS (HTTP Strict Transport Security, RFC 6797) rezolvă această problemă. Site-ul dumneavoastră trimite prin https acest antet:
Strict-Transport-Security: max-age=31536000Browserul ține apoi minte timp de un an (31.536.000 de secunde) că acest nume poate fi accesat doar prin https. Dacă vizitatorul tastează mai târziu http://, browserul îl transformă singur în https, înainte ca ceva să treacă prin rețea. Un antet HSTS primit prin http este ignorat de browser; contează doar prin https.
Există și un dezavantaj. Dacă un browser a memorat HSTS și întâlnește o eroare de certificat (expirat, nume greșit), vizitatorul nu primește niciun buton pentru a continua totuși. Site-ul dumneavoastră devine atunci inaccesibil pentru acești vizitatori până când certificatul este corect. De aceea:
- Activați HSTS doar când https funcționează peste tot și reînnoirea se face automat (lecția 7.3).
- Începeți cu un
max-agescurt, de exemplu o zi (86400), și creșteți treptat până la un an. - Fiți atent cu
includeSubDomains: se aplică fiecărui subdomeniu, inclusiv unui subdomeniu vechi cu un dispozitiv sau un serviciu fără certificat valid. preloadsolicită includerea într-o listă integrată în browsere (hstspreload.org). Pentru aceasta se cer, printre altele, unmax-agede cel puțin un an,includeSubDomainsși https pe toate subdomeniile. Eliminarea din listă durează luni de zile. Faceți acest pas doar dacă sunteți sigur că întregul domeniu va folosi https definitiv.
Celelalte antete de securitate
Pe lângă HSTS există câteva antete care ajută mult cu efort mic:
| Antet | Împotriva a ce | Valoare de pornire |
|---|---|---|
X-Content-Type-Options | browserul ghicește ce tip are un fișier, astfel încât o „imagine” încărcată poate rula ca script | nosniff |
Content-Security-Policy: frame-ancestors (sau mai vechiul X-Frame-Options) | clickjacking: un alt site vă încarcă pagina invizibil într-un frame | frame-ancestors 'self' (sau X-Frame-Options: SAMEORIGIN) |
Referrer-Policy | adresa paginii dumneavoastră (cu termeni de căutare sau numere de comandă) ajunge la alte site-uri | strict-origin-when-cross-origin |
Un Content-Security-Policy complet (ce scripturi și stiluri au voie să se încarce) se configurează individual pentru fiecare site și depășește cadrul acestui curs; începeți doar cu frame-ancestors.
În Caddy le setați cu directiva header în blocul unui site:
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 nu setează singur HSTS și aceste antete; trebuie deci să le adăugați efectiv. -Server elimină antetul Server. În lecția 9.4 veți seta în același tip de bloc propriul antet X-Weboke-Cursus pentru exercițiu.
În nginx puneți aceleași linii în blocul server pentru portul 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 face ca ele să fie trimise și la paginile de eroare. Atenție la o capcană cunoscută a nginx: dacă un bloc location conține el însuși un add_header, liniile add_header din blocul server nu mai sunt valabile pentru acel location. De aceea, verificați întotdeauna rezultatul:
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: așa vă poate raporta cineva o vulnerabilitate
Să presupunem că cineva găsește o vulnerabilitate pe serverul dumneavoastră, cum ar fi un director deschis sau un serviciu învechit. Cum află acea persoană pe cine trebuie să avertizeze? Pentru asta există security.txt (RFC 9116): un mic fișier text într-un loc fix, 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.txtRegulile:
Contacteste obligatoriu: o adresămailto:,https://sautel:la care ajung raportările. Folosiți o adresă pe care cineva o citește cu adevărat.Expireseste obligatoriu și poate apărea o singură dată: data după care fișierul este considerat învechit. RFC-ul recomandă o dată în decurs de un an. Astfel nu rămâne publicat un fișier cu o adresă de mult uitată. Notați-vă în agendă când trebuie să îl prelungiți.Preferred-Languages,CanonicalșiPolicy(un link către politica dumneavoastră privind raportările) sunt opționale.- Fișierul trebuie livrat prin https, ca text simplu (
text/plain, UTF-8). Vechea locație/security.txteste permisă în plus, dar/.well-known/are prioritate.
Plasarea fișierului la un site static:
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-8Dacă în nginx folosiți regula de siguranță location ~ /\. { deny all; } din lecția 7.2, puneți înaintea ei o excepție: location ^~ /.well-known/ { }. Pentru o aplicație în spatele unui reverse proxy, puteți face în Caddy ca ruta /.well-known/security.txt să indice spre un fișier, cu un bloc handle și file_server.
O greșeală frecventă: un site sau o aplicație care răspunde la orice cale necunoscută cu pagina principală și codul de stare 200. Atunci security.txt „există”, dar este HTML. Verificați deci și conținutul.
Pe AlmaLinux și Rocky Linux
Acolo, Caddy se instalează din sursa dezvoltatorilor sau din EPEL/COPR. Ca la nginx, SELinux trebuie să permită un reverse proxy (setsebool -P httpd_can_network_connect 1). Fișierul Caddyfile și antetele sunt aceleași.
Rezumat
- Caddy se ocupă singur de certificate, reînnoire și redirecționarea către https;
reverse_proxytransmite automat antetele corecte. - HSTS face ca browserele să rețină că site-ul dumneavoastră folosește doar https; creșteți treptat
max-age, fiți atent cuincludeSubDomainsși foarte atent cupreload. - Setați în plus
X-Content-Type-Options: nosniff,frame-ancestors 'self'și unReferrer-Policy; în Caddy cuheader, în nginx cuadd_header ... always, și verificați cucurl -I. - security.txt se află la
/.well-known/security.txt, prin https, ca text simplu, cuContactobligatoriu și un singurExpiresîn decurs de un an.
Test (quiz)
Exercițiu
Exercițiul Z7.4: HSTS, antete și security.txt. Setați pentru site-ul dumneavoastră HSTS (cel puțin 180 de zile, după ce https a funcționat bine o perioadă), X-Content-Type-Options: nosniff și frame-ancestors 'self' (sau X-Frame-Options) și publicați un security.txt cu Contact și un Expires în decurs de un an. Introduceți numele de gazdă. Programul descarcă https://<hostnaam>/ și verifică antetele, apoi descarcă https://<hostnaam>/.well-known/security.txt și verifică câmpurile. Nu salvează nimic în afară de rezultat și data Expires.
Lecturi suplimentare
- HSTS și headere de securitate pentru site-ul dumneavoastră web
- Caddy, Automatic HTTPS: https://caddyserver.com/docs/automatic-https
- Caddy, directiva header: https://caddyserver.com/docs/caddyfile/directives/header
- RFC 6797, HTTP Strict Transport Security: https://www.rfc-editor.org/rfc/rfc6797.html
- Lista HSTS preload și cerințele: https://hstspreload.org/
- RFC 9116, security.txt: https://www.rfc-editor.org/rfc/rfc9116.html
- securitytxt.org (creare și verificare): https://securitytxt.org/
