Linux iptables ssh переадресация портов (марсианский отказ)

12

У меня есть шлюз Linux, выполняющий NAT для моей домашней сети. У меня есть другая сеть, в которую я хотел бы прозрачно пересылать пакеты, но только в / из определенных IP / портов (т.е. не VPN). Вот несколько примеров IP и портов для работы:

Source          Router          Remote Gateway     Remote Target
192.168.1.10 -> 192.168.1.1 ->  1.2.3.4        ->  192.168.50.50:5000

Мне бы хотелось, чтобы исходный компьютер мог общаться с определенными портами на удаленной цели, как если бы он был напрямую маршрутизируемым от маршрутизатора. На маршрутизаторе eth0 - частная сеть, а eth1 - выход в Интернет. Remote Gateway - это еще одна машина Linux, на которую я могу подключиться по ssh, и она может напрямую направляться к Remote Target.

Моя попытка найти простое решение - настроить переадресацию порта ssh на маршрутизаторе, например:

ssh -L 5000:192.168.50.50:5000 1.2.3.4

Это прекрасно работает для маршрутизатора, который теперь может подключаться локально к порту 5000. Таким образом, «telnet localhost 5000» будет подключен к 192.168.50.50:5000, как и ожидалось.

Теперь я хочу перенаправить трафик из источника и воронки через установленный туннель ssh. Я попытался правило NAT для этого:

iptables -t nat -D PREROUTING -i eth0 -p tcp -s 192.168.1.10 --dport 5000 -d 1.2.3.4 -j DNAT --to-destination 127.0.0.1:5000

и так как Маршрутизатор уже является моим NAT-шлюзом, у него уже есть необходимое правило маршрутизации:

-A POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE

Большинство вопросов и ответов на этом сайте или в другом месте, кажется, имеют дело с переадресацией портов сервера или шпильки NAT, оба из которых у меня работают нормально в другом месте, ни один из которых не относится к этой ситуации. Я, конечно, мог бы DMZ перенаправлять порты Remote Target через Remote Gateway, но я не хочу, чтобы порты были доступны через Интернет, я хочу, чтобы они были доступны только через безопасный туннель SSH.

Лучший ответ, который я могу найти, касается отклонения марсианских пакетов в ядре Linux:

iptables, как перенаправить порт из loopback?

Я включил ведение журнала марсиан и подтвердил, что ядро ​​отклоняет эти пакеты как марсиане. За исключением того, что это не так: я точно знаю, для чего эти пакеты, откуда они и куда они идут (мой ssh-туннель).

Представленное здесь «обходное» решение применимо к этому первоначальному вопросу, но не применимо для моего случая.

Однако во время написания / исследования этого вопроса я обошел свою проблему, используя привязку IP-адреса источника SSH следующим образом:

ssh -L 192.168.1.1:5000:192.168.50.50:5000 1.2.3.4
iptables -t nat -D PREROUTING -i eth0 -p tcp -s 192.168.1.10 --dport 5000 -d 1.2.3.4 -j DNAT --to-destination 192.168.1.1:5000

Так как я не использую петлю, это обходит марсианский отказ.

Я до сих пор оставляю здесь вопрос по двум причинам:

  1. В надежде, что кто-то, кто пытается сделать что-то подобное в будущем, может найти это в своих поисках, и этот обходной путь может помочь им.
  2. Я по-прежнему предпочитаю идею, чтобы мой ssh-порт перенаправлял соединение, связанное только с обратной связью, и мог маршрутизировать их через iptables. Поскольку я точно знаю, что это за пакеты и куда они направляются, не должен ли я как-то пометить их как таковые, чтобы марсианская фильтрация Linux не отвергала их? Все мои поиски по этой теме приводят к rp_filter, который совсем не помог в моем тестировании. И даже если это сработало, это не относится к конкретным пакетам, которые я пытаюсь разрешить.

Я заинтересован в том, чтобы добавить свой вопрос и обходной путь в общий поиск, чтобы сэкономить кому-то еще часы поиска, которые я потратил только для того, чтобы придти в тупик, а также надеюсь, что кто-то ответит на петлевую / марсианскую часть моего вопроса, которая все еще остается открытой мне.

отметка
источник
При дальнейшем чтении поста Meta на UL vs SF я также обращаю внимание на просьбу Майкла не кросспостить. Я только добавил это, потому что это было специально помечено как не по теме в SF, так что, если это более уместно и возможно, просто переместить исходный вопрос и закрыть этот вопрос, это тоже было бы здорово.
Отметить
Помещение net.ipv4.conf.default.rp_filter = 0 и net.ipv4.conf.all.rp_filter = 0 в ваш /etc/sysctl.conf и выполнение команды "sudo sysctl -p" решает вашу проблему?
Руи Ф Рибейро
Я пытался применить эти оба непосредственно, т.е. 'sysctl net.ipv4.conf.default.rp_filter = 0', в том числе один для моего частного интерфейса. Я подтвердил, что они установлены через 'sysctl -a', однако марсианские пакеты до 127.0.0.1 все еще отклоняются. И даже если это сработало, открытие всех моих интерфейсов для марсиан это НЕ то, что я хочу. Я также не хочу открывать единый (личный) интерфейс. Я точно знаю, какие марсианские пакеты я хочу разрешить, и желаю / надеюсь на выражение iptables NAT / mangle, которое позволит мне сделать это.
Марк
Возможно, вы захотите net.ipv4.conf.default.rp_filter = 2 и некоторые другие правила iptables
Rui F Рибейро

Ответы:

1

Проблема с выполнением DNAT до 127.0.0.1:5000 заключается в том, что когда удаленная сторона отвечает, эти пакеты возвращаются в механизм маршрутизации, как если бы они были созданы локально (с 127.0.0.1), но имеют внешний адрес назначения. SNAT / MASQUERADE, соответствующий внешнему интерфейсу, перехватил бы их и переписал бы их, но решения о маршрутизации, которые должны быть приняты для пакетов, прибывающих на этот интерфейс, приходят первыми, и они запрещают эти пакеты, которые являются поддельными по умолчанию. Механизм маршрутизации не может гарантировать, что вы не забудете сделать это переписать позже.

Вместо этого вы должны иметь возможность отклонять любые внешние соединения с 192.168.1.1:5000 в iptables INPUT, кроме тех, которые приходят из 192.168.1.10, используя !аргумент перед -sспецификацией адреса источника. Если вы используете сброс TCP в качестве механизма отклонения ( -j REJECT --reject-with tcp-resetвместо того, чтобы пункт назначения ICMP по умолчанию был недоступен), он будет в значительной степени идентичен ситуации, когда ничто даже не прослушивало комбинацию этого адреса: порта с точки зрения внешнего мира.

Иосип Роден
источник
0

Я бы использовал openVPN для создания туннеля от маршрутизатора до RemoteGateway.

Тогда я бы на Router добавил маршрут:

route add -host RemoteTarget gw RemoteGateway-VPNадрес

используйте простое правило iptables, где бы вы ни хотели, чтобы ограничить количество доступных портов для Source.

Уэйн Уокер
источник