Login

Navigation

使用NGINX反向代理Home Assistant

Cover.png

前言:
使用NGINX作為Home Assistant的反向代理(Reverse Proxy),可以安全地使用標準的443(HTTPS)端口連接Home Assistant服務。

實現條件:
  • 在DNS服務,使域名(Domain)指向代理伺服器的外網(Public IP)
  • 在代理服務器內安裝Nginx服務及穫取SSL安全證書
  • 在Nginx添加Home Assistant的配置文件

操作步驟:
操作步驟是圍繞「在Nginx添加Home Assistant的配置文件」設定。
配置Home Assistant
Home Assistant預設是限制本機(127.0.0.1)以外的端口轉發,所以需要在Home Assistant的配置文件添加代碼,信任(放行)來自代理IP的標頭(Header)。

Home Assistantconfiguration.yaml配置文件中編輯及添加以下代碼

http:
  # For extra security set this to only accept connections on localhost if NGINX is on the same machine
  # Uncommenting this will mean that you can only reach Home Assistant using the proxy, not directly via IP from other clients.
  # server_host: 127.0.0.1
  use_x_forwarded_for: true
  # You must set the trusted proxy IP address so that Home Assistant will properly accept connections
  # Set this to your NGINX machine IP, or localhost if hosted on the same machine.
  trusted_proxies: <NGINX IP address here, or 127.0.0.1 if hosted on the same machine>
trusted_proxies: 後是允許(信任)的IP地址或者網段 如: 192.168.1.0/24
在Nginx 添加配置文件

/etc/nginx/conf.d/hass.conf

##  WebSocket connection depending on the variable.$http_upgrade
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    # Update this line to be your domain
    server_name example.com;

    # These shouldn't need to be changed
    listen [::]:80 default_server ipv6only=off;
    return 301 https://$host$request_uri;
}

server {
    # Update this line to be your domain
    server_name example.com;

    # Ensure these lines point to your SSL certificate and key
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    # Use these lines instead if you created a self-signed certificate
    # ssl_certificate /etc/nginx/ssl/cert.pem;
    # ssl_certificate_key /etc/nginx/ssl/key.pem;

    # Ensure this line points to your dhparams file
    # ssl_dhparam /etc/nginx/ssl/dhparams.pem;


    # These shouldn't need to be changed
    listen [::]:443 ssl default_server ipv6only=off; # if your nginx version is >= 1.9.5 you can also add the "http2" flag here
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    # ssl on; # Uncomment if you are using nginx < 1.15.0
    ssl_protocols TLSv1.2;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    proxy_buffering off;

    location / {
        proxy_pass http://HomeAssistant_IP:8123;
        proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}
替換內容註釋
server_name example.com域名Domain (URL)
HomeAssistant_IP:8123內網Home Assistant的IP地址 + 端口
fullchain.pemSSL證書 (cert.pem 及 chain.pem 合併檔案)
privkey.pemSSL證書 (申請網域的憑證密鑰)

其中的一段代碼,是NginxWebSocket連接,是Home Assistant配置文件需要用到。

map $http_upgrade $connection_upgrade {  
    default upgrade;
    ''      close;
}

使用以下指令檢查設定檔 hass.conf

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful


結語:
之前一直用的Nginx反向配置出現400 Bad Request錯誤,網上搜索後發現新版本的Home Assistant系統基於安全考量包含一個 WebSocket API而出現的變化。

相關連結:

參考資料:

Reverse proxy using NGINX - Community Guides - Home Assistant Community (home-assistant.io)

nginx — How to Fix Unknown "connection_upgrade" Variable (futurestud.io)