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 체인을 통과하지 않으므로 DNATted가 아닙니다. 로컬에서 생성된 트래픽을 DNAT하려면 OUTPUT 테이블을 사용하세요.

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

그러나 내가 말했듯이, 그것은 일을 지나치게 복잡하게 만듭니다. 또한 사용하기로 선택한 경우 위 규칙의 대상 주소를 일치시킬 수도 있습니다.

관련 정보