iptables перенаправляет локальные соединения на удаленную систему / порт

Я пытаюсь использовать SSH для переноса локального порта переадресации машин Windows 3389 на сервер redhat на каком-то произвольном порту (в непривилегированном регионе), который я защитил за брандмауэром, а затем перенаправить непривилегированный порт на сервере redhat на удаленный рабочий стол пользователя. По сути, создайте высокоспециализированную VPN, которая выполняет только одну задачу: подключите пользователей к своим системам за брандмауэром, используя зашифрованный туннель, который я контролирую.

Я знаю, много лет назад это было возможно с помощью команды:

iptables -A OUTPUT -t nat --dport ${LOCAL UNPRIV PORT} \
           -j DNAT ${ANOTHER SYSTEM}:${REMOTE PORT}

но из того, что я прочитал, похоже, что эта возможность была удалена, и я получаю сообщение в /var/log/messages

      kernel: NAT: no longer support implicit source local NAT 

Я нашел ресурсы, которые предполагают, что в ядре 2.6.X - 2.6.10 был способ включить это в ядре с использованием IP_NF_NAT_LOCAL, но, по-видимому, в более поздних ядрах его удалили. Я попытался перенаправить весь локальный трафик, чтобы он вошел в цепочку PREROUTING, и имел ограниченный успех, и это выглядит как плохая идея, потому что тогда мне нужно открыть непривилегированный порт на сервере, чтобы я мог передать его обратно в интерфейс eth0. Я уверен, что если бы у меня было больше времени, я мог бы найти какой-то причудливый клочж или обходной путь, но я бы предпочел не взламывать свои скрипты брандмауэра. Похоже, что должен быть гораздо более простой способ сделать это, я не вижу. Любая помощь или руководство, которое может предоставить сообщество, было бы очень полезно! заранее спасибо

3 ответа

Решение

Я не совсем уверен, понял ли я, но думаю, что вы просто не в той цепочке.:-) Я тоже растерялся, когда впервые использовал iptables. Но способ переадресации локального порта ${LOCAL UNPRIV PORT} заключается в следующем заявлении:

$IPT -t nat -A PREROUTING -i eth0 -p tcp --dport ${LOCAL UNPRIV PORT} 
     -j DNAT --to ${ANOTHER SYSTEM}:${REMOTE PORT}

Это смесь семантической проблемы и способа работы netfilter: в старые времена переадресация локального порта включала соединение с переадресацией, а также второе соединение с пунктом назначения. Iptables делает это за один шаг. Таким образом, вместо двух соединений - вы перенаправляете трафик на этот порт непосредственно к месту назначения. NETfilter выполняет все проверки работоспособности и ведение бухгалтерского учета: только пакеты, которые принадлежат действительному соединению, являются NAT и могут быть переадресованы.

Enabling DNAT doesn't allow any packets to be forwarded. You also have to add a rule:

$IPT -N INET-PRIV
$IPT -A FORWARD -i eth0 -o eth1 -j INET-PRIV
$IPT -A FORWARD -j DROP

$IPT -A INET-PRIV -p tcp -d ${ANOTHER SYSTEM} --dport ${REMOTE PORT} -j ACCEPT

$IPT -A INET-PRIV -j DROP

And you have to enable forwarding of course.

echo "1" > /proc/sys/net/ipv4/ip_forward

Pro iptables: more secure, more flexible, less memory and CPU used per connection

Contra iptables: forwarding a connection from a internal machine to a internal machine (feed it back into the eth0) doesn't make sense with iptables (of course you can always connect directly), forwarding traffic that is generated locally doesn't work (a port forwarding daemon might help - but usually doesn't make sense)

Exactly this might be the problem: you try to use NAT on a non-router, so you should use a forwarding daemon or skip this extra port forwarding completely and do:

ssh -L 1234:${ANOTHER SYSTEM}:${REMOTE PORT} special-vpn-box

On special-vpn-box you can only allow incoming connections from the router and outgoing connections to ${ANOTHER SYSTEM}:${REMOTE PORT} using iptables. That way users of the special-vpn-box can only access ${ANOTHER SYSTEM}:${REMOTE PORT} and won't be able to do anything else if they aren't trusted.

Вот что я делаю специально для локальной пересылки:

iptables -t nat -A OUTPUT -m addrtype --src-type LOCAL --dst-type LOCAL -p tcp --dport 3306 -j DNAT --to-destination ip.ip.ip.ip
iptables -t nat -A POSTROUTING -m addrtype --src-type LOCAL --dst-type UNICAST -j MASQUERADE

sysctl -w net.ipv4.conf.all.route_localnet=1

Убедитесь, что вы замените ip.ip.ip.ip для вашего реального публичного IP, а также --dport 3306 для порта, который вы хотите переслать.

Наконец, запустите команду sysctl, а также обновите /etc/sysctl.conf

Вы можете обновить sysctl.ctl разрешить маршрутизацию localhost с помощью следующей команды:

echo "net.ipv4.conf.all.route_localnet=1" >> /etc/sysctl.conf

Теперь все это кажется простым и хорошим, но потребовалось некоторое исследование и поиск. Имейте в виду и понимайте, что для пересылки localhost/127.0.0.1 требуется этот метод, а другие типичные примеры не работают. Некоторые примеры решений, которые не работают с localhost:

iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to ip.ip.ip.ip:3306
iptables -t nat -A POSTROUTING -d ip.ip.ip.ip -j MASQUERADE

http://realtechtalk.com/iptables_how_to_forward_localhost_port_to_remote_public_IP-1788-articles

# Enable IP Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -t nat -A PREROUTING  -p tcp \
--dport ${LOCAL UNPRIV PORT} -j DNAT --to-destination ${ANOTHER SYSTEM}:${REMOTE PORT}

iptables -t nat -A POSTROUTING -p tcp \
--dst ${ANOTHER SYSTEM} --dport ${REMOTE PORT} -j SNAT --to-source ${LOCAL SYSTEM}
Другие вопросы по тегам