Мне нужно взломать OS X pf, чтобы перенаправить все ssh-подключения от пользователя на эту машину. Я хочу, чтобы при выполнении
$ ssh google.com
чтобы получить те же результаты, что и с
$ ssh localhost
т. е. подключение к моему локально запущенному sshd.
В последних версиях Linux это будет выглядеть просто:
# iptables -t nat -A OUTPUT -p tcp --dport 22 -m owner --uid-owner theuser -j REDIRECT
В OS X 10.8, похоже, есть 2 метода - ipfw и pf. Ни один не работает. Ipfw:
# ipfw flush
# ipfw add 50 fwd 127.0.0.1,22 tcp from any to any 22 uid theuser
Если я оставлю эту uid theuser
часть, перенаправление сработает, за исключением пользовательской штуковины. Если я оставлю директиву uid
там, сетевой стек умрет, и система вскоре станет непригодной для использования; больше нет ipfw
, больше нет ps
, больше нет kill
.
Согласно страницам руководства, ipfw устарел, поэтому вместо него следует использовать пакетный фильтр:
# sysctl -w net.inet.ip.forwarding=1
Затем я добавил
anchor "910.Custom/*"
load anchor "910.Custom" from "/etc/pf.anchors/910.Custom"
в /etc/pf.anchors/com.apple
и
rdr on en1 proto TCP from any to any port 22 -> 127.0.0.1 port 22
в /etc/pf.anchors/910.Custom
(обратите внимание, что я ничего не упоминаю здесь о пользователе, поскольку в документации pf такая опция для правил rdr не указана).
После запуска # pfctl -ef /etc/pf.anchors/com.apple
ничего не происходит. Если я добавляю мусор /etc/pf.anchors/910.Custom
или даже осмеливаюсь добавить user theuser
после rdr
правила, брандмауэр судорожно жалуется на плохой синтаксис.
Может ли ядро OS X вообще выполнять маршрутизацию NAT, или Apple выдернула эту функциональность? Если может, то я что-то упустил?
LE. фиксированный iptables
синтаксис
решение1
Вы можете сделать это и с PF. Однако rdr
он принимает только входящие пакеты. Таким образом, вам нужно сначала направить эти пакеты на lo0, а затем добавить rdr
там правило (которое перехватит их, поскольку они будут направлены "откуда-то"), чтобы отправить их на ваш локальный SSH-сервер.
Порядок обязательно следующий: rdr
stuff, затем filter stuff (например, pass), но хронологически 2-е правило сработает первым (на $Out
), что затем активирует первое правило (на lo0
).
# Output interface
Out = en0
# A macro to shorten rules below
Packets = "proto tcp from" $Out "to any port 22"
# Rule 1: Redirect those connections _after_ they were routed to lo0 below
rdr pass log on lo0 $Packets -> 127.0.0.1
# Rule 2: Route _first_ new IPv4 TCP connections leaving $Out to lo0
pass out on $Out route-to lo0 inet $Packets