上篇文章給大家介紹瞭如何使用 wg-gen-web 來方便快捷地管理 WireGuard 的配置和祕鑰,文末埋了兩個坑:一個是 WireGuard
的全互聯模式(full mesh),另一個是使用 WireGuard 作為 Kubernetes
的 CNI 外掛。今天就來填第一個坑。
首先解釋一下什麼是全互聯模式(full mesh),全互聯模式其實就是一種網路連線形式,即所有結點之間都直接連線,不會通過第三方節點中轉流量。和前面提到的點對多點架構 其實是一個意思。
1. 全互聯模式架構與配置
在 WireGuard 的世界裡沒有 Server 和 Client 之分,所有的節點都是 Peer
。大家使用 WireGuard 的常規做法是找一個節點作為中轉節點,也就是 VPN 閘道器,然後所有的節點都和這個閘道器進行連線,所有節點之間都通過這個閘道器來進行通訊。這種架構中,為了方便理解,我們可以把閘道器看成 Server,其他的節點看成 Client,但實際上是不區分 Server 和 Client 的。
舉個例子,假設有 4
個節點,分別是 A/B/C/D,且這 4 個節點都不在同一個區域網,常規的做法是選取一個節點作為 VPN 閘道器,架構如圖:
這種架構的缺點我在之前的文章裡也介紹過了,缺點相當明顯:
- 當 Peer 越來越多時,VPN 閘道器就會變成垂直擴充套件的瓶頸。
- 通過 VPN 閘道器轉發流量的成本很高,畢竟雲伺服器的流量很貴。
- 通過 VPN 閘道器轉發流量會帶來很高的延遲。
那麼全互聯模式是什麼樣的架構呢?還是假設有 A/B/C/D 四個節點,每個節點都和其他節點建立 WireGuard 隧道,架構如圖:
這種架構帶來的直接優勢就是快!任意一個 Peer 和其他所有 Peer 都是直連,無需中轉流量。那麼在 WireGuard 的場景下如何實現全互聯模式呢?其實這個問題不難,難點在於配置的繁瑣程度,本文的主要目標就是精簡 WireGuard 全互聯模式的配置流程。為了讓大家更容易理解,我們們還是先通過架構圖來體現各個 Peer 的配置:
配置一目瞭然,每個 Peer 和其他所有 Peer 都是直連,根本沒有 VPN 閘道器這種角色。當然,現實世界的狀況沒有圖中這麼簡單,有些 Peer 是沒有公網 IP 的,躲在 NAT 後面,這裡又分兩種情況:
- NAT 受自己控制。這種情況可以在公網出口設定埠轉發,其他 Peer 就可以通過這個公網 IP 和埠連線當前 Peer。如果公網 IP 是動態的,可以通過 DDNS 來解決,但 DDNS 會出現一些小問題,解決方法可以參考 WireGuard 的優化。
- NAT 不受自己控制。這種情況無法在公網出口設定埠轉發,只能通過 UDP 打洞來實現互聯,具體可以參考 WireGuard 教程:使用 DNS-SD 進行 NAT-to-NAT 穿透。
接著上述方案再更進一步,打通所有 Peer 的私有網段,讓任意一個 Peer 可以訪問其他所有 Peer 的私有網段的機器。上述配置只是初步完成了全互聯,讓每個 Peer 可以相互訪問彼此而已,要想相互訪問私有網段,還得繼續增加配置,還是直接看圖:
紅色字型部分就是新增的配置,表示允許訪問相應 Peer 的私有網段,就是這麼簡單。詳細的配置步驟請看下一節。
2. 全互聯模式最佳實踐
對如何配置有了清晰的思路之後,接下來就可以進入實踐環節了。我不打算從 WireGuard 安裝開始講起,而是以前幾篇文章為基礎添磚加瓦。所以我建議讀者先按順序看下這兩篇文章:
我們們直接從配置開始說起。手擼配置的做法是不明智的,因為當節點增多之後工作量會很大,我還是建議通過圖形化介面來管理配置,首選 wg-gen-web。
現在還是假設有上節所述的 4 個 Peer,我們需要從中挑選一個 Peer 來安裝 wg-gen-web
,然後通過 wg-gen-web
來生成配置。挑選哪個 Peer 無所謂,這個沒有特殊限制,這裡假設挑選 AWS
來安裝 wg-gen-web
。
安裝的步驟直接略過,不是本文的重點,不清楚的可以閱讀我之前的文章 WireGuard 配置教程:使用 wg-gen-web 來管理 WireGuard 的配置。Server 配置如圖:
生成 Azure
的配置:
SUBMIT 之後再檢視 wg0.conf
的內容:
$ cat /etc/wireguard/wg0.conf
# Updated: 2021-02-24 07:34:23.805535396 +0000 UTC / Created: 2021-02-24 07:24:02.208816462 +0000 UTC
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = eEnHKGkGksx0jqrEDogjRj5l417BrEA39lr7WW9L9U0=
PreUp = echo WireGuard PreUp
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -I INPUT -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PreDown = echo WireGuard PreDown
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -D INPUT -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Azure / / Updated: 2021-02-24 07:43:52.717385042 +0000 UTC / Created: 2021-02-24 07:43:52.717385042 +0000 UTC
[Peer]
PublicKey = OzdH42suuOpVY5wxPrxM+rEAyEPFg2eL0ZI29N7eSTY=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.2/32
這裡無法通過圖形化介面新增私有網段的配置,我們可以直接修改 wg0.conf
新增配置:
$ cat /etc/wireguard/wg0.conf
# Updated: 2021-02-24 07:34:23.805535396 +0000 UTC / Created: 2021-02-24 07:24:02.208816462 +0000 UTC
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = eEnHKGkGksx0jqrEDogjRj5l417BrEA39lr7WW9L9U0=
PreUp = echo WireGuard PreUp
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -I INPUT -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PreDown = echo WireGuard PreDown
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -D INPUT -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Azure / / Updated: 2021-02-24 07:43:52.717385042 +0000 UTC / Created: 2021-02-24 07:43:52.717385042 +0000 UTC
[Peer]
PublicKey = OzdH42suuOpVY5wxPrxM+rEAyEPFg2eL0ZI29N7eSTY=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.2/32
AllowedIPs = 192.168.20.0/24
下載 Azure 配置檔案:
可以看到配置檔案內容為:
$ cat Azure.conf
[Interface]
Address = 10.0.0.2/32
PrivateKey = IFhAyIWY7sZmabsqDDESj9fqoniE/uZFNIvAfYHjN2o=
[Peer]
PublicKey = JgvmQFmhUtUoS3xFMFwEgP3L1Wnd8hJc3laJ90Gwzko=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.1/32, 192.168.10.0/24
Endpoint = aws.com:51820
先不急著修改,一鼓作氣生成所有 Peer 的配置檔案:
這時你會發現 wg0.conf
中已經包含了所有 Peer 的配置:
$ cat /etc/wireguard/wg0.conf
# Updated: 2021-02-24 07:57:00.745287945 +0000 UTC / Created: 2021-02-24 07:24:02.208816462 +0000 UTC
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = eEnHKGkGksx0jqrEDogjRj5l417BrEA39lr7WW9L9U0=
PreUp = echo WireGuard PreUp
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -I INPUT -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PreDown = echo WireGuard PreDown
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -D INPUT -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Aliyun / / Updated: 2021-02-24 07:57:45.941019829 +0000 UTC / Created: 2021-02-24 07:57:45.941019829 +0000 UTC
[Peer]
PublicKey = kVq2ATMTckCKEJFF4TM3QYibxzlh+b9CV4GZ4meQYAo=
PresharedKey = v818B5etpRlyVYHGUrv9abM5AIQK5xeoCizdWj1AqcE=
AllowedIPs = 10.0.0.4/32
# GCP / / Updated: 2021-02-24 07:57:27.3555646 +0000 UTC / Created: 2021-02-24 07:57:27.3555646 +0000 UTC
[Peer]
PublicKey = qn0Xfyzs6bLKgKcfXwcSt91DUxSbtATDIfe4xwsnsGg=
PresharedKey = T5UsVvOEYwfMJQDJudC2ryKeCpnO3RV8GFMoi76ayyI=
AllowedIPs = 10.0.0.3/32
# Azure / / Updated: 2021-02-24 07:57:00.751653134 +0000 UTC / Created: 2021-02-24 07:43:52.717385042 +0000 UTC
[Peer]
PublicKey = OzdH42suuOpVY5wxPrxM+rEAyEPFg2eL0ZI29N7eSTY=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.2/32
AllowedIPs = 192.168.20.0/24
繼續修改 wg0.conf
新增私有網段配置:
cat /etc/wireguard/wg0.conf
# Updated: 2021-02-24 07:57:00.745287945 +0000 UTC / Created: 2021-02-24 07:24:02.208816462 +0000 UTC
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = eEnHKGkGksx0jqrEDogjRj5l417BrEA39lr7WW9L9U0=
PreUp = echo WireGuard PreUp
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -I INPUT -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PreDown = echo WireGuard PreDown
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -D INPUT -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Aliyun / / Updated: 2021-02-24 07:57:45.941019829 +0000 UTC / Created: 2021-02-24 07:57:45.941019829 +0000 UTC
[Peer]
PublicKey = kVq2ATMTckCKEJFF4TM3QYibxzlh+b9CV4GZ4meQYAo=
PresharedKey = v818B5etpRlyVYHGUrv9abM5AIQK5xeoCizdWj1AqcE=
AllowedIPs = 10.0.0.4/32
AllowedIPs = 192.168.40.0/24
# GCP / / Updated: 2021-02-24 07:57:27.3555646 +0000 UTC / Created: 2021-02-24 07:57:27.3555646 +0000 UTC
[Peer]
PublicKey = qn0Xfyzs6bLKgKcfXwcSt91DUxSbtATDIfe4xwsnsGg=
PresharedKey = T5UsVvOEYwfMJQDJudC2ryKeCpnO3RV8GFMoi76ayyI=
AllowedIPs = 10.0.0.3/32
AllowedIPs = 192.168.30.0/24
# Azure / / Updated: 2021-02-24 07:57:00.751653134 +0000 UTC / Created: 2021-02-24 07:43:52.717385042 +0000 UTC
[Peer]
PublicKey = OzdH42suuOpVY5wxPrxM+rEAyEPFg2eL0ZI29N7eSTY=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.2/32
AllowedIPs = 192.168.20.0/24
現在問題就好辦了,我們只需將 wg0.conf 中的 Aliyun 和 GCP 部分的配置拷貝到 Azure 的配置中,並刪除 PresharedKey 的配置,再新增 Endpoint 的配置和 PostUP/PostDown 規則:
$ cat Azure.conf
[Interface]
Address = 10.0.0.2/32
PrivateKey = IFhAyIWY7sZmabsqDDESj9fqoniE/uZFNIvAfYHjN2o=
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -I INPUT -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -D INPUT -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = JgvmQFmhUtUoS3xFMFwEgP3L1Wnd8hJc3laJ90Gwzko=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.1/32, 192.168.10.0/24
Endpoint = aws.com:51820
# Aliyun / / Updated: 2021-02-24 07:57:45.941019829 +0000 UTC / Created: 2021-02-24 07:57:45.941019829 +0000 UTC
[Peer]
PublicKey = kVq2ATMTckCKEJFF4TM3QYibxzlh+b9CV4GZ4meQYAo=
AllowedIPs = 10.0.0.4/32
AllowedIPs = 192.168.40.0/24
Endpoint = aliyun.com:51820
# GCP / / Updated: 2021-02-24 07:57:27.3555646 +0000 UTC / Created: 2021-02-24 07:57:27.3555646 +0000 UTC
[Peer]
PublicKey = qn0Xfyzs6bLKgKcfXwcSt91DUxSbtATDIfe4xwsnsGg=
AllowedIPs = 10.0.0.3/32
AllowedIPs = 192.168.30.0/24
Endpoint = gcp.com:51820
同理,GCP 的配置如下:
$ cat GCP.conf
[Interface]
Address = 10.0.0.3/32
PrivateKey = oK2gIMBAob67Amj2gT+wR9pzkbqWGNtq794nOoD3i2o=
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -I INPUT -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -D INPUT -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = JgvmQFmhUtUoS3xFMFwEgP3L1Wnd8hJc3laJ90Gwzko=
PresharedKey = T5UsVvOEYwfMJQDJudC2ryKeCpnO3RV8GFMoi76ayyI=
AllowedIPs = 10.0.0.1/32, 192.168.10.0/24
Endpoint = aws.com:51820
# Aliyun / / Updated: 2021-02-24 07:57:45.941019829 +0000 UTC / Created: 2021-02-24 07:57:45.941019829 +0000 UTC
[Peer]
PublicKey = kVq2ATMTckCKEJFF4TM3QYibxzlh+b9CV4GZ4meQYAo=
AllowedIPs = 10.0.0.4/32
AllowedIPs = 192.168.40.0/24
Endpoint = aliyun.com:51820
# Azure / / Updated: 2021-02-24 07:57:00.751653134 +0000 UTC / Created: 2021-02-24 07:43:52.717385042 +0000 UTC
[Peer]
PublicKey = OzdH42suuOpVY5wxPrxM+rEAyEPFg2eL0ZI29N7eSTY=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.2/32
AllowedIPs = 192.168.20.0/24
Endpoint = azure.com:51820
Aliyun 的配置如下:
$ cat Aliyun.conf
[Interface]
Address = 10.0.0.4/32
PrivateKey = +A1ZESJjmHuskB4yKqTcqC3CB24TwBKHGSffWDHxI28=
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -j ACCEPT; iptables -I INPUT -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -D INPUT -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = JgvmQFmhUtUoS3xFMFwEgP3L1Wnd8hJc3laJ90Gwzko=
PresharedKey = v818B5etpRlyVYHGUrv9abM5AIQK5xeoCizdWj1AqcE=
AllowedIPs = 10.0.0.1/32, 192.168.10.0/24
Endpoint = aws.com:51820
# GCP / / Updated: 2021-02-24 07:57:27.3555646 +0000 UTC / Created: 2021-02-24 07:57:27.3555646 +0000 UTC
[Peer]
PublicKey = qn0Xfyzs6bLKgKcfXwcSt91DUxSbtATDIfe4xwsnsGg=
AllowedIPs = 10.0.0.3/32
AllowedIPs = 192.168.30.0/24
Endpoint = gcp.com:51820
# Azure / / Updated: 2021-02-24 07:57:00.751653134 +0000 UTC / Created: 2021-02-24 07:43:52.717385042 +0000 UTC
[Peer]
PublicKey = OzdH42suuOpVY5wxPrxM+rEAyEPFg2eL0ZI29N7eSTY=
PresharedKey = 1SyJuVp16Puh8Spyl81EgD9PJZGoTLJ2mOccs2UWDvs=
AllowedIPs = 10.0.0.2/32
AllowedIPs = 192.168.20.0/24
Endpoint = azure.com:51820
最後在各自的節點上通過各自的配置檔案把 WireGuard 跑起來,就搞定了。
整個圖形化介面配置過程中會出現好幾個地方需要手動調整配置,這是因為 wg-gen-web
的功能目前還不完善,需要給它一定的時間。如果你無法接受手動調整配置,可以嘗試另外一個專案:wg-meshconf,這個專案專門用來生成 mesh 的配置,但沒有圖形化管理介面。各有利弊吧,大家自行選擇。
3. 總結
我知道,很多人可能還是一頭霧水,這玩意兒的應用場景有哪些?我隨便舉個簡單的例子,假設你在雲伺服器上部署了 Kubernetes 叢集,可以用本地的機器和雲伺服器的某臺節點組建 WireGuard 隧道,然後在本地的 AllowedIPs
中加上 Pod 網段和 Service 網段,就可以那啥了,你懂吧?
好吧,又埋了一個坑,關於如何在家中直接訪問雲伺服器 k8s 叢集的 Pod IP 和 Service IP,後面會有專門的文章給大家講解,雖然我也不確定是多久以後。。
Kubernetes 1.18.2 1.17.5 1.16.9 1.15.12離線安裝包釋出地址http://store.lameleg.com ,歡迎體驗。 使用了最新的sealos v3.3.6版本。 作了主機名解析配置優化,lvscare 掛載/lib/module解決開機啟動ipvs載入問題, 修復lvscare社群netlink與3.10核心不相容問題,sealos生成百年證書等特性。更多特性 https://github.com/fanux/sealos 。歡迎掃描下方的二維碼加入釘釘群 ,釘釘群已經整合sealos的機器人實時可以看到sealos的動態。