Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I need to hack the OS X pf to redirect all ssh connections from an user to this machine. I want, when doing

$ ssh

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,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/ and

rdr on en1 proto TCP from any to any port 22 -> 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/ 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

share|improve this question
I'd love to know why you want to do this instead of just disabling SSH. – John Gardeniers Aug 26 '12 at 6:36
This is not the real thing I need to do. I took port 22 TCP just as a simplified, easy to test in other places, example. – foxx1337 Aug 26 '12 at 10:41
I'm actually constructing an RTMP proxy. Here you go, no nonesense. If it makes sense now, eagerly waiting for the solution. – foxx1337 Aug 26 '12 at 12:18

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 a rdr 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 (on lo0).

# Output interface
Out = en0
Packets = "proto tcp from $Out to any port 22"
# Step "2". Rdr those same packets that were routed to lo0 below
rdr pass log on lo0 $Packets ->
# Step "1". Route new IPv4 TCP connections leaving $Out to lo0
pass out on $Out  route-to lo0  inet $Packets keep state
share|improve this answer
This way does not work for ppp0. Any suggestions? – Elden Jan 26 '14 at 17:13
How exactly does it not work? After applying this config, does ssh still reach the destination on the internet, or do the packets just seem to get lost? – Dan Jan 31 '14 at 16:26
Traffic to the proxy cannot be reached. – Elden Feb 4 '14 at 6:57
@Dan From the pf.conf(5) man page, "Macros are not expanded inside quotes". I replaced $Out inside of the $Packets assignment and pfctl stopped complaining about syntax errors. – flackend Sep 15 '15 at 2:17
@Dan hey man, can you help me out on my question here? thanks! – est Jan 19 at 13:37

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.