让Home Assistant支持外网访问
1. 背景
Home Assistant是一个布署于家庭局域网的智能家居中枢,可以在家庭网中使用其管理页面http://<ip>:<port>来登录。
但Home Assistant的网页端和手机客户端默认是不支持外网访问的,就算配置了NAT端口转发,还是使用CDN方式(如Cloudflare Tunnel)做反向代理到公网,都是无法从公网连接。究其原因是Home Assistant会检查是否从内网地址访问,如果不是,那么会强制要求https方式连接并且会检查TLS证书是否有效。
2. 解决方法
2.1. 购买Home Assistant Cloud
在手机客户端或网页端连接页面处注册Nabu Casa帐号并订阅Home Assistant Cloud(第一个月免费),订阅后会得到了一个外网URL,用它填入连接设置中的外网URL,即可连接成功。
Home Assistant Cloud的本质是给你一个带TLS证书的https反向代理地址,零配置就可以使用,但收费。
2.2. 使用自己的域名和TLS证书
使用自己的域名指向Home Assistant的NAT外网地址或CDN地址,购买此域名的TLS证书,将证书路径放入configuration.yaml的http配置段中,如下:
1
2
3
4
5
http:
server_port: 8123
ssl_certificate: /ssl/fullchain.pem
ssl_key: /ssl/privkey.pem
然后使用证书对应的域名访问即可。
此方式需要一定的配置工作,需要自己申请证书,比较适合自己的域名已经有证书的情况。
2.3. 使用X-Forwarded-For扩展头部
此方式最简单,适合使用CDN反向代理来加速网站的情况,先说如何做:
a) 配置configuration.yaml
在configuration.yaml中的http配置段加入use_x_forwarded_for: true以及CDN反向代理的连接地址范围
1
2
3
4
http:
use_x_forwarded_for: true
trusted_proxies:
- 10.0.3.0/24
b) 配置域名使用CDN加速
配置Tunnel指向Home Assistant的内网访问地址,域名配置使用CDN加速方式访问Tunnel。
c) 使用域名访问
网页端使用https://<domain-name>:<port>访问。
手机客户端在外部URL处填入https://<domain-name>:<port>,确认连接。

总结
X-Forwarded-For是一个HTTP扩展头部。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由Squid这个缓存代理软件引入,用来表示HTTP请求端真实IP。 由于Cloudflare等CDN的Tunnel可以开启客户端https证书,这时候就可以用它来通过Home Assistant的检查了。