前言
繼上次玩 OpenWrt 的第三篇,這次是設定 WireGuard VPN,我查了不少文章,感覺很少人遇到我這問題,我覺得應該是我的網路配置的關係,在這邊分享踩坑經驗出來。
如果你的網路配置比較單純的話,不需要做太多設定,我是比較特殊一點,搞了很複雜的網路環境。
網路環境
首先介紹我家網路配置,多了交換機後有點複雜,下圖現實接線的示意圖,圖中的顏色用以區分網段,而粗細用以區分層級。

目前會想這樣設計,主要是想要隔離我家人與我的網路環境,讓他們干擾不到我,其實一台交換機就夠了。
不過交換機可沒有強大的防火牆阿,軟路由的防火牆才是真的強大。而且只有軟路由才可以辦得到我這複雜的需求。
下面一張圖是化簡後的網路布局,把交換器拔掉(實際上是接著的)的虛擬網路圖。

ASUS 硬路由在這邊是一級路由,而軟路由則是二級路由,透過軟路由的虛擬區網,已經做到兩個區域網路各自隔離(LAN 藍色、LAN2 紅色)。
目的
我的主要目的是想要我常用的電腦,也就是 LAN(藍色),加上 VPN,使我連線到公網是走 NordVPN 的路線。
不過這步有點小麻煩,因為 NordVPN 並沒有提供 WireGuard 的金鑰,但你還是有機會可以實現。
取得 NordVPN 的連線資訊
第一步,先在 Linux 環境中安裝工具包以及 NordVPN。
sudo apt install wireguard curl jq net-tools
sh <(curl -sSf https://downloads.nordcdn.com/apps/linux/install.sh)
第二步,連線到 NordVPN。
# 登入 NordVPN
sudo nordvpn login
# 設定協議
sudo nordvpn set technology nordlynx
# 連線
sudo nordvpn c
第三步,取得金鑰(公鑰與私鑰)。
# 顯示私鑰
sudo wg show nordlynx private-key
# 顯示公鑰 與 伺服器資訊
curl -s "https://api.nordvpn.com/v1/servers/recommendations?&filters\[servers_technologies\]\[identifier\]=wireguard_udp&limit=1"|jq -r '.[]|.hostname, .station, (.locations|.[]|.country|.city.name), (.locations|.[]|.country|.name), (.technologies|.[].metadata|.[].value), .load'

上圖是我在 Kali Linux 中輸入指令的示意圖。
最後記得要中斷 NordVPN 的連線。
sudo nordvpn d
設置 OpenWrt
如果你的 OpenWrt 還不支援 WireGuard,請先安裝。
opkg install kmod-wireguard luci-app-wireguard luci-proto-wireguard wireguard wireguard-tools
設置 WireGuard
如果前面都沒問題,這裡就是關鍵步驟了。還記得先前拿到的私鑰和公鑰嗎?
第一步,開啟 OpenWrt 接口畫面 (Interface)。

第二步,添加新的接口,通常取名為為 wg0。按照你習慣設定即可。選好協議 WireGuard VPN 點添加。

第三步,一般設定中,填入你剛剛取得的私鑰,不要點到「生成密鑰」。
IP 地址,就從你剛剛連線 NordVPN 的介面卡中取得(ifconfig)。
設定好後,就可以開啟下個介面,對端 (EndPoint),我一直覺得這翻譯很怪,總之就是遠端 Server 的意思,路由器本身當 Client 端連上 遠端 VPN Server。

第四步,填入剛剛取得的公鑰,允許的 IP 輸入 0.0.0.0/0 。
路由允許的 IP 這裡是一個大坑,如果你的網路環境很單純,直接打勾就可以了。這邊我暫時不打勾,因為我要自己設定路由。
如果你的軟路由是二級路由器,也不應該打勾,因為你會到不了 Gateway ,0.0.0.0/0 會路由你的 Gateway 地址,導致迴圈,封包出不去外網,至少我這邊的情況是這樣。
端點主機就填入 NordVPN 的主機位置。
端口保持預設值 51820,Keep-Alive 設定 25。
設定到這邊,VPN 的部分基本上就完工了!如果沒有生效,請重新開機。只要有動到路由表,建議都重新啟動軟路由會比較好。
路由表設定
# 新增路由表300,設定 wg0 路由 0.0.0.0/0
uci add network route
uci set network.@route[-1].interface="wg0"
uci set network.@route[-1].target="0.0.0.0"
uci set network.@route[-1].netmask="0.0.0.0"
uci set network.@route[-1].table="300"
# 新增 IP 網路規則,LAN 接口查詢路由表300
uci add network rule
uci set network.@rule[-1].in="lan"
uci set network.@rule[-1].lookup="300"
# 儲存網路規則 並 重啟網路
uci commit network
/etc/init.d/network restart
防火牆設定
首先一般情況,應該設定 lan 可以轉發到 wan 以及 wg0,如下圖。

到這裡,就算是完工了。但如果你要設定 Kill-Switch,就必須要把 wan 移出允許轉發到的目標區域。
設定防火牆 Kill-Switch (選)

要開啟 Kill-Switch 就必須把 lan 轉發到 wan 的選項移除掉,只能轉發到 wg0,這樣 lan 不走 VPN 就永遠到不了外網。

這是示意圖,直接把 LAN 到 WAN 的路由,用防火牆轉發規則擋掉,這樣 LAN 就出不去。
檢查
現在的 IP 應該是剛剛設定的 VPN Server 的 IP,如果不是,代表你某步驟做錯。


如果你有開啟 Kill-Switch,可以連上 wan 確認 Kill-Switch 有沒有工作。在這裡我的 WAN 是 192.168.0.1 (一級路由)。
或是你可以停止 wg0 接口,當 wg0 接口被切斷,那你會默認轉發到 wan,如果你可以成功上網,而且 IP 是你原本的真實 IP,那麼代表你 Kill-Switch 沒有設定成功。

測速
到了最令人振奮的時刻,軟路由進行對岸所謂的「科學上網」,最重要的就是性能了,根據你的軟路由 CPU 的好壞,可以決定你的網速可以跑到多快。
聽說 x86 CPU 是很不錯的,所以我也選擇了 Intel 的 J4125。
下面是我的測速結果:兩次測速,下載約 470 Mbps、上傳約 74 Mbps。


如果沒有連線 wg0,使用 wan 接口上網,(無 VPN)的結果如下,大概是直接跑滿目前申裝的網路,500 Mbps 上/下傳 。

參考資料:
https://www.ivpn.net/setup/router/openwrt-wireguard/
https://hiy.tw/2021/06/nordvpn_wireguard/
其他文章:
軟路由初體驗 在 PVE 8.0 上安裝 OpenWrt 22.03
使用 OpenWrt 踩坑經驗與心得 設置虛擬區域網路進行隔離
在 OpenWrt 設定 WireGuard VPN 白名單繞過本地網路 並且維持 Kill Switch 開啟

WeilsNetLogo