Moduuli 7 · 7.4
Caddy, HSTS ja security.txt
Moduuli 7: Verkkotunnus, verkkopalvelin ja https · Lukuaika: 12 minuuttia
Tavoite: Tämän oppitunnin jälkeen osaat käyttää Caddya helppona verkkopalvelimena, jossa on automaattinen https, ottaa käyttöön HSTS:n ja tärkeimmät suojausotsakkeet (Caddyssa ja nginxissä) ilman, että sivustosi lakkaa näkymästä, ja julkaista kelvollisen security.txt-tiedoston.
Keskeiset käsitteet: Caddy, Caddyfile, automaattinen 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 ilman huolia
Oppitunneilla 7.2 ja 7.3 rakensit nginxillä ja certbotilla sivuston, jossa on https. Siihen tarvittiin kaksi ohjelmaa, muutama tiedosto ja ajastin. Caddy hoitaa kaiken yhdellä ohjelmalla: se on verkkopalvelin, jossa on sisäänrakennettu ACME-asiakas. Kun nimi on määrityksissä, nimi osoittaa palvelimeen ja portit 80 ja 443 ovat avoinna, Caddy hakee varmenteen itse, uusii sen ajoissa ja ohjaa http-liikenteen https:ään.
Caddy löytyy Debianin ja Ubuntun pakettilähteestä (hieman vanhempana versiona). Tekijät tarjoavat myös oman apt-lähteen, jossa on uusin versio, omalla avaimellaan ja Signed-By-määrityksellä kuten oppitunnilla 4.1. Moduulissa 9 Caddy toimii konttina Docker-palveluidesi edessä (oppitunti 9.4). Tässä käytät sitä tavallisena palveluna.
anna@web1:~$ sudo apt install caddy
anna@web1:~$ systemctl status caddyKäytä porteissa 80 ja 443 joko nginxiä tai Caddya, älä molempia: vain yksi ohjelma voi kuunnella samaa porttia.
Caddyfile
Määritykset ovat tiedostossa /etc/caddy/Caddyfile. Staattinen sivusto ja sovellus käänteisen välityspalvelimen takana:
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
}Siinä kaikki. Caddy kuuntelee itsestään sekä IPv4:ää että IPv6:ta, hakee varmenteet kolmelle nimelle, ohjaa http:n https:ään ja välittää reverse_proxy-määrityksessä otsakkeet X-Forwarded-For ja X-Forwarded-Proto automaattisesti (nginxissä teit tämän käsin, oppitunti 7.2).
Testaus ja uudelleenlataus toimivat kuten nginxissä:
anna@web1:~$ caddy validate --config /etc/caddy/Caddyfile
Valid configuration
anna@web1:~$ sudo systemctl reload caddy
anna@web1:~$ sudo journalctl -u caddy -fJournalista näet varmenteiden haun. Jos jokin menee pieleen, syy näkyy siellä: yleensä sama kuin certbotissa (portti 80 kiinni, nimi osoittaa muualle tai IPv6 ei toimi; oppitunti 7.3).
HSTS: selain muistaa, että sivusto on https
Ohjauksessa http:stä https:ään on yksi heikko kohta: aivan ensimmäinen pyyntö kulkee vielä salaamattomana http:n kautta. Samassa verkossa oleva voi siepata sen ja pitää kävijän http:ssä. HSTS (HTTP Strict Transport Security, RFC 6797) ratkaisee tämän. Sivustosi lähettää https:n kautta tämän otsakkeen:
Strict-Transport-Security: max-age=31536000Selain muistaa silloin vuoden ajan (31.536.000 sekuntia), että tähän nimeen saa yhdistää vain https:llä. Jos kävijä myöhemmin kirjoittaa http://, selain muuttaa sen itse https:ksi jo ennen kuin mitään lähtee verkkoon. Selain ei välitä http:n kautta tulevasta HSTS-otsakkeesta; se huomioidaan vain https:n kautta.
Asialla on kääntöpuolensa. Jos selain on tallentanut HSTS:n ja näkee varmennevirheen (vanhentunut, väärä nimi), kävijä ei saa painiketta, jolla jatkaa silti. Sivustosi on silloin näille kävijöille saavuttamaton, kunnes varmenne on kunnossa. Siksi:
- Ota HSTS käyttöön vasta, kun https toimii kaikkialla ja uusiminen on automaattista (oppitunti 7.3).
- Aloita lyhyellä
max-age-arvolla, esimerkiksi yhdellä päivällä (86400), ja nosta sitä vaiheittain vuoteen. - Ole varovainen
includeSubDomains-asetuksen kanssa: se koskee jokaista aliverkkotunnusta, myös vanhaa aliverkkotunnusta, jossa on laite tai palvelu ilman kelvollista varmennetta. preloadpyytää pääsyä selaimiin sisäänrakennetulle listalle (hstspreload.org). Sitä varten vaaditaan muun muassa vähintään vuodenmax-age,includeSubDomainsja https kaikissa aliverkkotunnuksissa. Listalta poistuminen kestää kuukausia. Tee tämä vain, jos olet varma, että koko verkkotunnus on pysyvästi https.
Muut suojausotsakkeet
HSTS:n lisäksi on muutama otsake, jotka auttavat paljon pienellä vaivalla:
| Otsake | Mitä vastaan | Aloitusarvo |
|---|---|---|
X-Content-Type-Options | selain arvaa, millainen tiedosto on, jolloin ladattu "kuva" voi suoritua skriptinä | nosniff |
Content-Security-Policy: frame-ancestors (tai vanhempi X-Frame-Options) | clickjacking: toinen sivusto lataa sivusi näkymättömänä kehykseen | frame-ancestors 'self' (tai X-Frame-Options: SAMEORIGIN) |
Referrer-Policy | sivusi osoite (hakusanoineen tai tilausnumeroineen) vuotaa muille sivustoille | strict-origin-when-cross-origin |
Täydellinen Content-Security-Policy (mitkä skriptit ja tyylit saa ladata) räätälöidään sivustokohtaisesti eikä kuulu tähän kurssiin; aloita pelkällä frame-ancestors-määrityksellä.
Caddyssa asetat ne header-direktiivillä sivuston lohkossa:
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 ei aseta HSTS:ää eikä näitä otsakkeita itse, joten ne pitää todella lisätä. -Server poistaa otsakkeen Server. Oppitunnilla 9.4 lisäät samanlaiseen lohkoon oman otsakkeesi X-Weboke-Cursus tehtävää varten.
nginxissä lisäät samat rivit portin 443 server-lohkoon:
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 varmistaa, että ne lähetetään myös virhesivujen mukana. Huomaa nginxin tunnettu sudenkuoppa: jos location-lohkossa on itsessään yksikin add_header, server-lohkon add_header-rivit eivät enää koske kyseistä locationia. Tarkista siksi aina lopputulos:
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: näin sinulle voi ilmoittaa haavoittuvuudesta
Oletetaan, että joku löytää palvelimeltasi haavoittuvuuden, kuten avoimen hakemiston tai vanhentuneen palvelun. Mistä hän tietää, ketä varoittaa? Sitä varten on security.txt (RFC 9116): pieni tekstitiedosto vakiopaikassa, 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.txtSäännöt:
Contacton pakollinen:mailto:-,https://- taitel:-osoite, johon ilmoitukset tulevat. Käytä osoitetta, jota joku oikeasti lukee.Expireson pakollinen ja saa esiintyä vain kerran: päivämäärä, jonka jälkeen tiedostoa pidetään vanhentuneena. RFC suosittelee päivämäärää vuoden sisällä. Näin ei jää voimaan tiedostoa, jossa on kauan sitten unohdettu osoite. Merkitse kalenteriisi, milloin se pitää uusia.Preferred-Languages,CanonicaljaPolicy(linkki ilmoituskäytäntöösi) ovat valinnaisia.- Tiedoston on tultava https:n kautta pelkkänä tekstinä (
text/plain, UTF-8). Vanha sijainti/security.txton sallittu lisänä, mutta/.well-known/menee edelle.
Tiedoston lisääminen staattiselle sivustolle:
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-8Jos käytät nginxissä oppitunnin 7.2 turvaverkkoa location ~ /\. { deny all; }, lisää sen eteen poikkeus: location ^~ /.well-known/ { }. Käänteisen välityspalvelimen takana olevalle sovellukselle voit Caddyssa ohjata polun /.well-known/security.txt tiedostoon handle-lohkolla ja file_server-määrityksellä.
Yleinen virhe: sivusto tai sovellus vastaa jokaiseen tuntemattomaan polkuun etusivulla ja tilakoodilla 200. Silloin security.txt "on olemassa", mutta se on HTML:ää. Tarkista siis myös sisältö.
AlmaLinuxissa ja Rocky Linuxissa
Caddy asennetaan niissä tekijöiden lähteestä tai EPEL/COPR-lähteestä. Kuten nginxissä, SELinuxin on sallittava käänteinen välityspalvelin (setsebool -P httpd_can_network_connect 1). Caddyfile ja otsakkeet ovat samat.
Yhteenveto
- Caddy hoitaa varmenteet, uusimisen ja ohjauksen https:ään itse;
reverse_proxyvälittää oikeat otsakkeet automaattisesti. - HSTS saa selaimet muistamaan, että sivustosi on vain https; kasvata
max-age-arvoa vähitellen, ole varovainenincludeSubDomains-asetuksen kanssa ja hyvin varovainenpreload-asetuksen kanssa. - Aseta lisäksi
X-Content-Type-Options: nosniff,frame-ancestors 'self'jaReferrer-Policy; Caddyssaheader-direktiivillä, nginxissäadd_header ... always-rivillä, ja tarkista komennollacurl -I. - security.txt on osoitteessa
/.well-known/security.txt, https:n kautta, pelkkänä tekstinä, ja siinä on pakollinenContactja yksiExpiresvuoden sisällä.
Tietovisa (quiz)
Tehtävä
Tehtävä Z7.4: HSTS, otsakkeet ja security.txt. Ota sivustollesi käyttöön HSTS (vähintään 180 päivää, kun https on toiminut hyvin jonkin aikaa), X-Content-Type-Options: nosniff ja frame-ancestors 'self' (tai X-Frame-Options), ja julkaise security.txt, jossa on Contact ja Expires vuoden sisällä. Syötä palvelimesi nimi. Ohjelma hakee osoitteen https://<hostnaam>/ ja tarkistaa otsakkeet sekä hakee osoitteen https://<hostnaam>/.well-known/security.txt ja tarkistaa kentät. Se ei tallenna mitään muuta kuin tuloksen ja Expires-päivämäärän.
Lue lisää
- HSTS ja suojausotsikot verkkosivustollesi
- Caddy, Automatic HTTPS: https://caddyserver.com/docs/automatic-https
- Caddy, header-direktiivi: https://caddyserver.com/docs/caddyfile/directives/header
- RFC 6797, HTTP Strict Transport Security: https://www.rfc-editor.org/rfc/rfc6797.html
- HSTS-preload-lista ja sen vaatimukset: https://hstspreload.org/
- RFC 9116, security.txt: https://www.rfc-editor.org/rfc/rfc9116.html
- securitytxt.org (luonti ja tarkistus): https://securitytxt.org/
