Ssh

如何對 linux iptable 埠轉發進行故障排除

  • August 20, 2020

已經有很多關於如何做到這一點的幫助和指導。但是由於某種原因,我無法使其正常工作,並且不確定如何對其進行故障排除。

我有一個帶有私有 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 ec2-user@10.0.94.67
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 ec2-user@10.0.94.67

我錯過了什麼?我該如何解決?謝謝。

我有一種感覺,你把事情複雜化了。當您使用 SSH 轉發到數據庫的連接時,忘記 iptables 和 NAT,只需使用 SSH 直接轉發到數據庫伺服器:

採用:

my-machine$ ssh -v -NL 5432:10.0.122.220:5432 -i my-key ec2-user@10.0.94.67

代替:

my-machine$ ssh -v -NL 5432:10.0.94.67:5432 -i my-key ec2-user@10.0.94.67

解釋為什麼您的解決方案不起作用:本地生成的流量不通過 NAT 表的 PREROUTING 鏈,因此它不是 DNATted。使用 OUTPUT 表對本地生成的流量進行 DNAT:

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

但正如我所說 - 它是過於復雜的事情。如果您選擇使用它,您可能還希望在上述規則中匹配目標地址。

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