所以我有一個 VPS (KVM) 伺服器,運行帶有公共 IP 的 Debian bullseye。該伺服器也運行wireguard 伺服器。在家裡,我有另一台伺服器(位於 NAT 後面),有連接到我的 VPS 的wireguard 用戶端。隧道已啟動並正在運行,這意味著我可以透過wireguard VPN 正常通訊。
+----------------------------------+ +-------------------------------
| Homeserver (behind NAT) | | VPS (KVM) with public IP |
| 192.168.1.10 | | 1.2.3.4 |
| +------------------------| |--------------------+ |
| | wg-homeserver | - - - - - - | wg-vps | |
| | 192.168.200.2 | | 192.168.200.1 | |
| +------------------------| |--------------------+ |
| | | |
+----------------------------------+ +------------------------------+
我的家庭伺服器運行許多監聽連接埠(所有 IP 位址)的 docker 容器,這意味著這些連接埠可以從 192.168.1.0/24 存取。我現在需要在 VPS 的公共 IP 位址上轉發 1 個 TCP 和 1 個 UDP 端口,並透過 Wireguard 鏈路將流量轉發到我的家庭伺服器上的相同端口:
1.2.3.4:10000/tcp -> 192.168.200.2:10000/tcp
1.2.3.4:10001/udp -> 192.168.200.2:10001/udp
兩台機器上都啟用了 IP 轉發,這意味著cat /proc/sys/net/ipv4/ip_forward
顯示1
。
為了轉發 TCP 端口,我有以下規則:
iptables -A FORWARD -d 192.168.200.2/32 -i wg-vps -p tcp --dport 10000 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 10000 -j DNAT --to-destination 192.168.200.2:10000
當我嘗試時,ssh -p 10000 1.2.3.4
我沒有看到 記錄任何資料包wireguard -i wg-vps
。我嘗試了很多其他事情,但無法弄清楚我做錯了什麼或遺漏了什麼。
無論如何,對於 UDP 端口,我創建了這條規則,稍微成功一些:
iptables -t nat -A PREROUTING -d 1.2.3.4/32 -i eth0 -p udp --dport 10001 -j DNAT --to-destination 192.168.200.2:10001
這是我發送 udp 測試資料包的方式:
echo -n test | nc -4 -u 1.2.3.4 10001
當我這樣做時,我可以tcpdump -i wg-vps
在我的 VPS 日誌上看到以下內容(4.5.6.7
是我的公用 IP 位址):
11:35:47.497622 IP 4.5.6.7.43357 > 192.168.200.2.10001: UDP, length 4
看起來它正在嘗試做正確的事情並獲取資料包,將目的地更新為192.168.200.2
,然後將其放入wireguard 介面上wg-vps
。但tcpdump -i wg-homeserver
在我的家庭伺服器上從未顯示此資料包到達。
事實上,我注意到,當我watch ip -s link show wg-homeserver
在 Homeserver 上時,每次向該連接埠發送 udp 封包時,RX 錯誤都會增加 1。所以某物讓它一路到達那裡,但無論它是什麼,它都沒有出現,tcpdump
並且似乎被丟棄在下面的某個地方。這很奇怪,因為 Wireguard 鏈路上的 UDP 和 TCP 在兩個方向上都運作得很好。
據我了解,tcpdump
在 iptables 之前顯示資料包,所以我的猜測是,即使資料包似乎被寫入wireguard 接口,它也會在某個地方被丟棄。
更新: 好的,我找到了一種啟用wireguard 日誌記錄的方法:
echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
當使用它追蹤日誌時,dmesg --follow
wireguard 正在丟棄資料包,原因如下:
wireguard: wg-homeserver: Packet has unallowed src IP (4.5.6.7) from peer 20 (xxxxxx)
所以我認為這意味著它不喜歡來源位址是來自請求來源的原始位址這一事實。我不想做 SNAT,所以我想我只需要以某種方式教它它應該允許任何來源位址。
這就是我的wireguard 配置部分AllowedIPs
中的設定。[Peer]
這解決了這個問題:
AllowedIPs = 0.0.0.0/0, ::0/0
在此之前,我已將介面遮罩與本[Interface]
節中的內容類似,但我沒有意識到這會限制資料包的來源位址。
然而,這會劫持所有流量並嘗試透過wireguard連結路由它,因為wg-quick
它AllowedIPs
認為它應該添加一條路由並透過VPN重新導向所有流量。這顯然是不希望的,但幸運的是有一個解決方案:添加Table = off
到該[Interface]
部分將阻止這種情況。
答案1
請參閱規則表以了解傳出資料包在家庭伺服器上的路由方式。 wg-quick 將會加入一些規則。
ip rule show
對我來說,我必須刪除 wg-quick 產生的一些規則(這使得它將所有封包轉送到 wg),然後添加轉送所需連接埠的規則。您可以從上面的命令中看到 wg table#。
ip -4 rule add sport 80 table XXXXX
ip -4 rule add sport 443 table XXXXX
上面的方法工作了一段時間。但當 dhcp 租約到期或 LAN 電纜斷開並重新連接時,systemd-networkd 將刪除自訂規則。所以我完全刪除了 wg-quick 並使用 systemd-networkd 來配置 wg 介面和路由規則。