Vai al contenuto

Impostazioni cookie

Scelga per ogni tipo quali cookie consente. Può modificare la sua scelta in qualsiasi momento tramite Impostazioni cookie in fondo a ogni pagina. Informativa sulla privacy

Necessari

Sempre attivi

Servono per accedere, conservare il carrello e ricordare le sue scelte. Sono sempre attivi.

Quali cookie?
  • weboke_sessie, weboke_klant, weboke_remember: la sua sessione e la permanenza dell'accesso
  • weboke_basket: il suo carrello
  • wkBtwIncl: visualizzazione dei prezzi con o senza IVA
  • wok_cookies: la sua scelta sui cookie, 12 mesi

Misurano quale annuncio porta a una visita o a un ordine, così non paghiamo annunci che non funzionano.

Quali cookie?
  • Google Ads tramite Google Tag Manager (_gcl_au, _gcl_aw), fino a 90 giorni
  • OpenAI Ads, annunci in ChatGPT
  • wok_aff: tramite quale partner è arrivato da noi (programma di affiliazione), 60 giorni

4,6

Paese e lingua

Ogni paese ha il suo sito, con i prezzi e l'IVA di quel paese.

Vedi

Caddy, HSTS e security.txt

Modulo 7: Dominio, server web e https · Tempo di lettura: 12 minuti

Obiettivo della lezione: Dopo questa lezione saprà usare Caddy come server web semplice con https automatico, impostare HSTS e i principali header di sicurezza (in Caddy e in nginx) senza rendere il Suo sito irraggiungibile, e pubblicare un security.txt valido.

Concetti chiave: Caddy, Caddyfile, https automatico, 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 senza pensieri

Nelle lezioni 7.2 e 7.3 ha creato con nginx e certbot un sito con https. Si tratta di due programmi, alcuni file e un timer. Caddy fa tutto in uno: è un server web con un client ACME integrato. Se un nome è presente nella configurazione, punta al server e le porte 80 e 443 sono raggiungibili, Caddy ottiene da solo un certificato, lo rinnova in tempo e reindirizza http verso https.

Caddy è presente nei repository dei pacchetti di Debian e Ubuntu (in una versione un po' più vecchia); gli sviluppatori offrono anche un proprio repository apt con la versione più recente, con una propria chiave e Signed-By come nella lezione 4.1. Nel modulo 9 Caddy viene eseguito come container per i Suoi servizi Docker (lezione 9.4). Qui lo usa come un normale servizio.

anna@web1:~$ sudo apt install caddy
anna@web1:~$ systemctl status caddy

Usi nginx oppure Caddy sulle porte 80 e 443, non entrambi: un solo programma alla volta può restare in ascolto su una porta.

Il Caddyfile

La configurazione si trova in /etc/caddy/Caddyfile. Un sito statico e un'applicazione dietro un 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
}

È tutto qui. Caddy resta in ascolto automaticamente su IPv4 e IPv6, richiede i certificati per i tre nomi, reindirizza http verso https e con reverse_proxy inoltra da solo gli header X-Forwarded-For e X-Forwarded-Proto (ciò che in nginx ha fatto a mano, lezione 7.2).

Il test e il ricaricamento funzionano come con nginx:

anna@web1:~$ caddy validate --config /etc/caddy/Caddyfile
Valid configuration
anna@web1:~$ sudo systemctl reload caddy
anna@web1:~$ sudo journalctl -u caddy -f

Nel journal vede il recupero dei certificati. Se qualcosa va storto, lì trova il motivo: di solito lo stesso che con certbot (porta 80 chiusa, nome che punta altrove, IPv6 non funzionante; lezione 7.3).

HSTS: far ricordare al browser che si tratta di https

Il reindirizzamento da http a https ha un punto debole: la primissima richiesta via http viaggia ancora non cifrata. Qualcuno sulla stessa rete può intercettarla e trattenere il visitatore su http. HSTS (HTTP Strict Transport Security, RFC 6797) risolve questo problema. Il Suo sito invia via https questo header:

Strict-Transport-Security: max-age=31536000

Il browser ricorda allora per un anno (31.536.000 secondi) che questo nome è accessibile solo via https. Se in seguito il visitatore digita http://, il browser lo trasforma da solo in https, ancora prima che qualcosa passi sulla rete. Un header HSTS ricevuto via http viene ignorato dal browser; vale solo via https.

C'è un rovescio della medaglia. Se un browser ha memorizzato HSTS e rileva un errore del certificato (scaduto, nome errato), il visitatore non ha alcun pulsante per procedere comunque. Il Suo sito resta quindi irraggiungibile per quei visitatori finché il certificato non è corretto. Per questo:

  1. Attivi HSTS solo quando https funziona ovunque e il rinnovo avviene automaticamente (lezione 7.3).
  2. Inizi con un max-age breve, per esempio un giorno (86400), e lo aumenti per gradi fino a un anno.
  3. Faccia attenzione con includeSubDomains: vale per ogni sottodominio, anche per un vecchio sottodominio con un dispositivo o un servizio senza certificato valido.
  4. preload chiede l'inserimento in un elenco integrato nei browser (hstspreload.org). Per questo si richiedono tra l'altro un max-age di almeno un anno, includeSubDomains e https su tutti i sottodomini. Uscire dall'elenco richiede mesi. Lo faccia solo se è certo che l'intero dominio resterà per sempre in https.

Gli altri header di sicurezza

Oltre a HSTS esistono alcuni header che con poco sforzo aiutano molto:

HeaderContro che cosaValore con cui iniziare
X-Content-Type-Optionsil browser cerca di indovinare il tipo di file, per cui un'"immagine" caricata può essere eseguita come scriptnosniff
Content-Security-Policy: frame-ancestors (o il più vecchio X-Frame-Options)clickjacking: un altro sito carica la Sua pagina in modo invisibile in un frameframe-ancestors 'self' (o X-Frame-Options: SAMEORIGIN)
Referrer-Policyl'indirizzo della Sua pagina (con termini di ricerca o numeri d'ordine) finisce ad altri sitistrict-origin-when-cross-origin

Un Content-Security-Policy completo (quali script e stili possono essere caricati) va costruito su misura per ogni sito ed esula da questo corso; inizi solo con frame-ancestors.

In Caddy li imposta con la direttiva header nel blocco di un sito:

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 non imposta da solo HSTS né questi header; deve quindi inserirli Lei. -Server rimuove l'header Server. Nella lezione 9.4 imposterà in un blocco dello stesso tipo un Suo header X-Weboke-Cursus per l'esercizio.

In nginx inserisce le stesse righe nel blocco server per la porta 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 fa sì che vengano inviati anche con le pagine di errore. Attenzione a un noto tranello di nginx: se in un blocco location compare anche un solo add_header, le righe add_header del blocco server non valgono più per quella location. Per questo verifichi sempre il risultato:

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-origin

security.txt: così qualcuno può segnalarLe una vulnerabilità

Supponga che qualcuno trovi una vulnerabilità sul Suo server, per esempio una cartella aperta o un servizio obsoleto. Come fa questa persona a sapere chi avvisare? Per questo esiste security.txt (RFC 9116): un piccolo file di testo in una posizione fissa, 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.txt

Le regole:

  • Contact è obbligatorio: un indirizzo mailto:, https:// o tel: a cui arrivano le segnalazioni. Usi un indirizzo che qualcuno legge davvero.
  • Expires è obbligatorio e può comparire una sola volta: la data dopo la quale il file è considerato obsoleto. La RFC consiglia una data entro un anno. In questo modo non resta online un file con un indirizzo dimenticato da tempo. Segni in agenda quando deve prolungarla.
  • Preferred-Languages, Canonical e Policy (un link alla Sua policy per le segnalazioni) sono facoltativi.
  • Il file deve essere servito via https, come testo semplice (text/plain, UTF-8). La vecchia posizione /security.txt è ammessa come aggiunta, ma /.well-known/ ha la precedenza.

Pubblicarlo per un sito statico:

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-8

Se in nginx usa la regola di riserva location ~ /\. { deny all; } della lezione 7.2, inserisca prima un'eccezione: location ^~ /.well-known/ { }. Per un'applicazione dietro un reverse proxy può far puntare in Caddy il percorso /.well-known/security.txt a un file con un blocco handle e file_server.

Un errore frequente: un sito o un'applicazione che risponde a ogni percorso sconosciuto con la home page e lo stato 200. In quel caso security.txt "esiste", ma è HTML. Verifichi quindi anche il contenuto.

Su AlmaLinux e Rocky Linux

Lì Caddy proviene dal repository degli sviluppatori oppure da EPEL/COPR. Come per nginx, SELinux deve consentire un reverse proxy (setsebool -P httpd_can_network_connect 1). Il Caddyfile e gli header sono gli stessi.

Riepilogo

  • Caddy gestisce da solo certificati, rinnovo e reindirizzamento verso https; reverse_proxy inoltra automaticamente gli header corretti.
  • HSTS fa ricordare ai browser che il Suo sito è solo https; aumenti max-age gradualmente, faccia attenzione con includeSubDomains e moltissima attenzione con preload.
  • Imposti inoltre X-Content-Type-Options: nosniff, frame-ancestors 'self' e un Referrer-Policy; in Caddy con header, in nginx con add_header ... always, e verifichi con curl -I.
  • security.txt si trova in /.well-known/security.txt, via https, come testo semplice, con Contact obbligatorio e un solo Expires entro un anno.

Quiz

1. Perché HSTS è utile, se già reindirizza http verso https?



2. Imposta HSTS con max-age=31536000; includeSubDomains. Una settimana dopo risulta che camera.example.com non ha un certificato valido. Che cosa notano i visitatori che hanno già visitato il Suo sito?



3. Quali campi sono obbligatori in un security.txt?



4. In nginx ha inserito gli header di sicurezza nel blocco server, ma per /api/ non vengono inviati. Nel blocco location /api/ c'è un add_header proprio. Che cosa succede?



5. Che cosa deve fare prima di aggiungere preload al Suo header HSTS?



Esercizio

Esercizio Z7.4: HSTS, header e security.txt. Imposti per il Suo sito HSTS (almeno 180 giorni, dopo che https funziona bene da un po' di tempo), X-Content-Type-Options: nosniff e frame-ancestors 'self' (o X-Frame-Options), e pubblichi un security.txt con Contact e un Expires entro un anno. Inserisca il Suo hostname. Il programma recupera https://<hostnaam>/ e verifica gli header, poi recupera https://<hostnaam>/.well-known/security.txt e verifica i campi. Non salva nulla oltre al risultato e alla data di Expires.

Esercizio Z7.4: HSTS, header e security.txt

Solo per i corsisti iscritti. Recuperiamo https://<naam>/ e /.well-known/security.txt (solo GET).




Quello che inserisce e quello che rileviamo non vengono salvati. Il Suo browser ricorda le Sue risposte e se ha superato l'esercizio. Se ha effettuato l'accesso, conserviamo in I miei corsi solo il fatto che l'esercizio era (quasi) corretto; anche lì può eliminarlo.

Per approfondire

Un momento…

Configuri i suoi domini

Per ogni dominio imposti i nameserver, il collegamento al suo hosting e chi ne diventa l'intestatario.

Caricamento dei suoi domini…