開放 Home Assistant 外部連線的糾結
常常在論壇上看到網友詢問如何安全的存取家中的 Home Assistant,一般常見的作法,如果 ISP(網路服務提供者)有提供固定 IP,那基本上在 router 設定好 port forwarding,連結該外部 IP 位址以及設定的 port 即可存取 Home Assistant 的網頁介面(例如 http://123.123.123.123:8123)。如果是動態/浮動 IP(須為 public IP,也就是可外部存取到的 IP 位址),一般也可以透過 DDNS 動態域名對應的服務讓我們可以透過域名來存取,不用擔心 IP 變動後無法連線,像是 Home Assistant 內就有內建 DuckDNS add-on,很容易的就可以申請到免費的域名並完成自動 IP 更新的動作。
但透過 http:// 未加密的方式輸入帳密存取,帳密在外部網路到家中這段連線過程中經過的主機都可以看到我們傳輸的內容,所以再進階一點我們可以申請 TLS/SSL 安全憑證並建立 https:// 的加密連線,確保我們的帳密在連線過程中不被惡意的第三方擷取。
透過 DuckDNS 與 NGINX Reverse Proxy 建立加密連線的教學
不過如果家中有很多服務想要外部存取,那我們勢必要開很多個 port,要做一堆 port forwarding,想要便於使用搞不好還需要建立一堆域名去對應每個服務… 開越多服務,相對來說就給惡意的第三方越多攻擊的目標,尤其如果使用者本身對網路安全的概念薄弱,開啟的服務又有漏洞,就有可能會讓自己成為被攻擊的對象,或是被當成攻擊別人的跳板。
因此今天我們要來介紹另一種連線的方式,就是透過 VPN(虛擬私人網路)建立一道由外部通往家中的私人通道,讓我們即使不在家中,也能如在家中一樣存取局部網路上的服務及裝置。
關於 VPN(虛擬私人網路)
顧名思義,VPN 可以讓我們在外部公眾網路與家中私有網路之間建立起一個私人通道,即使人在外面也能如同於家中一般存取家中內部網路上的服務。要達成這樣的目的,我們於家中需要建立一個 VPN server,並在要從外部連回的裝置上使用 VPN client 做好對應的設定,才能夠建立 VPN 連線,而有這種功能的 router 通常至少都要中、高價位的產品才會提供,設定上步驟通常也不少。
我們今天要介紹的方案,就是 Home Assistant 標準環境中提供的 WireGuard add-on,這個 add-on 可以讓我們相對容易的在內部網路中建立一個 VPN server,透過在手機或電腦上下載 WireGuard app,我們可以半自動或手動的方式輸入對應的設定參數,即可完成 VPN client 的設置,並透過 WireGuard 建立的 VPN 連線存取內網中的服務。
接下來,就跟著圖文步驟來看看怎麼設定。
設定 WireGuard Add-on
WireGuard 是 Home Assistant Add-on 的標配套件之一,因此直接到 `Supervisor -> Add-on Store` 底下,搜尋 WireGuard 即可找到該套件:
找到後進行安裝,之後到 Configuration 中修改 host 的資訊,這邊可以是外部 IP 或是域名,記得如果可以取得固定 IP 才可輸入 IP 位址,否則就需要使用 DDNS 服務避免 IP 變更後無法連線。“Peers” 的名稱如果想要自訂的話也可以一併修改,在這篇教學我使用預設的 hassio,基本上剩下的設定都可以用預設值,如果有進階設定需求請再參照 WireGuard 以及 add-on 的文件調整:
完成後啟動 WireGuard,我會建議養成一個好習慣看一下 log 有沒有出現什麼需要注意的地方:
基本上在 server 端的設定這樣就完成了。Add-on 會自動產生一組 public/private key,對應的設定參數,以及一個 QR code 條碼圖檔。在手機或平板上下載 WireGuard app 後可以透過 QR code 快速完成設定,或使用設定檔內的參數手動設定。透過內建的 File editor(須先從 Supervisor -> Add-on Store
安裝),瀏覽 /ssl/wireguard/peer_name
資料夾,即可看到剛剛說的那些檔案。“peer_name” 就是剛才設定 WireGuard 時說過可以改的 Peers 的名稱參數,如果使用預設名稱的話,就會是 hassio:
如果你發現你在 File editor
裡無法瀏覽 config/
之前的目錄的話,記得到 File editor
的設定中,將 enforce_basepath
設為 false
。預設參數為 true
,會限制使用者只能瀏覽 config/
底下的資料,避免不小心誤刪重要系統檔案造成問題:
由於要允許裝置能從外網連線到 server,請記得完成上述步驟後,到自己的 router 上設定 port forwarding,WireGuard Add-on 預設使用的是 UDP port 51820,注意是 UDP 而不是 TCP,設定時別選錯了。(將外部的 51820 指向到 Home Assistant IP 的 51820,有改 port 的話就依照自己的設定調整)
基本上 WireGuard Add-on 的設定就到這邊,基本上這是 server 端的部分。接下來我們需要設定 WireGuard client/app 讓裝置於外部時可以連線到 server 來。
設定 WireGuard App
先在手機或平板上下載 WireGuard app,選擇 Add a tunnel
,並選擇 Create from QR code。記得剛才在 WireGuard 資料夾底下的 QR code 圖檔嗎?掃描該圖檔即可自動完成 peer 端的設定:
掃描後可自行定義一個名稱給該設定檔,設定一個方便自己辨識的名稱即可:
像我在 iPhone 或 iPad 上掃描,app 會提示說需要允許建立 VPN 設定,允許後該設定檔將會建立於設定底下的 VPN 欄位內:
接下來可以從 WireGuard app 或是 VPN 選單中啟用此連線,就可以連到 WireGuard server。預設的設定會允許你存取 Home Assistant 所在的網段,可以看到下圖中,手機是使用 5G 上網,但是我在瀏覽器上輸入家中實驗環境的 HA 內部 IP 也能存取網頁介面。其他像是 UniFi Controller、router 或是其他位於該網段的裝置都可以存取的到,如同我於家中一般:
那如果我是電腦要設定不能用 QR code 怎麼辦呢?記得剛才用 File editor 瀏覽 WireGuard 資料夾內有個 client.conf 檔案嗎?一個方式是下載那個 client.conf 檔案並匯入到 WireGuard 的桌面程式中,或是依照畫面上的提示輸入該檔案內對應欄位的內容,即可手動建立一個連線設定。
如果你的 router 本身有提供 VPN server 的功能的話,個人還是會建議使用 router 本身的,這樣如果 HA 出問題時才不會連帶喪失存取內網的功能,不過有些效能較差的 router 內建的 VPN server 往往也不是太穩定,因此可以加設 WireGuard,平時用 WireGuard,出問題再用 router 的當作備援方案,也是一種應用方式。
其實自己在不少 router 上設定過各種不同類型的 VPN servers,但 HA 上的 WireGuard add-on 差不多是最容易設定的之一了,有這方面需求的朋友不妨試試看。