L'obiettivo è configurare una connessione sicura (HTTPS) su Openhab per permettere l'esposizione diretta su internet del vostro Openhab senza usare il servizio Cloud.
Condizione essenziale è avere un IP pubblico fisso o una configurazione DDNS e permettere il portforwarding della porta 443 (o quella che volete configurare) sul vostro router verso l'host di openhab.
Inoltre servirà avere dei certificati digitali che possono essere autoprodotti (selfsigned) oppure possono essere generati con il servizio di Letsencrypt che genererà certificati gratuiti della durata di 3 mesi ma con una CA riconosciuta dai principali browser.
Per usare un DDNS ho trovato comodo DuckDNS, creare un account e registrare il nome host corrispondente al vostro host.
Alla pagina DuckDNS installa il client adatto al tuo host.
Installare OpenSSL:
sudo apt-get install openssl
Una volta completato, è necessario creare una directory in cui posizionare i nostri certificati:
sudo mkdir -p /etc/ssl/certs
Generiamo con OpenSSL una chiave RSA lunga 2048 bit e un certificato valido per un anno (ci metterà diverso tempo):
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/openhab.key -out /etc/ssl/certs/openhab.crt
Ti verranno chieste alcune informazioni che dovrai compilare per il certificato, quando ti verrà richiesto un nome comune , puoi inserire il tuo indirizzo IP: Nome comune (es. FQDN del server o TUO nome) []: xx.xx. xx.xx
Rinominare il certificato in .pem
sudo mv /etc/ssl/certs/openhab.crt /etc/ssl/certs/openhab.pem
Usando il servizio DDNS di DuckDns abbiamo bisogno di creare i certificati digitali con il metodo trovato da jmorahan, quindi creiamo questo due script nella HOME di openhabian sostituendo il valore del tuo TOKEN preso da DuckDns:
auth.sh
#!/bin/bash
DUCKDNS_TOKEN="your_token_here"
[[ "$(curl -s "https://www.duckdns.org/update?domains=${CERTBOT_DOMAIN%.duckdns.org}&token=${DUCKDNS_TOKEN}&txt=${CERTBOT_VALIDATION}")" = "OK" ]]
cleanup.sh
#!/bin/bash
DUCKDNS_TOKEN="your_token_here"
[[ "$(curl -s "https://www.duckdns.org/update?domains=${CERTBOT_DOMAIN%.duckdns.org}&token=${DUCKDNS_TOKEN}&txt=${CERTBOT_VALIDATION}&clear=true")" = "OK" ]]
Concediamo le autorizzazioni di esecuzioni:
chmod +x auth.sh cleanup.sh
Procediamo con il processo di verifica lanciando:
sudo certbot certonly --manual --preferred-challenges dns --manual-auth-hook ./auth.sh --manual-cleanup-hook ./cleanup.sh
I certificati avranno scadenza 90 giorni, potranno essere rinnovati con il comando:
certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"
Usiamo lo strumento di configurazione di Openhab:
sudo openhabian-config
Scegliere una USERNAME e una PASSWORD e concludere la procedura con l'installazione automatica dei pacchetti necessari.
Il file di configurazione che ne consegue dovrebbe essere una cosa del genere sotto il path /etc/nginx/sites-enabled/openhab (caso SELFSIGNED):
#################################
# openHABian NGINX Confiuration #
#################################
## Redirection
server {
listen 80;
server_name IPPUBBLICO;
return 301 https://$server_name$request_uri;
}
## Reverse Proxy to openHAB
server {
# listen 80;
listen 443 ssl;
server_name IPPUBBLICO;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
# Cross-Origin Resource Sharing.
# add_header 'Access-Control-Allow-Origin' 'http://localhost:8080/rest';
add_header 'Access-Control-Allow_Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
## Secure Certificate Locations
ssl_certificate /etc/ssl/certs/openhab.pem;
ssl_certificate_key /etc/ssl/private/openhab.key;
location / {
proxy_pass http://localhost:8080/;
# proxy_buffering off; # openHAB supports non-buffering specifically for SSEs now
proxy_set_header Host $http_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;
# Password Protection
auth_basic "Username and Password Required";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
Il file di configurazione che ne consegue dovrebbe essere una cosa del genere sotto il path /etc/nginx/sites-enabled/openhab (caso letsencrypt):
#################################
# openHABian NGINX Confiuration #
#################################
## Redirection
server {
# listen 80;
server_name mydomain.duckdns.org;
return 301 https://$server_name$request_uri;
}
## Reverse Proxy to openHAB
server {
# listen 80;
listen 443 ssl;
server_name mydomain.duckdns.org;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
# Cross-Origin Resource Sharing.
add_header 'Access-Control-Allow-Origin' '*' always; # make sure that also a 400 response works
add_header 'Access-Control-Allow_Credentials' 'true' always;
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range' always;
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH' always;
## Secure Certificate Locations
ssl_certificate /etc/letsencrypt/live/mydomain.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain.duckdns.org/privkey.pem;
location / {
proxy_pass http://localhost:8080/;
# proxy_buffering off; # openHAB supports non-buffering specifically for SSEs now
proxy_set_header Host $http_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_read_timeout 3600; # to avoid "offline" error msgs in Basic UI
## Password Protection
auth_basic "Username and Password Required";
auth_basic_user_file /etc/nginx/.htpasswd;
}
## Let's Encrypt webroot location
location /.well-known/acme-challenge/ {
root /var/www/mydomain.duckdns.org;
}
}
# vim: filetype=conf
Se la chiave ssl_dhparam non è presente generarla:
sudo openssl dhparam 2048 -out /etc/nginx/ssl/dhparam.pem
Puoi testare le tue impostazioni di sicurezza su SSLLABS (assicurati di selezionare "Non mostrare i risultati nelle schede" se non desideri che il tuo dominio venga visualizzato)
Se vogliamo raggiungere migliori livelli di sicurezza dobbiamo generare delle chiavi più sicure:
sudo mkdir -p /etc/nginx/ssl
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
Inseriamo nella parte degli SSL certificate queste direttive (assicurati che siano sopra le location)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
keepalive_timeout 70;
Per aggiungere un nuovo utente:
sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd {username}
Per rimuovere un utente:
sudo htpasswd -D /etc/nginx/.htpasswd {username}
Per rilanciare il NGINX:
sudo systemctl restart nginx.service
Link utili
2018 Ⓒ TanzoLab