iptables equivalent for mac os x

Solution 1:

So I found out a way to do this. I'm not sure if it's the preferred way but it works! At your favourite shell:

sudo ifconfig lo0 10.0.0.1 alias
sudo ipfw add fwd 127.0.0.1,9090 tcp from me to 10.0.0.1 dst-port 80

(The alias to lo0 seems to be the missing part)

If you'd like a (fake) domain to point to this new alias then make sure /etc/hosts contains the line:

10.0.0.1 www.your-domain.com

Solution 2:

I was able to get this working using the ifconfig and pfctl commands on Mac 10.10.2. With the following approach I'm successfully mapping 127.0.0.1:3000 to mydomain.com locally on my machine.

In your command line enter the following two commands to forward connections to 127.0.0.1:3000 to 10.0.0.1:

sudo ifconfig lo0 10.0.0.1 alias
echo "rdr pass on lo0 inet proto tcp from any to 10.0.0.1 port 80 -> 127.0.0.1 port 3000" | sudo pfctl -ef -

Then edit your /etc/hosts or /private/etc/hosts file and add the following line to map your domain to 10.0.0.1.

10.0.0.1 mydomain.com

After you save your hosts file flush your local DNS:

sudo discoveryutil udnsflushcaches

Now open mydomain.com in a browser and you'll be seeing the server hosted on your localhost port (i.e. 127.0.0.1:3000). Basically this process maps an <ip>:<port> to a new <ip> so that you can then map a host that IP.


Solution 3:

I too had to do a similar thing recently, and in searching came upon this answer. Unfortunately, the answer of Nafe uses ipfw which is now deprecated and unavailable in OSX; and the answer of Kevin Leary is indeed a bit hackish. So I had to make something better (cleaner) and decided to share it here for posterity. This answer is largely based on the approach mentioned at this gist.

As OP mentions, pointing a browser at 192.168.99.100 should get a response from a server at localhost:8000. Adding an alias to ifconfig isn't really necessary, pfctl alone is sufficient: to achieve this the pf.conf file at /etc/pf.conf needs to be modified.

First we create (with sudo) a new anchor file (let's call it redirection) at: /etc/pf.anchors/redirection. This is basically a regular text file and contains the following line (just like in the answer of Kevin Leary): rdr pass on lo0 inet proto tcp from any to 192.168.99.100 port = 80 -> 127.0.0.1 port 8000. Once the new anchor file has been created, it needs to be referenced within the pf.conf file. Open the pf.conf file with sudo and add rdr-anchor "redirection" after the last rdr-anchor line (which is rdr-anchor "com.apple/*") and add load anchor "redirection" from "/etc/pf.anchors/redirection" at the end.

Ultimately, this is what the pf.conf file should look like:

scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
rdr-anchor "redirection"  #added for redirection/port forwarding
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
load anchor "pow" from "/etc/pf.anchors/redirection"  #added for redirection/port forwarding

And that's almost it. Just restart pfctl by issuing sudo pfctl -d to disable it first and then sudo pfctl -fe /etc/pf.conf to start it again.

Now, if you need this happen automatically after every restart, another tiny bit of work needs to be done: the launch daemon for pfctl needs to be updated (the referenced gist mentions that pf is enabled automatically on boot, however this does not seem to be the case from looking at the code). Open (with sudo) System/Library/LaunchDaemons/com.apple.pfctl.plist and look for this:

<array>
          <string>pfctl</string>
          <string>-f</string>
          <string>/etc/pf.conf</string>
</array>

and add the line <string>-e</string> to ultimately make it like this:

<array>
         <string>pfctl</string>
         <string>-e</string>
         <string>-f</string>
         <string>/etc/pf.conf</string>
</array>

That should do it.

Caveat: Apple no longer allows to change the launch demon files just like that (not with sudo, nor chmod, nor anything else). The only way is to tinker with the System Integrity Protection settings: boot into recovery mode and launch terminal. Check the SIP status with csrutil status, it should generally be enabled. Disable it with csrutil disable and reboot in normal mode and then do the changes to the plist file as discussed above. Once done, go back to recovery mode and re-enable the protection (it's in place for good reason) by issuing csrutil enable.

Explanation: One can check by issuing the ifconfig command that 127.0.0.1 is already the (default) alias for localhost lo0 - this fact is being used to avoid having to add an extra alias for localhost and to simply use the default address in the pf.conf file.

UPDATE: Unfortunately, it seems as though loading the file at startup does not work. I am still trying to get help to have it sorted. Until then, running sudo pfctl -f /etc/pf.conf after starting up does the trick.


Solution 4:

This worked well for me:

  • Enable firewall via System Preferences
  • Create ipfw startup file as described here: https://serverfault.com/a/235124/94860
  • Add the following line to the startup file, as described here: http://xeiam.com/port-forwarding-80-to-8080-using-ipfw-on-mac-os-x/

    add 100 fwd 127.0.0.1,8080 tcp from any to any 80 in