SCOPI DELLA GUIDA:
CONCETTI AFFRONTATI:
|
COMPONENTI SOFTWARE UTILIZZATE:
PREREQUISITI:
DISPOSITIVI FISICI UTILIZZATI:
|
GUIDA DEDICATA A utenti: |
|
NOTE E DISCLAIMER
|
|
Revisione guida: 2.3 |
Abstract
Con un Raspberry Pi installato con sistema operativo Raspberry Pi OS è relativamente facile dotarsi di un servizio reverse proxy per la propria rete domestica.
L’adozione di un software gratuito come Caddy, per esempio, consente di realizzare tale funzionalità di rete in pochi e semplici passi; tale strumento può poi essere configurato e utilizzato per le sue tipiche funzioni di reindirizzamento delle chiamate da Internet verso servizi presenti sulla propria rete interna nonché l’ottenimento automatico degli eventuali certificati crittografici utili alla navigazione sicura verso tali servizi.
N.b. Sebbene non si tratti di scienza missilistica, l’implementazione di questa guida prevede un minimo di cultura sul networking nonché sul funzionamento del reverse proxy. Inutile e deleterio tentare di configurare su Caddy senza conoscere l’abc su questi temi. |
ATTENZIONE: Per funzionare, questa guida dev’essere letta con particolare attenzione e calma. Pena, il probabile fallimento della configurazione del servizio.
Si parte
Assunti
Questa guida è dedicata a chi abbia già un Raspberry in uso con sistema operativo Raspberry Pi OS (aka Raspberry Pi OS). Per coloro che non abbiano ancora provveduto e si trovino ad avere un Raspberry nuovo, magari acquistato appositamente per realizzare la propria domotica, allora questo passo della guida va smarcato seguendo prima un’altra guida, che spiega passo passo come configurare il sistema operativo Raspberry Pi OS.
La guida da seguire:
-
- per chi abbia a disposizione una tastiera e un mouse USB, è questa;
- per chi non li abbia, è quest’altra.
Una volta terminata la configurazione di Raspberry Pi OS (inclusa la possibilità di collegarvisi tramite SSH nonché aver effettuato il perfezionamento) è possibile procedere nella presente guida.
Si assume infine che l’host che ospiterà Caddy possegga un indirizzo IP fisso assegnato automaticamente dal router domestico.
Installare Docker
Installare Docker su Raspberry Pi dotato di sistema operativo Raspberry Pi OS è piuttosto semplice, esiste una procedura completamente automatica e una manuale. Entrambe le procedure sono illustrate in dettaglio in questa breve guida.
Se si ha già provveduto all’installazione di Docker, va da sé che questo passaggio possa essere saltato.
ATTENZIONE: affinché i comandi a seguire funzionino, è necessario aver aggiunto Docker al gruppo sudoers, come spiegato in guida. |
Dominio
N.b. Se si possiede un dominio proprio o comunque una gestione DDNS diversa da DuckDNS, si può saltare direttamente alla sezione “Port forwarding“. |
Affinché sia raggiungibile dall’esterno in modo semplificato, il punto di accesso alla rete domestica (ovvero interfaccia WAN del modem) deve esser rappresentato da un nome univoco (chiamato FQDN) il quale veda l’IP ad esso associato aggiornarsi automaticamente ad ogni variazione, dato che quello assegnato al vostro modem/router cambia ciclicamente. Per fare questo interviene il servizio Dynamic DNS (o DDNS), ovvero un servizio che tenga traccia dell’ultima variazione e risponda, ai sistemi che chiedano la risoluzione (traduzione) del nome DNS, l’ultimo IP conosciuto, ovvero quello in uso.
DuckDNS è il servizio che abbiamo scelto per questa funzione di fornitura di FQDN nonché di associazione dinamica dell’IP.
N.b. Caddy può serenamente gestire anche domini propri acquistati e gestiti sulla rete dai più diversi fornitori diversi da DuckDNS. Come vedremo a seguire, la “challenge” (ovvero la procedura di ottenimento automatica dei certificati) varia da fornitore a fornitore: impossibilitati a documentare qualsiasi casistica possibile, in questa guida analizzeremo le più comuni modalità di challenge tra i servizi più comunemente usati. Ciononostante, con i debiti accorgimenti la guida di massima è valida anche per gli altri casi. |
Collegarsi quindi al servizio tramite l’indirizzo https://www.duckdns.org e, una volta registrati creare un proprio nome dominio che, univocamente, rappresenterà il vostro modem collegato ad Internet. Il suffisso è sempre lo stesso (“.duckdns.org“) mentre ciò che cambia e va scelto è il suffisso (per esempio “casamia“).
Per questa guida, daremo per assunto di aver creato il seguente FQDN:
casamia.duckdns.org
dove “duckdns.org” è la parte fissa mentre casamia è il nome di dominio da noi creato a mo’ di esempio.
All’interno della vostra sezione privata di DuckDNS troverete anche un campo importante chiamato “token“, il quale appare analogo a questo:
e3ff465f-c6d6-acb1-4416-44b2af152111
Appuntarselo da una parte, tornerà utile a breve.
Aggiornamento di DuckDNS
Prima di provvedere alla configurazione di Caddy è necessario assicurarsi che l’associazione del proprio FQDN con l’IP assegnato al modem dal nostro provider Internet sia garantita quasi in tempo reale. A fronte dell’eventuale cambiamento dell’IP Internet sull’interfaccia WAN del proprio modem/router, è necessario che tale variazione venga comunicata a DuckDNS, in modo da aggiornare la conseguente risoluzione dell’FQDN.
N.b. Questo paragrafo non va attuato se sulla propria rete c’è già qualche dispositivo che provveda a tale funzione di associazione dell’IP con il proprio FQDN, come per esempio un modem/router FRITZ!Box o altri modelli/marche in grado di effettuare da sé l’operazione. Se e quando un modem è in grado di provvedere a tale funzione, è sempre buona regola lasciare che sia lui ad aggiornare tale associazione, e non il Raspberry o altri host della propria rete. |
N.b. Gli utenti che utilizzino già l’HUB Home Assistant possono alternativamente utilizzare questa guida che non prevede l’adozione di un container ad hoc, cosa invece descritta nel presente paragrafo. |
Istanzieremo dunque un container Docker ad hoc che contenga una mini-app concepita specificamente a tal scopo.
Per farlo, eseguire il seguente comando:
docker run -d --name=duckdns -e TZ=Europe/Rome -e SUBDOMAINS=NOME_DOMINIO -e TOKEN=MIO_TOKEN_DUCKDNS --restart always ghcr.io/linuxserver/duckdns
sostituendo nel comando le stringhe indicate come segue:
NOME_DOMINIO | nome dominio definito sul servizio DuckDNS (inteso come terzo livello, quindi nel caso sopra solo “casamia“) |
MIO_TOKEN_DUCKDNS | toker fornito da DuckDNS |
Eseguito il comando, il container verrà scaricato ed istanziato. Al termina, verificare tramite il comando:
docker logs duckdns
che i log riportino qualcosa tipo:
Your IP was updated at Thu Gen 1 00:00:00 CET 1980
il che indica un corretto avvio dell’applicazione container e dell’avvenuto aggiornamento dell’associazione IP/FQDN.
Diversamente, un errore tipo:
Something went wrong, please check your settings Thu Gen 1 00:00:00 CET 1980
indica che qualche errore è stato commesso nella formulazione del comando di cui sopra (verificare nome dominio e token).
In caso di errori, fermare e cancellare il container con:
docker container stop duckdns docker container rm duckdns
e ritentare, correggendo gli errori, la sua creazione come spiegato sopra.
Una volta attuata correttamente tale configurazione, DuckDNS conoscerà in tempo (quasi) reale l’IP del vostro modem/router, e con lui, voi e chi interrogherà tale FQDN.
Configurazione Docker Compose
Per coloro che utilizzino, per la gestione dei container, l’utile tool Docker Compose, la configurazione è la seguente:
duckdns:
container_name: duckdns
image: ghcr.io/linuxserver/duckdns
environment:
- "TZ=Europe/Rome"
- "SUBDOMAINS=NOME_DOMINIO"
- "TOKEN=MIO_TOKEN_DUCKDNS"
restart: always
Prestare attenzione, ovviamente, alle personalizzazoni dei campi SUBDOMAINS e TOKEN come da indicazioni precedenti.
Una volta salvato il file docker-compose.yaml, eseguire il comando:
docker compose up -d duckdns
il quale provvederà a istanziare il container.
N.b. In caso il comando “docker compose” dovesse dare errore, verificare di non aver installata la versione applicativa di Docker Compose anzichè la versione plug-in alla quale il comando sopra fa riferimento. In tal caso, adeguare il comando da “docker compose” a “docker-compose” (col trattino in mezzo). |
Port forwarding
Per far sì che Caddy possa autonomamente provvedere all’ottenimento di eventuali certificati SSL per il proprio FQDN nonché accettare le connessioni esterna da girare – in quanto reverse proxy – è necessario configurare delle regole di port forwarding sul modem/router. Il cosiddetto “aprire le porte”.
Prima di proseguire oltre – se non si ha già dimestichezza col port forwarding – si consiglia la lettura di questo articolo.
IMPORTANTE.
Le regole di port forwarding variano in base alle porte che si vogliano esporre verso Internet rispetto a quelle aperte (e da raggiungere) internamente. Questo non è oggetto della presente guida, in quanto qualsiasi guida presente su inDomus che referenzi la presente e che utilizzi Caddy come reverse proxy spiegherà questo aspetto nello specifico del servizio. Ciò che viene spiegato in questa occasione – ovvero alla prima installazione e configurazione di Caddy – è relativo alle porte (eventualmente) da aprire in caso si voglia far provvedere a Caddy all’ottenimento di eventuali certificati SSL per la securizzazione delle comunicazioni dentro-fuori. I certificati crittografici, per essere considerati validi, devono essere rilasciati da una Certification Authority riconosciuta: nel caso della presente guida utilizzeremo il servizio gratuito Let’s Encrypt. Questo processo viene automatizzato sfruttando uno specifico protocollo (chiamato ACME Protocol) il quale prevede tre modalità diverse, dette anche challenge, per appurare la propria “identità” al gestore del servizio e ottenere quindi i certificati richiesti. Tali modalità sono:
Su Caddy le prime due challenge vengono utilizzate di default, la terza invece va eventualmente abilitata in configurazione (il che disabilita le prime due).
Dunque, quali porte vanno “aperte” tramite port forwarding e girate verso l’host che ospita Caddy? La TCP 80, la 443 o nessuna? La scelta ovviamente è soggettiva e dipende da diversi fattori. Dipende in primis dal DNS provider, in base se esso consenta o meno la scrittura dei TXT record. Dipende anche dal proprio modem: non tutti permettono l’apertura delle porte 80 e 443. Dipende dalla volontà o meno di voler esporre il proprio server sulle porte 80 e 443. Per fare qualche esempio:
e altro. |
In questa guida assumeremo di utilizzare la casistica più classica, ovvero il primo esempio qui sopra spiegato, ovvero quello che utilizza port forwarding della porta TCP 443 o TCP 80 nonché – come vedremo – la corretta challenge prevista per DuckDNS (la TLS-ALPN).
La configurazione per il port forwarding sul modem da noi consigliata è:
- IP destinazione: IP statico del Raspberry Pi (assegnato in precedenza);
- Porta esterna: TCP 443
- Porta interna: TCP 443
oppure
- IP destinazione: IP statico del Raspberry Pi (assegnato in precedenza);
- Porta esterna: TCP 80
- Porta interna: TCP 80
Punto della situazione
Arrivati a questo punto della guida abbiamo:
- un FQDN rappresentante il nostro punto di ingresso alla rete locale;
- un sistema di aggiornamento automatico dell’FQDN;
- un port forwarding su porta TCP 443 o 80 (o nessuno, se si usa la DNS Challenge).
Ora non manca che installare Caddy e far sì che nella sua configurazione ci sia l’ottenimento automatico dei certificati da parte di Let’s Encrypt per il nostro FQDN.
Istanziare Caddy su Docker
Una volta dotati di un proprio FQDN è dunque il momento di installare (o meglio, “istanziarvi sopra”) Caddy. Prima di procedere, però, è necessario creare una cartella la quale conterrà la sua configurazione.
Una volta collegati via SSH al Raspberry Pi tramite utenza “pi“, provvedere a creare a cartella:
mkdir -p ~/caddy/data
Creare poi un file il file di configurazione (detto – e chiamato – “Caddyfile“):
nano ~/caddy/Caddyfile
all’interno copiare il seguente codice:
# When your config is ok comment block below to disable use of AMCE staging server
{
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
https://casamia.duckdns.org {
respond "Saluti dal Crew inDomus.it"
file_server
}
Dove ovviamente “casamia.duckdns.org” andrà personalizzato col proprio FQDN.
Una volta completata la modifica, usciamo dall’editor salvando il file (CTRL+x, y, invio).
Istanziamo dunque Caddy su Docker tramite il comando specifico al quale passeremo i seguenti argomenti:
- nome del container: caddy;
- il file di configurazione “Caddyfile” da utilizzare;
- la directory “data” nella quale verranno salvati i certificati;
- la porte da esporre (443 o 80).
Eseguire quindi il comando:
docker run --init -d --name="caddy" -e "TZ=Europe/Rome" -v ~/caddy/Caddyfile:/etc/caddy/Caddyfile -v ~/caddy/data:/data --restart always -p 443:443 -p 80:80 caddy:latest
Al termine, verifichiamo che tutto sia andato per il verso giusto:
docker logs caddy
in fondo al log dovremmo trovare qualcosa come:
{"level":"info","ts":1610093092.9648476,"logger":"tls.issuance.acme.acme_client","msg":"validations succeeded; finalizing order","order":"https://acme-staging-v02.api.letsencrypt.org/acme/order/yyyyyy/zzzzzz"} {"level":"info","ts":1610093093.8919973,"logger":"tls.issuance.acme.acme_client","msg":"successfully downloaded available certificate chains","count":2,"first_url":"https://acme-staging-v02.api.letsencrypt.org/acme/cert/xxxxxxxxxxxxxxxxxxxxxxxxxxx"} {"level":"info","ts":1610093093.8923566,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"casamia.duckdns.org"}
il che confermerà il funzionamento del tutto.
Andremo anche verificare la generazione fisica dei certificati portandoci sotto la directory appena creata: noteremo che sarà presente un’alberatura nuova nella quale troveremo i file dei certificati:
sudo ls -latr ~/caddy/data/caddy/certificates/acme-staging-v02.api.letsencrypt.org-directory/casamia.duckdns.org
questo l’output:
total 20
-rw------- 1 pi pi 227 gen 1 00:00 casamia.duckdns.org.key
-rw------- 1 pi pi 171 gen 1 00:00 casamia.duckdns.org.json
-rw------- 1 pi pi 3299 gen 1 00:00 casamia.duckdns.org.crt
drwx------ 3 pi pi 4096 gen 1 00:00 ..
drwx------ 2 pi pi 4096 gen 1 00:00 .
In caso di problemi, ripetere i passi precedenti, portando particolare attenzione alla configurazione di port forwarding sul modem/router.
Come spiegato sopra, questi non sono i certificati definitivi: dovremo quindi fermare il container Docker di Caddy, modificare il file di configurazione e riavviarlo.
nano ~/caddy/Caddyfile
Cancelliamo le prime quattro righe; il contenuto del file di configurazione diventerà quindi:
https://casamia.duckdns.org { respond "Saluti dal Crew inDomus.it" file_server }
Dove ovviamente “casamia.duckdns.org” andrà personalizzato col proprio FQDN.
Una volta completata la modifica, usciamo dall’editor salvando il file (CTRL+x, y, invio).
Riavviamo dunque il container:
docker restart caddy
dopo il riavvio, verifichiamo i log:
docker logs caddy
anche in questo caso dovremmo trovare:
{"level":"info","ts":1610092585.0720239,"logger":"tls.issuance.acme.acme_client","msg":"validations succeeded; finalizing order","order":"https://acme-v02.api.letsencrypt.org/acme/order/yyyyyy/zzzzzz"} {"level":"info","ts":1610092586.0094872,"logger":"tls.issuance.acme.acme_client","msg":"successfully downloaded available certificate chains","count":2,"first_url":"https://acme-v02.api.letsencrypt.org/acme/cert/xxxxxxxxxxxxxxxxxxxxxxxxxxx"} {"level":"info","ts":1610092586.0111442,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"casamia.duckdns.org"}
il che confermerà il funzionamento definitivo del tutto.
Andremo anche verificare la generazione fisica dei certificati portandoci sotto la directory appena creata: noteremo che sarà presente un’alberatura nuova nella quale troveremo i file dei certificati:
sudo ls -latr ~/caddy/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/casamia.duckdns.org
questo l’output:
total 20
-rw------- 1 pi pi 227 gen 1 00:00 casamia.duckdns.org.key
-rw------- 1 pi pi 171 gen 1 00:00 casamia.duckdns.org.json
-rw------- 1 pi pi 3299 gen 1 00:00 casamia.duckdns.org.crt
drwx------ 3 pi pi 4096 gen 1 00:00 ..
drwx------ 2 pi pi 4096 gen 1 00:00 .
A questo punto come verifica finale possiamo puntare al dominio configurato nel Caddyfile
https://casamia.duckdns.org
avendo naturalmente cura di correggere casamia col proprio nome dominio.
Se si accederà a una schermata del seguente tipo:
congratulazioni: Caddy è ora operativo.
Configurazione Docker Compose
Per coloro che utilizzino, per la gestione dei container, l’utile tool Docker Compose, la configurazione è la seguente:
caddy:
container_name: caddy
image: caddy:latest
volumes:
- "~/caddy/Caddyfile:/etc/caddy/Caddyfile"
- "~/caddy/data:/data"
environment:
- "TZ=Europe/Rome"
restart: always
ports:
- "80:80"
- "443:443"
Una volta salvato il file docker-compose.yaml, eseguire il comando:
docker compose up -d caddy
il quale provvederà a istanziare il container.
N.b. In caso il comando “docker compose” dovesse dare errore, verificare di non aver installata la versione applicativa di Docker Compose anzichè la versione plug-in alla quale il comando sopra fa riferimento. In tal caso, adeguare il comando da “docker compose” a “docker-compose” (col trattino in mezzo). |
Abbiamo finito?
In realtà, nì.
Caddy, di per sé ora è operativo ma, in buona sostanza, non sta facendo nulla se non ottenere automaticamente gli aggiornamenti dei certificati per il nostro FQDN. Va da sé che per utilizzarlo per ciò che è concepito, ovvero la funzione di reverse proxy, sarà necessario indicare in configurazione (nel “Caddyfile”) quali regole implementare e riavviare coerentemente il container, oltre a implementare le relative regole di port forwarding sul modem/router.
Un esempio: Home Assistant
Ipotizziamo di voler gestire il traffico esterno per un’istanza di Home Assistant presente sulla rete interna in modo da farlo raggiungere dall’esterno su porta 9000 (e in modo sicuro con certificati SSL) per controllare la propria domotica in remoto.
Le cose da fare sono:
- modificare coerentemente il “Caddyfile”;
- configurare il port forwarding;
- riavviare il container Docker di Caddy.
MODIFICA AL CADDYFILE
Modificheremo il Caddyfile come segue:
(https_header) { header { Strict-Transport-Security "max-age=31536000; includeSubdomains" X-XSS-Protection "1; mode=block" X-Content-Type-Options "nosniff" X-Frame-Options "SAMEORIGIN" Referrer-Policy "same-origin" } } https://casamia.duckdns.org { respond "Saluti dal Crew inDomus" file_server } https://casamia.duckdns.org:9000 { import https_header reverse_proxy http://IP_DELLA_ISTANZA_HOME_ASSISTANT:8123 @ws: { header Connection "Upgrade" header Upgrade websocket } }
Come si nota, la regola indica che tutte le richieste https verso casamia.duckdns.org:9000 vengano reindirizzate verso l’indirizzo interno http://IP_DELLA_ISTANZA_HOME_ASSISTANT:8123.
CONFIGURARE IL PORT FORWARDING
Sul modem/router, definire una regola di port forwarding così modellata:
- IP destinazione: IP statico del Raspberry Pi che ospita Caddy
- Porta esterna: TCP 9000
- Porta interna: TCP 9000
RICONFIGURARE CADDY
docker container stop caddy
docker container rm caddy
docker run --init -d --name="caddy" -e "TZ=Europe/Rome" -v ~/caddy/Caddyfile:/etc/caddy/Caddyfile -v ~/caddy/data:/data --restart always -p 443:443 -p 9000:9000 caddy:latest
Si noti come in fondo al secondo comando sia stato aggiunto -p 9000:9000, ovvero l’associazione della nuova porta d’ingresso ora gestita, la 9000. Terminata questa configurazione, Home Assistant sarà raggiungibile dall’esterno, via https, presso il proprio FQDN alla porta 9000.
Questo ovviamente è solo un esempio illustrativo: per tutte le possibili configurazioni (non documentate da inDomus) si consiglia di far riferimento direttamente alla documentazione Caddy.
N.b. Attenzione: naturalmente se si provvede a instanziare Caddy via Docker Compose, va da sé che anche tale file debba essere modificato aggiungendo le porte da esporre al container, per esempio la 9000 come per l’esempio sopra. |
RICONFIGURARE HOME ASSISTANT
Dato che abbiamo portato l’esempio di Home Assistant, dopo la configurazione di Caddy ricordarsi anche di effettuare un’ultima modifica, ma stavolta lato Home Assistant.
Questa pagina è redatta, manutenuta e aggiornata dallo staff di inDomus, un gruppo di persone molto diverse tra loro che trovi, per domande e supporto, sul forum e sulla chat del sito. Alcuni link sono taggati in qualità di affiliati Amazon e riceviamo un compenso dagli acquisti idonei, utile al sostenimento del sito, ma le nostre recensioni sono tutte indipendenti e non sponsorizzate. Se ti sei perso, a tua disposizione c'è la mappa. |