I need to hack the OS X pf to redirect all ssh connections from an user to this machine. I want, when doing
$ ssh google.com
to get the same results as with
$ ssh localhost
ie a connection to my locally running sshd.
Under a recent Linux, this would simply be:
# iptables -t nat -A OUTPUT -p tcp --dport 22 -m owner --uid-owner theuser -j REDIRECT
Under OS X 10.8, there appear to be 2 methods – ipfw and pf. Neither works.
Ipfw:
# ipfw flush
# ipfw add 50 fwd 127.0.0.1,22 tcp from any to any 22 uid theuser
If I drop the uid theuser
part, the redirect works, minus the user thingie. If I leave the uid
directive there, the network stack dies and the system shortly becomes unusable; no more ipfw
, no more ps
, no more kill
.
According to the man pages, ipfw is deprecated, so packet filter should be used instead:
# sysctl -w net.inet.ip.forwarding=1
Then I added
anchor "910.Custom/*"
load anchor "910.Custom" from "/etc/pf.anchors/910.Custom"
in /etc/pf.anchors/com.apple
and
rdr on en1 proto TCP from any to any port 22 -> 127.0.0.1 port 22
in /etc/pf.anchors/910.Custom
(notice how I'm not mentioning anything about a user here, since the pf docs don't list such an option for rdr rules).
After I run # pfctl -ef /etc/pf.anchors/com.apple
nothing happens. If I add garbage to /etc/pf.anchors/910.Custom
or even if I dare add user theuser
after the rdr
rule, the firewall fitfully complains of the bad syntax.
Can the OS X kernel even perform NAT routing anymore, or did Apple yank out that functionality? If it can, am I missing anything?
LE. fixed iptables
syntax
Best Answer
You can do it with PF as well. However,
rdr
only accepts incoming packets. Thus, you have to first route those packets to lo0, then add ardr
-rule there (which will catch them as they will be routed in from "somewhere") to send them to your local SSH-server.The order is necessarily:
rdr
stuff, then filter stuff (like pass), but chronologically the 2nd rule will hit first (on$Out
), which will then activate the first rule (onlo0
).