Назад | Перейти на главную страницу

Как устранить неполадки при перенаправлении портов linux iptable

Уже есть масса помощи и руководств о том, как это сделать. Но по какой-то причине я не могу заставить его работать и не знаю, как это исправить.
У меня есть экземпляр postgres RDS с частным IP 10.0.122.220. У меня также есть хост-бастион с (да) частным IP 10.0.94.67. Я могу подключиться к портам хоста-бастиона, но не к RDS. Итак, я пытаюсь перенаправить порт 5432 хоста бастиона в порт 5432 экземпляра RDS.
Это статус хозяина бастиона:

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

Но я все еще не могу подключиться к экземпляру RDS с помощью SSH-туннелирования:

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

Объяснение, почему ваше решение НЕ работает: локально сгенерированный трафик НЕ проходит через цепочку PREROUTING таблицы NAT, поэтому он НЕ DNATted. Используйте таблицу OUTPUT для локально генерируемого трафика DNAT:

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

Но, как я уже сказал, это слишком сложно. И вы также можете захотеть сопоставить адрес назначения в приведенном выше правиле, если решите его использовать.