Wireguard 全互聯模式(full mesh)配置指南

上篇文章給大家介紹瞭如何使用 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 後面,這裏又分兩種情況:

  1. NAT 受自己控制。這種情況可以在公網出口設置端口轉發,其他 Peer 就可以通過這個公網 IP 和端口連接當前 Peer。如果公網 IP 是動態的,可以通過 DDNS 來解決,但 DDNS 會出現一些小問題,解決方法可以參考 WireGuard 的優化
  2. 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的動態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章