如何解决 Linux iptable 端口转发问题

如何解决 Linux iptable 端口转发问题

关于如何做到这一点,已经有大量帮助和指南。但由于某种原因,我无法让它工作,也不确定如何排除故障。
我有一个带有私有 IP 的 RDS postgres 实例10.0.122.220。我还有一个带有(是)私有 IP 的堡垒主机10.0.94.67。我可以连接到堡垒主机上的端口,但不能连接到 RDS。所以我试图将5432堡垒主机的端口转发到5432RDS 实例的端口。
这是堡垒主机的状态:

bastion$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    inet 10.0.94.67/19 brd 10.0.95.255 scope global dynamic eth0
...

bastion$ ip route show | grep default
default via 10.0.64.1 dev eth0

bastion$ cat /proc/sys/net/ipv4/ip_forward
1

然后我添加了两个 NAT 规则:

bastion# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 5432 -j DNAT --to-destination 10.0.122.220

bastion# iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 5432 -d 10.0.122.220 -j SNAT --to-source 10.0.94.67

bastion# iptables -v -t nat -L -n
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0            tcp dpt:5432 to:10.0.122.220

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 443 packets, 32660 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 443 packets, 32660 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 SNAT       tcp  --  *      eth0    0.0.0.0/0            10.0.122.220         tcp dpt:5432 to:10.0.94.67

但是我仍然无法借助 SSH 隧道连接到 RDS 实例:

my-machine$ ssh -v -NL 5432:10.0.94.67:5432 -i my-key [email protected]
debug1: Connection to port 5432 forwarding to 10.0.94.67 port 5432 requested.
debug1: channel 2: new [direct-tcpip]
channel 2: open failed: connect failed: Connection refused
debug1: channel 2: free: direct-tcpip: listening port 5432 for 10.0.94.67 port 5432, connect from 127.0.0.1 port 57447 to 127.0.0.1 port 5432, nchannels 3
debug1: Connection to port 5432 forwarding to 10.0.94.67 port 5432 requested.
debug1: channel 2: new [direct-tcpip]
channel 2: open failed: connect failed: Connection refused
debug1: channel 2: free: direct-tcpip: listening port 5432 for 10.0.94.67 port 5432, connect from 127.0.0.1 port 57448 to 127.0.0.1 port 5432, nchannels 3
... keeps repeating the above

我可以确认的是,RDS 已启动、正在运行且响应,并且堡垒主机可以访问它,因为使用以下 SSH 隧道我可以连接到数据库:

my-machine$ ssh -v -NL 5432:10.0.122.220:5432 -i my-key [email protected]

我错过了什么?我该如何解决问题?谢谢。

答案1

我感觉你把事情搞得太复杂了。当你使用 SSH 将连接转发到数据库时,请忘记 iptables 和 NAT,只需使用 SSH 直接转发到数据库服务器:

使用:

my-machine$ ssh -v -NL 5432:10.0.122.220:5432 -i my-key [email protected]

代替:

my-machine$ ssh -v -NL 5432:10.0.94.67:5432 -i my-key [email protected]

解释为什么您的解决方案不起作用:本地生成的流量不会经过 NAT 表的 PREROUTING 链,因此不会被 DNAT。使用 OUTPUT 表对本地生成的流量进行 DNAT:

bastion# iptables -t nat -A OUTPUT -p tcp --dport 5432 -j DNAT --to-destination 10.0.122.220

但正如我所说 - 这会让事情变得过于复杂。如果您选择使用它,您可能还想在上面的规则中匹配目标地址。

相关内容