通過 OpenVPN 進行埠轉發
這是我的場景。我有三個主機。
- GATEWAY 執行 OpenVPN 伺服器。它有 1 個 LAN IP (192.168.1.10) 和 1 個 OpenVPN IP (10.8.0.1)。
2)LOCAL-CLIENT,與GATEWAY在同一區域網路內的機器,有1個區域網路IP(192.168.1.12)
- REMOTE-SERVER,一個 MySQL 伺服器,它是 OpenVPN 伺服器的客戶端。它有 1 個公共 IP 和 1 個 OpenVPN IP (10.8.0.51)。
我希望能夠通過 VPN 從 LOCAL-CLIENT 連接到 REMOTE-SERVER 上的 MySQL。
到目前為止,我已經啟用了 IP 轉發並添加了一個埠轉發,如下所示:
echo "1" > /proc/sys/net/ipv4/ip_forward iptables -t nat -A OUTPUT -p tcp --dport 3306 -j DNAT --to 10.8.0.51
這適用於 GATEWAY,我可以使用 192.168.1.10 作為主機連接到 MySQL。但是當我從 LOCAL-CLIENT 嘗試時,我收到“連接被拒絕”錯誤(使用 MySQL 客戶端或 telnet 到埠 3306)。
我在這裡想念什麼?
順便說一句,我還嘗試轉發 HTTP 埠以針對也在 REMOTE-SERVER 上執行的 Apache 進行測試,我得到了相同的結果,所以這不是 MySQL 問題。
更多資訊:
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0 10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0 192.168.1.0 0.0.0.0 255.255.255.0 U 1 0 0 eth1 5.5.0.0 0.0.0.0 255.255.252.0 U 0 0 0 as0t0 5.5.4.0 0.0.0.0 255.255.252.0 U 0 0 0 as0t1 5.5.8.0 0.0.0.0 255.255.252.0 U 0 0 0 as0t2 5.5.12.0 0.0.0.0 255.255.252.0 U 0 0 0 as0t3 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth1
這是我在 GATEWAY 上的 iptables(AFAIK,大部分規則都是由 OpenVPN 伺服器添加的)。這是在應用@SmallClanger 建議的更改之後。
iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination AS0_ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED AS0_ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 AS0_IN_PRE all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x2000000/0x2000000 AS0_ACCEPT tcp -- 0.0.0.0/0 192.168.1.10 state NEW tcp dpt:915 AS0_ACCEPT tcp -- 0.0.0.0/0 192.168.1.10 state NEW tcp dpt:914 AS0_ACCEPT udp -- 0.0.0.0/0 192.168.1.10 state NEW udp dpt:917 AS0_ACCEPT udp -- 0.0.0.0/0 192.168.1.10 state NEW udp dpt:916 AS0_WEBACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED AS0_WEBACCEPT tcp -- 0.0.0.0/0 192.168.1.10 state NEW tcp dpt:943 Chain FORWARD (policy ACCEPT) target prot opt source destination AS0_ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED AS0_IN_PRE all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x2000000/0x2000000 AS0_OUT_S2C all -- 0.0.0.0/0 0.0.0.0/0 ACCEPT all -- 10.8.0.0/24 0.0.0.0/0 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable ACCEPT tcp -- 0.0.0.0/0 10.8.0.51 tcp dpt:3306 Chain OUTPUT (policy ACCEPT) target prot opt source destination AS0_OUT_LOCAL all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_ACCEPT (7 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_DNS (2 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 172.20.2.26 DROP all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_IN (4 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 5.5.0.1 ACCEPT all -- 0.0.0.0/0 10.8.0.1 ACCEPT all -- 0.0.0.0/0 192.168.1.0/24 AS0_IN_POST all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_IN_POST (1 references) target prot opt source destination AS0_OUT all -- 0.0.0.0/0 0.0.0.0/0 DROP all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_IN_PRE (2 references) target prot opt source destination AS0_DNS tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:53 AS0_DNS udp -- 0.0.0.0/0 0.0.0.0/0 state NEW udp dpt:53 AS0_IN all -- 0.0.0.0/0 5.5.0.0/20 AS0_IN all -- 0.0.0.0/0 192.168.0.0/16 AS0_IN all -- 0.0.0.0/0 172.16.0.0/12 AS0_IN all -- 0.0.0.0/0 10.0.0.0/8 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_OUT (2 references) target prot opt source destination DROP all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_OUT_LOCAL (1 references) target prot opt source destination DROP icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 5 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_OUT_S2C (1 references) target prot opt source destination AS0_OUT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_WEBACCEPT (2 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
這是 NAT 表
iptables -L -n -t nat Chain PREROUTING (policy ACCEPT) target prot opt source destination AS0_NAT_PRE_REL_EST all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED AS0_DPFWD_UDP udp -- 0.0.0.0/0 192.168.1.10 udp dpt:1194 state NEW AS0_DPFWD_TCP tcp -- 0.0.0.0/0 192.168.1.10 tcp dpt:443 state NEW DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:10.8.0.51 Chain POSTROUTING (policy ACCEPT) target prot opt source destination AS0_NAT_POST_REL_EST all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED AS0_NAT_PRE all -- 0.0.0.0/0 0.0.0.0/0 mark match 0x2000000/0x2000000 MASQUERADE all -- 10.8.0.0/24 0.0.0.0/0 Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain AS0_DPFWD_TCP (1 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 to:192.168.1.10:914 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_DPFWD_UDP (1 references) target prot opt source destination DNAT udp -- 0.0.0.0/0 0.0.0.0/0 to:192.168.1.10:916 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_NAT (2 references) target prot opt source destination SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.1.10 SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:10.8.0.1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_NAT_POST_REL_EST (1 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_NAT_PRE (1 references) target prot opt source destination AS0_NAT_TEST all -- 0.0.0.0/0 5.5.0.0/20 AS0_NAT_TEST all -- 0.0.0.0/0 192.168.0.0/16 AS0_NAT_TEST all -- 0.0.0.0/0 172.16.0.0/12 AS0_NAT_TEST all -- 0.0.0.0/0 10.0.0.0/8 AS0_NAT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_NAT_PRE_REL_EST (1 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain AS0_NAT_TEST (4 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ACCEPT all -- 0.0.0.0/0 5.5.0.0/20 AS0_NAT all -- 0.0.0.0/0 0.0.0.0/0
編輯:
根據@SmallClanger 的評論,我意識到我不需要進行任何埠轉發或 NAT。LOCAL-CLIENT 能夠通過其 VPN 的 IP 連接到 REMOTE-SERVER。為此,由於我的 VPN 網關不是預設網關,我必須在 LOCAL-CLIENT 上添加此靜態路由:
ip route add 10.8.0.0/24 via 192.168.1.10 dev eth0
我還必須刪除 iptables 上的這條 FORWARD 規則,它阻止 LOCAL-CLIENT 連接到任何 VPN 客戶端:
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
這是因為該
OUTPUT
鏈僅作用於源自本地程序的數據包。(在此處查看此有用的圖像。)如果您將該規則替換為(或補充,如果您仍想從網關連接):
iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to 10.8.0.51
而且,如果您還沒有允許流量:
iptables -t filter -A FORWARD -p tcp -d 10.8.0.51 --dport 3306 -j ACCEPT
然後你的連接應該通過。由於它已經在網關中工作,您可以確定 MySQL 正在正確偵聽並且它的伺服器正在接受連接。
但是,我懷疑您是否真的需要 NAT。
FORWARD
單獨的路由應該使用適當的規則來處理這個問題。該路由可以手動建立,也可以通過 VPN 伺服器配置建立,這取決於您的要求。如果您想查看此選項,您可以將您的 openvpn 伺服器配置和輸出添加route -n
到您的文章中嗎?編輯
為確保連接通過 VPN 路由返回,您需要從伺服器到 LAN 的路由。要在 MySQL 伺服器上手動添加:
route add -net 192.168.1.0/24 dev tun0
(如果tun0
是您的 VPN 客戶端介面)。如果可行,最好將其添加到您的 VPN 客戶端配置中:(
route 192.168.1.0/24
這將在連接時自動創建路由,無論使用的隧道介面或 PPP 端點地址如何)一個有用的調試提示:
tcpdump -i tun0 -qtln port 3306
在伺服器上將顯示通過 VPN 適配器(客戶端或伺服器)的 mysql 流量。您應該能夠看到連接握手出錯的地方。