Firewall

Wireguard 未完成握手

  • April 23, 2022

我有兩個 Debian GNU/Linux 系統(bullseye/sid),都在埠 23456 上執行wireguard,都在 NAT 後面。兩者都執行 > 5.6 的核心版本(wireguard mainlined)。

系統 A 是伺服器,它在權威名稱伺服器中為其網際網路域動態更新專用“A 記錄”,並為其分配面向網際網路的路由器 A(ZyWALL USG 100 防火牆)分配的正確公共 IP 地址。它每分鐘這樣做一次,但公共 IP 地址實際上僅在路由器/防火牆重新啟動時才會更改,這基本上不會發生。

系統 B 在 VDSL 路由器 B 後面,它充當線保護客戶端,指向動態更新的“A 記錄”和埠 33456。路由器 B 是消費級 VDSL 路由器,它允許出站方向的所有內容,只回復入站。

路由器/防火牆 A (ZyWALL USG 100) 被配置為允許埠 23456 上的 UDP 數據包通過它並將它們轉發到伺服器 A。以下是相關配置螢幕:

ZyWALL USG 100wireguard-behind-NAT 配置

這是伺服器 A Wireguard 配置文件(此程式碼段中的密鑰,儘管有效,但不是真實的):

[Interface]
Address = 10.31.33.100/24, fc00:31:33::1/64
ListenPort = 23456
PrivateKey = iJE/5Qy4uO55uUQg8nnDKQ/dFT1MEq+tDfFXrGNj3GY=
# PreUp = iptables -t nat -A POSTROUTING -s 10.31.33.0/24  -o enp1s0 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -s fc00:31:33::/64 -o enp1s0 -j MASQUERADE
# PostDown = iptables -t nat -D POSTROUTING -s 10.31.33.0/24  -o enp1s0 -j MASQUERADE; ip6tables -t nat -D POSTROUTING -s fc00:31:33::/64 -o enp1s0 -j MASQUERADE

# Simon
[Peer]
PublicKey = QnkTJ+Qd9G5EybA2lAx2rPNRkxiQl1W6hHeEFWgJ0zc=
AllowedIPs = 10.31.33.211/32, fc00:31:33::3/128

這是客戶端 B 的wireguard 配置(同樣,密鑰和域不是真實的):

[Interface]
PrivateKey = YA9cRlF4DgfUojqz6pK89poB71UFoHPM6pdMQabWf1I=
Address = 10.31.33.211/32

[Peer]
PublicKey = p62kU3HoXLJACI4G+9jg0PyTeKAOFIIcY5eeNy31cVs=
AllowedIPs = 10.31.33.0/24, 172.31.33.0/24
Endpoint = wgsrv.example.com:33456
PersistentKeepalive = 25

這是描述這種情況的髒圖:

Client B -> LAN B -> VDSL Router B (NAT) -> the internet -> ZyWALL (NAT) -> LAN A -> Server A

在兩個系統上啟動wireguard 不會建立VPN 連接。在客戶端啟動調試消息並將 LOG 規則添加到 iptables 中,記錄OUTPUT數據包,我得到了很多這些:

[414414.454367] IN= OUT=wlp4s0 SRC=10.150.44.32 DST=1.2.3.4 LEN=176 TOS=0x08 PREC=0x80 TTL=64 ID=2797 PROTO=UDP SPT=36883 DPT=33456 LEN=156 
[414419.821744] wireguard: wg0-simon: Handshake for peer 3 (1.2.3.4:33456) did not complete after 5 seconds, retrying (try 2)
[414419.821786] wireguard: wg0-simon: Sending handshake initiation to peer 3 (1.2.3.4:33456)

我已經向伺服器添加了一個 LOG iptables 規則,以便診斷路由器配置問題。

root@wgserver ~ # iptables -t nat -I INPUT 1 -p udp --dport 23456 -j LOG

它記錄從客戶端收到的wireguard數據包(但我不知道它們是無效還是不完整):

[ 1412.380826] IN=enp1s0 OUT= MAC=6c:62:6d:a6:5a:8e:d4:60:e3:e0:23:30:08:00 SRC=37.161.119.20 DST=10.150.44.188 LEN=176 TOS=0x08 PREC=0x00 TTL=48 ID=60479 PROTO=UDP SPT=8567 DPT=23456 LEN=156 
[ 1417.509702] IN=enp1s0 OUT= MAC=6c:62:6d:a6:5a:8e:d4:60:e3:e0:23:30:08:00 SRC=37.161.119.20 DST=10.150.44.188 LEN=176 TOS=0x08 PREC=0x00 TTL=48 ID=61002 PROTO=UDP SPT=8567 DPT=23456 LEN=156 

所以我傾向於假設 A 路由器(ZyWALL USG 100)已正確配置為讓數據包進入伺服器本地網路。為了證實這個假設,我什至嘗試用另一個消費級路由器替換 ZyWALL 並將伺服器移動到不同的網際網路連接上,但問題仍然存在,所以我確定問題不是防火牆,也不是它的具體問題網路連接。

這是伺服器網路配置,以防萬一:

auto lo
iface lo inet loopback

auto enp1s0
iface enp1s0 inet static
   address 10.150.44.188/24
   gateway 10.150.44.1

最重要的是,使用相同的客戶端、相同的 VDSL 路由器(客戶端)、相同的網際網路連接、類似的伺服器配置(顯然不同的密鑰和域)、類似的防火牆配置(伺服器端、不同的防火牆模型)。

這可能很愚蠢,但您是否嘗試創建新的伺服器密鑰、客戶端密鑰並重試?當配置文件錯誤時,Wireguard 可以完全這樣做。

好的,你提到客戶端在 VDSL 上,所以我懷疑你有 MTU 問題。

有線(現在是無線)網路連接的正常 MTU 為 1500 字節,但在 *DSL 上,PPPoE 層佔用 8 個字節,使得可用的 MTU 實際上為 1492。(也有可能您的網路連接已設置為甚至更低的 MTU。)

Wireguard 的數據包成本為 80 字節,這意味著隧道 MTU 預設為 1420。嘗試將其降低相同的 8 個字節,到 1412。(如果您的 MTU 已經低於 1492,則降低。)

您還需要讓客戶端告訴伺服器在隧道數據包上降低其 MTU。這可以通過 iptables 規則來完成。

在客戶端 wg0.conf 中,您將需要以下內容:

[Interface]
MTU = 1412
PostUp = iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
PostDown = iptables -D FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
;....the rest

引用自:https://serverfault.com/questions/1040165