NGINX e Home Assistant: aumentiamo la sicurezza della nostra domotica
Argomento: Nginx |
Livello: Esperto (Novizio,Esperto, Pro) |
Difficoltà: Media (Bassa, Media, Alta) |
Introduzione
Scopo di questo articolo è cercare di dare una soluzione per esporre su Internet in maniera “centralizzata” i servizi di domotica, ma non solo, presenti nella nostra LAN domestica: per fare questo sarà messo in piedi un servizio di reverse proxy.
Cosa è un reverse proxy?
Intanto partiamo dal concetto e definizione di server proxy: un server proxy è un servizio che ha il compito di ricevere richieste di contenuto da uno o più client della propria rete e di inoltrarle a molteplici server che si trovano per esempio su Internet.
Un reverse proxy o proxy inverso, come dice il nome, effettua il lavoro opposto del proxy: accetta una richiesta da client come un browser su PC o uno smartphone collegati per esempio alla rete Internet e la inoltra ad uno o più server nella propria rete aziendale o domestica, ricevuta la risposta da questo server la consegna al client originale. Il reverse proxy effettua tutte le operazioni necessarie per garantire il flusso regolare del traffico di rete tra client e server.
Questo articolo riguarderà NGINX uno dei più diffusi ed utilizzati reverse proxy, che è disponibile come addon per Home Assistant, in realtà di addon ne esistono due: uno “ufficiale” e uno della community; quello della community ha una interfaccia grafica di configurazione cosa che manca nell’addon ufficiale. Esistono altri soluzioni di reverse proxy come Caddy disponibili per HA come addon di terze parti, la cui configurazione si basa su concetti simili a quelli che saranno esposti nell’articolo.
Benefici delle soluzioni reverse proxy
L’utilizzo di un reverse proxy come NGINX ha alcuni vantaggi che riporto di seguito: si tratta di benefici generali che non si adattano a tutti i casi d’uso o configurazioni, in particolare nel caso di Home Assistant il beneficio principale è quello del miglioramento della sicurezza.
- Bilanciamento del carico (load balancing): un proxy inverso può eseguire il bilanciamento del carico che consente di distribuire le richieste dei client in modo uniforme tra N server di back-end. Questo processo aiuta notevolmente a evitare lo scenario in cui un determinato server viene sovraccaricato a causa di un picco improvviso nelle richieste, inoltre migliora anche la ridondanza poiché se un server si arresta, il proxy inverso reindirizzerà semplicemente le richieste a un altro server.
- Miglioramento della sicurezza: un proxy inverso funge anche da linea di difesa per i server back-end (nel caso specifico HA), infatti il reverse proxy garantisce che l’identità dei server di back-end rimanga sconosciuta.Questo ad esempio è di aiuto nella protezione dei server da attacchi DoS. Altro caso d’uso relativo ad Home Assistant è la possibilità di aprire unicamente la porta HTTPS/443 sul proprio firewall, e gestire diversi servizi attraverso opportuni nomi DNS (Domain Name System). Inoltre come vedremo nelle configurazioni di dettaglio sarà possibile personalizzare alcuni parametri come le versioni dei protocolli SSL/TLS e le cosidette cipher suite, cioè gli algoritmi per lo scambio delle chiavi crittografiche, di crittografia e di message authentication,
- Miglioramento delle prestazioni: Nginx per esempio ha prestazioni eccellenti nel fornire contenuto statico pertanto, se gestisce tutte le richieste di questo tipo ed invia la richiesta di contenuti dinamici ad un web server è possibile migliorare le prestazioni ottimizzando la consegna degli contenuti in base alla loro tipologia. Inoltre, i proxy inversi possono anche essere utilizzati per consegnare il contenuto memorizzato nella cache ed eseguire la crittografia SSL (SSL offloading) per alleggerire il lavoro del server Web.
- Logging e controllo (auditing) facilitati: poiché esiste un solo punto di accesso, ciò rende le funzioni di logging e auditing molto più semplici. Utilizzando questo metodo, è possibile monitorare facilmente ciò che entra ed esce attraverso il proxy inverso.
Configurazione NGINX
Come consueto Home Assistant (una volta conosciuto come Hass.io) ci dà una bella mano nell’installazione visto che esistono ben due addon NGINX uno da configurare in maniera manuale attraverso un file di configurazione e l’altro tramite interfaccia grafica. Per chi invece utilizza Home Assistant Core e volesse installare NGINX consiglio di seguire una delle tante guide presenti su Internet e tornare poi qui per prendere spunto per la configurazione dei servizi di reverse proxy.
Configurazione addon ufficiale
La configurazione base dell’addon è piuttosto semplice, l’esempio seguente ha come prerequisiti alcuni passaggi importanti che vanno eseguiti prima di passare alla configuraizone dell’addon vero e proprio:
- configurazione di un dominio di terzo livello su Duckdns.org, nell’esempio miosito.duckdns.org, è possibile anche utilizzare un proprio dominio per esempio www.miodominio.com.
- se utilizzate l’addon DuckDNS nella cartella
/ssl
, avrete già i certificati per HTTPS, se non utilizzate DuckDNS avete bisogno di creare questi certificati in qualche modo se vorrete utilizzare HTTPS - nel file
configuration.yaml
, eliminate dalla sezionehttp:
le seguenti opzioni:ssl_certificate
,ssl_key
,server_port
comebase_url
inserite il vostro sito (ad esempiohttps://miosito.duckdns.org
)
Nel blocco di codice sottostante è riportata la configurazione dell’addon dove le voci certfile
e keyfile
si riferiscono ai certificati per l’HTTPS e domain
al proprio dominio DuckDNS o altro nome DNS, la sezione customize
con la voce active: true
è da usare per le configurazioni avanzate.
1 2 3 4 5 6 7 8 9 |
domain: miosito.duckdns.org certfile: fullchain.pem keyfile: privkey.pem hsts: max-age=63072000; includeSubDomains cloudflare: false customize: active: false default: nginx_proxy_default*.conf servers: nginx_proxy/*.conf |
La configurazione proposta effettua la crittografia del traffico tra il client e il reverse proxy, mentre tra reverse proxy e HA il traffico è in chiaro. La figura seguente dà una vista di insieme delle varie componenti con il flusso del traffico che passa dal reverse proxy e viene dirottato ad un altro server, per esempio una NAS, dove risiede il servizio richiesto.
Configurazioni avanzate addon ufficiale
Con la precedente configurazioni dell’addon il vostro accesso da remoto ad Home Assistant passa ora da NGINX, quello che però è possibile fare con un reverse proxy non si limita solo a questo, ma è possibile rendere disponibile all’esterno con una connessione sicura HTTPS qualsiasi servizio web abbiate nella vostra rete domestica.
Per rendere fruibile questa possibilità esistono due configurazioni che possono essere messe in campo:
- utilizzo di virtual host
- URL Rewrite
Virtual Host
“Virtual host” è un termine che è proprio del web server Apache, tuttavia, viene comunemente utilizzato anche dagli utenti di Nginx anche se il termine corretto sarebbe “server block”. Comunque il significato è il medesimo e si riferisce alla caratteristica di poter ospitare più siti web su un singolo server. Questa funzionalità è molto comodo perché possiamo richiamare dall’esterno cioè da un client su Internet attraverso differenti nomi DNS un servizio web che gira sullo stesso server/raspberry in cui gira NGINX o in un altro server della propria rete domestica.
Vediamo un esempio di configurazione da inserire in un file con estensione .conf nella cartella /share/nginx_proxy
:
- server_name: è il nome DNS che vogliamo richiamare, occorre naturalmente configurarlo su DuckDNS
- ssl_certificate e ssl_certificate_key: sono i certificati associati al nome DNS che vogliamo richiamare
- ssl_protocols: riguarda quali versioni del prorocollo SSL/TLS può utilizzare NGINX in fase di negoziazione (“handshake”) con il client, si consiglia di lasciare solo TLS 1.2 e 1.3, visto che versioni precedenti sono considerate non sicure e dal marzo 2020 i principali browser web non le supporteranno più.
- ssl_ciphers: riguarda gli algoritmi di cifratura che possono essere utilizzati nella fase di handshake del protocollo SSL/TLS, anche qui occorre prestare attenzione a cosa si usa perché nel corso del tempo alcuni algoritmi possono diventare obsoleti, per questa sezione ho seguito le indicazioni riportate da Mozilla.
- sezione location: in questa sezione alla voce
proxy_pass
va specificato tramite indirizzo IP e porta TCP il server della rete domestica che vogliamo richiamare dall’esterno
Per gli altri parametri della configurazione vi rimando alla documentazione ufficiale di NGINX.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
server { server_name miosito2.duckdns.org; # dhparams file ssl_dhparam /data/dhparams.pem; ssl_certificate /ssl/fullchain.pem; ssl_certificate_key /ssl/privkey.pem; listen 443 http2 ssl; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; proxy_buffering off; location / { proxy_pass http://192.168.1.101:80; proxy_redirect http:// https://; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } |
URI Rewrite
Con questa tecnica è possibile cambiare parte dell’URI in una richiesta proveniente da un client, si usa per esempio per informare che una risorsa risiede in una posizione diversa. Nel nostro caso usremo la tecnica per associare diversi siti web disponibili sulla propria LAN domestica o semplicemente sul proprio server/Rasberry ad un unico nome DNS.
Il trucco consiste nel far corrispondere ad ogni URI un web server diverso, per esempio potrei associare l’url miosito.duckdns.org
ad Home Assistant e miosito.duckdns.org/plix
ad un server chiamato “plix” che “gira” sulla porta 32000.
Vediamo la configurazione da inserire nel file /share/nginx_proxy_default.conf
:
- location: definisce il modo in cui le richieste vengono elaborate per diversi URI e risorse
- proxy_pass: imposta il protocollo e l’indirizzo di un server proxy e un URI opzionale a cui deve essere mappata una location.
- rewrite: impostando il “break” il processo di riscrittura dell’URI si interrompe e la richiesta modificata non verrà elaborata da un’altra “location”
1 2 3 4 5 6 7 8 9 10 |
location /plix/ { rewrite /plix/(.*) /$1 break; proxy_pass http://192.168.1.101:32400; proxy_redirect http:// https://; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } |
Configurazione addon della community
Come detto precedentemente l’add-on della community si avvale di un interfaccia grafica e ci evita di dover andare a scrivere a mano i nostri file. Una volta installato l’addon basterà avviarlo e premere open web ui, loggarsi usando user: [email protected]
, pwd: changeme
per vedere caricata la nostra interfaccia grafica, ricordatevi di cambiare user e password.
Premete sul tasto “Proxy Hosts” e poi in alto a destra su “add Proxy Host” e vi ritroverete davanti la seguente schermata:
New Proxy Host
- Domain Names: Inserite qui il vostro dominio, ad esempio
pippo.duckdns.org
- Forward Hostname/Ip: Inserite qui l’indirizzo IP della macchina che volete raggiungere, ad esempio 192.168.1.21
- Forward Port: Inserite qui la porta del servizio, ad esempio se stiamo configurando Home Assistant la 8123
- Attivate Websockets Support e recatevi nella scheda custom location se volete raggiungere qualche altro servizio installato sulla stessa macchina, altrimenti saltate pure il punto seguente.
Custom Location
Supponiamo di voler raggiungere “plix” all’indirizzo “pippo.duckdns.org/plix
“:
- Location: Inseriamo il percorso, nel nostro esempio /plix/
- premiamo il tasto ingranaggio e nel riquadro che si apre inseriamo rewrite /plix/(.*) /$1 break;
- Forward Hostname/Ip: Inserite qui l’indirizzo ip della macchina che volete raggiungere, ad esempio 192.168.1.21
- Forward Port: Inserite qui la porta del servizio, ad esempio 9091
- rechiamoci nella schermata ssl
SSL
- SSL Certificate: Cliccate su “None” e selezionate “request a new ssl certificate”, una volta selezionata la voce vedrete apparire sotto il campo mail, inserite la vostra vera mail, verrà utilizzata per rinnovare il certificato. A tal proposito se utilizzate l’addon DuckDns impostate nella configurazione dell’addon il parametro “accept_terms:” su “false” , da questo momento sarà nginx a rinnovare il vostro certificato, ricordatevi di aprire la porta “80” del router in prossimità della scadenza dello stesso.
- abilitate Force SSL
Se tutto è andato per il verso giusto adesso dovreste raggiungere i vostri servizi agli indirizzi che avete impostato.
Conclusioni
L’articolo ha presentato una configurazione per centralizzare tutti gli accessi dall’esterno verso un unico punto di accesso alla nostra LAN di casa, con i vantaggi sopra descritti ma questo non vuol dire che implementando questa guida non dobbiamo più preoccuparci degli aspetti di sicurezza: occorre sempre stare attenti alle configurazioni e valutare bene quali dati e servizi vogliamo esporre su Internet.
17 risposte
Salve, scusate qual’è la differenza tra usare un proxy server ed una vpn?? Grazie
La vpn ti permette di accedere ad un determinata rete in modo sicuro detto tunnel privato virtuale, senza l’esigenza di avere dei server pubblici esposti al web.
Ciao si potrebbe installare nginx su un server ubuntu e far puntare l’addon a quel server?
Se fosse possibile come?
non mi è chiaro cosa vuoi fare visto che l’addon è NGINX. Se la domanda è: “è possibile usare l’addon NGINX per redirigere il traffico ad un altro server nella LAN?” la risposta è si utilizzando le configurazioni spiegate nel’articolo
Come mai nonostante io specifichi “ssl_protocols TLSv1.2 TLSv1.3;” mi abilita anche la v1.0 e 1.1?
E’ come se non mi leggesse la configurazione personalizzata.
Cosa devo mettere all’interno del file default?
Io vorrei solo accedere al mio hassio senza duckdns, ma con il mio dominio e specificando un po di parametri ssl.
E’ possibile utilizzare un sito TOR, per esempio xxxxxxxxxxx.onion invece di duckdns?
Ciao,
ho istallato l’addon della community ma ora non ho più comunicazione nell’integrazione tra google assistant e HA. come dovrei configurare l’addon per evitare l’errore di Connessione sicura non riuscita?
ciao e grazie!
Domanda da non esperto di reti, a livello di sicurezza, che differenza c’è tra lasciare la 8123 aperta sul router o mettere in piedi questa guida e poi lasciar aperta la 443?
Se oltre a questa guida dovessi ativare anche la VPN con wireguard a quel punto potrei chiudere anche la 443?
L’integrazione con alexa haaska continuerebbe a funzionare?
Grazie
1) se esponi 1 unico servizio, non molta a parte che nginx probabilmente é più “sicuro” di HA
2) se usi la VPN puoi chiudere tutte le porte esposte sull’esterno ad esclusione di quella necessaria per la VPN
3) in VPN le integrazioni alexa / GH non funzionano
ok è un po’ quello che pensavo, ma per il punto 3 non c’è nessun modo di avere una vpn e far funzionare haaska (alexa)?
grazie
Ciao, ho già un server nginx che gira su una macchina della mia rete lan che si occupa di reindirizzare il traffico ai vari ip della lan interna a secondo della URL richiesta.
Ho provato quindi a creare nella configurazione di nginx:
location /ha/ {
rewrite /ha/(.*) /$1 break;
proxy_pass http://IP_DOVE_GIRA_HOMEASSISTANT:8123;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
e poi nelle direttive della location / ho aggiunto:
if ($http_referer ~ “^https?://[^/]+/ha/(.*)$”){
rewrite ^/(.*) https://$http_host/ha/$1 redirect;
}
Collegandomi poi al mio ip pubbico del tipo “https://mio.ip/ha/” la pagina di login spunta ma con un messaggio di errore e non mi fa accedere… idee?
Beh senza log difficile da dire
Ciao e grazie per la guida.
– Home Assistant su porta 8123 su cui ho installato add on Node Red e DuckDns con ssl
autogenerato.
– Su Node Red utilizzo i nodi dashboard e ho quindi creato una semplice dashboard che riesco a
visualizzare su Home Assistant , inserendola su lovelace come pagina web ed indirizzo
“https://homeassistant.local:1880/endpoint/ui/”
– Il problema è da remoto , fuori rete, per esempio dal cellulare. Non riesco proprio a visualizzarla
– Ho visto questa guida ed ho quindi istallato l’ add-on nginx della community con associato le
medesime chiavi ssl utilizzate su Home Assistant.
– Ero speranzoso ma ho provato varie combinazioni senza sbloccare la situazione. Ammetto di
essere messo, diciamo così, discretamente male quando su parla di reti etc. per cui……
– Sul router ho aperto la porta 1880 in ingresso e uscita e la 443 su 8123 , entrambe su IP raspberry.
Ho quasi finito i tentativi per cui …. grazie a prescindere…. ≧◔◡◔≦
allora hai fatto un bell’arrosto, partiamo dal fatto che NGINX o qualsiasi altro reverse proxy serve anche per evitare di aprire una miriade di porte all’esterno, quindi:
1) la prima cosa da fare è aprire una porta sul router verso l’esterno ad esempio la 443 e configurare il port forwarding sul router verso nginx sempre della 443
2) nella conf più semplice, i certifcati SSL li gestisce NGINX quindi la comunicazione tra esterno e NGINX sarà in HTTPS, tra NHINX e HA o nodered o altro addon che non prevede configurazione “ingress” sarà in HTTP (quindi no certificati)
Vedi prima di partire così poi se avrai voglia puoi pensare di usare all’interno della tua LAN (in locale) anche HTTPS
Salve, bellissima guida. Funziona tutto: http da locale e https da esterno. Potresti indicarmi come fare per avere anche https da lan? grazie
Puoi guardare sul sito di neginx come fare, ad esempio è descritto qui come effettuare il collegamento https verso i server interni:
“Or if you instead receive traffic over HTTP and send it to the backend servers over HTTPS –> https://www.nginx.com/blog/nginx-ssl/ ”
Dovrai anche preoccuparti del certificato sul server di backend
Grazie per la splendida guida. Ho messo in campo il tutto al primo colpo !!!