5

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

foxx1337
  • 169
  • 1
  • 5

1 Answers1

10

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

# 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
poige
  • 9,171
  • 2
  • 24
  • 50
Dan
  • 261
  • 3
  • 5
  • 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 04 '14 at 06:57
  • 1
    @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 02:17
  • @Dan hey man, can you help me out on my question [here](http://apple.stackexchange.com/questions/223944/pf-port-forwarding-on-os-x-yosemite-to-avoid-block)? thanks! – est Jan 19 '16 at 13:37
  • May I enquire as to why the `Out` and `Packets` macros are used? Is it a stylistic thing or would using `en0` etc change the processing somehow? – ian Dec 03 '18 at 04:06
  • Well, first of all this ruleset simply won't load due to syntax errors. – poige Sep 13 '19 at 10:11