这是我的情况。我有三个主机。
1) 运行 OpenVPN Server 的 GATEWAY。它有 1 个 LAN IP(192.168.1.10)和 1 个 OpenVPN IP(10.8.0.1)。
2)LOCAL-CLIENT,与GATEWAY位于同一LAN内的机器,具有1个LAN IP(192.168.1.12)
3) 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(据我所知,大多数规则都是由 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
答案1
这是因为该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 流量。您应该能够看到连接握手出错的地方。
答案2
当我用这个打开端口时,我遇到了一个问题, iptables -t nat -A PREROUTING -p tcp --dport 25565 -j DNAT --to 10.8.0.2
我无法连接到在端口 25565 上运行的其他 minecraft 服务器。因此,ChatGPT 最终使用这两个命令解决了这个问题:
目标 NAT(DNAT)规则将外部端口 25565 转发到内部 IP 10.8.0.2
iptables -t nat -A PREROUTING -i enX0 -p tcp --dport 25565 -j DNAT --to 10.8.0.2:25565
源 NAT (SNAT) 规则将传出数据包的源 IP 更改为外部 IP
iptables -t nat -A POSTROUTING -o enX0 -s 10.8.0.0/24 -j SNAT --to-source 172.31.24.6
这是我的 openvpn 服务器网络:admin@ip-172-31-24-6:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000
link/ether 02:2b:3b:fd:5e:f5 brd ff:ff:ff:ff:ff:ff
inet 172.31.24.6/20 metric 100 brd 172.31.31.255 scope global dynamic enX0
valid_lft 3308sec preferred_lft 3308sec
inet6 fe80::2b:3bff:fefd:5ef5/64 scope link
valid_lft forever preferred_lft forever
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 10.8.0.1/24 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::fad8:69f1:63e0:e5ef/64 scope link stable-privacy
valid_lft forever preferred_lft forever