上篇文章給大家介紹了如何使用 wg-gen-web 來方便快捷地管理 WireGuard 的配置和秘鑰谷醉,文末埋了兩個坑:一個是 WireGuard
的全互聯(lián)模式(full mesh)嗦随,另一個是使用 WireGuard 作為 Kubernetes
的 CNI 插件。今天就來填第一個坑皂林。
首先解釋一下什么是全互聯(lián)模式(full mesh)义图,全互聯(lián)模式其實就是一種網(wǎng)絡(luò)連接形式浅乔,即所有結(jié)點之間都直接連接大咱,不會通過第三方節(jié)點中轉(zhuǎn)流量咆霜。和前面提到的點對多點架構(gòu) 其實是一個意思。
1. 全互聯(lián)模式架構(gòu)與配置
在 WireGuard 的世界里沒有 Server 和 Client 之分轿塔,所有的節(jié)點都是 Peer
特愿。大家使用 WireGuard 的常規(guī)做法是找一個節(jié)點作為中轉(zhuǎn)節(jié)點,也就是 VPN 網(wǎng)關(guān)勾缭,然后所有的節(jié)點都和這個網(wǎng)關(guān)進行連接揍障,所有節(jié)點之間都通過這個網(wǎng)關(guān)來進行通信。這種架構(gòu)中俩由,為了方便理解毒嫡,我們可以把網(wǎng)關(guān)看成 Server,其他的節(jié)點看成 Client幻梯,但實際上是不區(qū)分 Server 和 Client 的兜畸。
舉個例子努释,假設(shè)有 4
個節(jié)點,分別是 A/B/C/D咬摇,且這 4 個節(jié)點都不在同一個局域網(wǎng)洽洁,常規(guī)的做法是選取一個節(jié)點作為 VPN 網(wǎng)關(guān),架構(gòu)如圖:
這種架構(gòu)的缺點我在之前的文章里也介紹過了菲嘴,缺點相當(dāng)明顯:
- 當(dāng) Peer 越來越多時饿自,VPN 網(wǎng)關(guān)就會變成垂直擴展的瓶頸。
- 通過 VPN 網(wǎng)關(guān)轉(zhuǎn)發(fā)流量的成本很高龄坪,畢竟云服務(wù)器的流量很貴昭雌。
- 通過 VPN 網(wǎng)關(guān)轉(zhuǎn)發(fā)流量會帶來很高的延遲。
那么全互聯(lián)模式是什么樣的架構(gòu)呢健田?還是假設(shè)有 A/B/C/D 四個節(jié)點烛卧,每個節(jié)點都和其他節(jié)點建立 WireGuard 隧道,架構(gòu)如圖:
這種架構(gòu)帶來的直接優(yōu)勢就是快妓局!任意一個 Peer 和其他所有 Peer 都是直連总放,無需中轉(zhuǎn)流量。那么在 WireGuard 的場景下如何實現(xiàn)全互聯(lián)模式呢好爬?其實這個問題不難局雄,難點在于配置的繁瑣程度,本文的主要目標(biāo)就是精簡 WireGuard 全互聯(lián)模式的配置流程存炮。為了讓大家更容易理解炬搭,咱們還是先通過架構(gòu)圖來體現(xiàn)各個 Peer 的配置:
配置一目了然,每個 Peer 和其他所有 Peer 都是直連穆桂,根本沒有 VPN 網(wǎng)關(guān)這種角色宫盔。當(dāng)然,現(xiàn)實世界的狀況沒有圖中這么簡單享完,有些 Peer 是沒有公網(wǎng) IP 的灼芭,躲在 NAT 后面,這里又分兩種情況:
- NAT 受自己控制般又。這種情況可以在公網(wǎng)出口設(shè)置端口轉(zhuǎn)發(fā)彼绷,其他 Peer 就可以通過這個公網(wǎng) IP 和端口連接當(dāng)前 Peer。如果公網(wǎng) IP 是動態(tài)的倒源,可以通過 DDNS 來解決苛预,但 DDNS 會出現(xiàn)一些小問題,解決方法可以參考 WireGuard 的優(yōu)化笋熬。
- NAT 不受自己控制热某。這種情況無法在公網(wǎng)出口設(shè)置端口轉(zhuǎn)發(fā),只能通過 UDP 打洞來實現(xiàn)互聯(lián),具體可以參考 WireGuard 教程:使用 DNS-SD 進行 NAT-to-NAT 穿透昔馋。
接著上述方案再更進一步筹吐,打通所有 Peer 的私有網(wǎng)段,讓任意一個 Peer 可以訪問其他所有 Peer 的私有網(wǎng)段的機器秘遏。上述配置只是初步完成了全互聯(lián)丘薛,讓每個 Peer 可以相互訪問彼此而已,要想相互訪問私有網(wǎng)段邦危,還得繼續(xù)增加配置洋侨,還是直接看圖:
紅色字體部分就是新增的配置,表示允許訪問相應(yīng) Peer 的私有網(wǎng)段倦蚪,就是這么簡單希坚。詳細的配置步驟請看下一節(jié)。
2. 全互聯(lián)模式最佳實踐
對如何配置有了清晰的思路之后陵且,接下來就可以進入實踐環(huán)節(jié)了裁僧。我不打算從 WireGuard 安裝開始講起,而是以前幾篇文章為基礎(chǔ)添磚加瓦慕购。所以我建議讀者先按順序看下這兩篇文章:
咱們直接從配置開始說起聊疲。手擼配置的做法是不明智的,因為當(dāng)節(jié)點增多之后工作量會很大沪悲,我還是建議通過圖形化界面來管理配置获洲,首選 wg-gen-web。
現(xiàn)在還是假設(shè)有上節(jié)所述的 4 個 Peer可训,我們需要從中挑選一個 Peer 來安裝 wg-gen-web
昌妹,然后通過 wg-gen-web
來生成配置。挑選哪個 Peer 無所謂握截,這個沒有特殊限制,這里假設(shè)挑選 AWS
來安裝 wg-gen-web
烂叔。
安裝的步驟直接略過谨胞,不是本文的重點,不清楚的可以閱讀我之前的文章 WireGuard 配置教程:使用 wg-gen-web 來管理 WireGuard 的配置蒜鸡。Server 配置如圖:
生成 Azure
的配置:
SUBMIT 之后再查看 wg0.conf
的內(nèi)容:
$ 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
這里無法通過圖形化界面添加私有網(wǎng)段的配置胯努,我們可以直接修改 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 配置文件:
可以看到配置文件內(nèi)容為:
$ 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 的配置文件:
這時你會發(fā)現(xiàn) wg0.conf
中已經(jīng)包含了所有 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
繼續(xù)修改 wg0.conf
添加私有網(wǎng)段配置:
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
現(xiàn)在問題就好辦了逢防,我們只需將 wg0.conf 中的 Aliyun 和 GCP 部分的配置拷貝到 Azure 的配置中叶沛,并刪除 PresharedKey 的配置,再添加 Endpoint 的配置和 PostUP/PostDown 規(guī)則:
$ 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
最后在各自的節(jié)點上通過各自的配置文件把 WireGuard 跑起來灰署,就搞定了。
整個圖形化界面配置過程中會出現(xiàn)好幾個地方需要手動調(diào)整配置,這是因為 wg-gen-web
的功能目前還不完善溉箕,需要給它一定的時間晦墙。如果你無法接受手動調(diào)整配置,可以嘗試另外一個項目:wg-meshconf肴茄,這個項目專門用來生成 mesh 的配置晌畅,但沒有圖形化管理界面。各有利弊吧寡痰,大家自行選擇抗楔。
3. 總結(jié)
我知道逮京,很多人可能還是一頭霧水忌穿,這玩意兒的應(yīng)用場景有哪些?我隨便舉個簡單的例子喘帚,假設(shè)你在云服務(wù)器上部署了 Kubernetes 集群贪婉,可以用本地的機器和云服務(wù)器的某臺節(jié)點組建 WireGuard 隧道反粥,然后在本地的 AllowedIPs
中加上 Pod 網(wǎng)段和 Service 網(wǎng)段,就可以那啥了疲迂,你懂吧才顿?
好吧,又埋了一個坑尤蒿,關(guān)于如何在家中直接訪問云服務(wù)器 k8s 集群的 Pod IP 和 Service IP郑气,后面會有專門的文章給大家講解,雖然我也不確定是多久以后腰池。尾组。