在 Freshtomato 和 OpenWRT 之間使用 Tinc VPN 建立 L3 VPN,實現區域網路互通
我平常使用的路由器是 arm 架構的,上面裝 Freshtomato 韌體,連到我的伺服器之間是用 WireGuard,但是手邊另一台路由器架構是 mips,對應的 Freshtomato 原始碼不包含 WireGuard,至於為什麼不包含我還沒仔細研究是哪部分使得這個架構沒有包含 WireGuard,但是有 Tinc 我就先用了 Tinc。
這邊的拓樸是讓 OpenWRT 有公開的 IP 位址作為大家的入口。
| 設定 | 內容 |
|---|---|
| 介面名稱 | tinc_vpn1 |
| 節點名稱 | openwrt |
| LAN IP | 192.168.140.1/24 |
| WAN IP | 111.111.111.111 |
| 設定 | 內容 |
|---|---|
| 介面名稱 | tinc(固定) |
| 節點名稱 | freshtomato |
| LAN IP | 192.168.150.1/24 |
參考 官方文件 設定
opkg update
opkg install tinc
mkdir -p /etc/tinc/tinc_vpn1
tinc -n tinc_vpn1 generate-ed25519-keys < /dev/null
如果不跟舊版節點連線的話就不用生 RSA 金鑰。
公私鑰對存在 /etc/tinc/tinc_vpn1/ed25519_key.{pub|priv}
變數 VPN_SPUB 是伺服器 ed25519 公鑰不含 Ed25519PublicKey = 這段,VPN_CPUB 是客戶(這裡是 Freshtomato 節點)公鑰不含 Ed25519PublicKey = 這段。
VPN_IF=tinc_vpn1
SELF_NODENAME=openwrt
CLIENT_NODENAME=freshtomato
uci -q delete tinc.${VPN_IF}
uci set tinc.${VPN_IF}="tinc-net"
uci set tinc.${VPN_IF}.enabled="1"
uci set tinc.${VPN_IF}.Interface="${VPN_IF}"
uci set tinc.${VPN_IF}.Name="${SELF_NODENAME}"
uci -q delete tinc.${SELF_NODENAME}
uci set tinc.${SELF_NODENAME}="tinc-host"
uci set tinc.${SELF_NODENAME}.enabled="1"
uci set tinc.${SELF_NODENAME}.net="${VPN_IF}"
uci set tinc.${SELF_NODENAME}.Name="${SELF_NODENAME}"
uci set tinc.${SELF_NODENAME}.PublicKey="1"
uci set tinc.${SELF_NODENAME}.Ed25519PublicKey="${VPN_SPUB}"
uci add_list tinc.${SELF_NODENAME}.Subnet="192.168.140.0/24"
uci -q delete tinc.${CLIENT_NODENAME}
uci set tinc.${CLIENT_NODENAME}="tinc-host"
uci set tinc.${CLIENT_NODENAME}.enabled="1"
uci set tinc.${CLIENT_NODENAME}.net="${VPN_IF}"
uci set tinc.${CLIENT_NODENAME}.Name="${CLIENT_NODENAME}"
uci set tinc.${CLIENT_NODENAME}.PublicKey="1"
uci set tinc.${CLIENT_NODENAME}.Ed25519PublicKey="${VPN_CPUB}"
uci add_list tinc.${CLIENT_NODENAME}.Subnet="192.168.150.0/24"
uci commit tinc
service tinc restart
uci -q delete network.${VPN_IF}
uci set network.${VPN_IF}="interface"
uci set network.${VPN_IF}.proto="static"
uci set network.${VPN_IF}.ipaddr="192.168.140.2"
uci set network.${VPN_IF}$.netmask='255.255.0.0'
uci set network.${VPN_IF}.device="${VPN_IF}"
uci commit network
service network restart
此處的 IP 位址設定需要是自己 LAN 區段的某個空位址,因為 Freshtomato 的路由表是照自己 IP 套介面的 Subnet mask 建立的,Tinc 自己的路由是照 Hosts 的 Subnet 跑的,如果設定一個 VPN 介面用的虛擬位址,會讓 openwrt 進去 freshtomato 的封包 src 是不屬於 openwrt 的 Subnet,回程就會回不來。
設定 netmask 是要讓沒有其他路由規則的 192.168.0.0/16 往 tinc_vpn1 走,有點簡略粗暴,正常應該要是把每個 Edge 的 Subnet 用白名單加進路由表,但是這就是一個假設 192.168.0.0/16 都要往 Tinc mesh 走的設定方式。
照自己偏好的方式確定 tinc_vpn1 可以跟 Lan 互相 Forward 就好。
參考 官方文件 設定。
在 GUI 中找到 VPN/Tinc,在 Generate Keys 裡面生成金鑰對,然後複製 ed25519 的公私鑰起來。
我這次要用的是 Router mode,所以 Interface Type 選 TUN。
| 設定名稱 | 值 |
|---|---|
| Enable on Start | True |
| Poll Interval | 1 |
| Interface Type | TUN |
| VPN Netmask | 255.255.0.0 |
| Host Name | freshtomato |
| Ed25519 Private Key | 貼上剛才生成的私鑰 |
在 Hosts 列表中也需要加上自己的節點資訊,以提供 Mesh 交換。
| Connect To | Name | Address | Port | Compression | Subnet |
|---|---|---|---|---|---|
| False | freshtomato | 0 | 192.168.150.0/24 | ||
| True | openwrt | 111.111.111.111 | 655 | 0 | 192.168.140.0/24 |
每個節點要填上 ed25519 public key,需要包含 Ed25519PublicKey = 這段。
互相 ping 對面區域網路,有通就成了。
我剛設定完有踩到 OpenWRT 那裏沒有自動建立路由表的坑,還有官方教學裡面設定給介面卡的 IP 不在其他節點 Subnet 的坑,都在上面的設定裡面補上了,雖然不確定是不是正解,但我認為是正確的。
接下來我也試過加上第二台 Freshtomato 機器,Hosts 只設定自己跟 openwrt,在連上之後也有成功學到第一台 Freshtomato 的路徑。
Keyboard Shortcuts
| Command | Function |
|---|---|
| ? (Shift+/) | Bring up this help modal |
| g+h | Go to Home |
| g+p | Go to Posts |
| g+e | Open Editor page on GitHub in a new tab |
| g+s | Open Source page on GitHub in a new tab |
| r | Reload page |