I want to forward requests from 192.168.99.100:80
to 127.0.0.1:8000
. This is how I'd do it in linux using iptables
:
iptables -t nat -A OUTPUT -p tcp --dport 80 -d 192.168.99.100 -j DNAT --to-destination 127.0.0.1:8000
How do I do the same thing in MacOS X? I tried out a combination of ipfw
commands without much success:
ipfw add fwd 127.0.0.1,8000 tcp from any to 192.168.99.100 80
(Success for me is pointing a browser at http://192.168.99.100
and getting a response back from a development server that I have running on localhost:8000
)
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:
(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:
I was able to get this working using the
ifconfig
andpfctl
commands on Mac 10.10.2. With the following approach I'm successfully mapping127.0.0.1:3000
tomydomain.com
locally on my machine.In your command line enter the following two commands to forward connections to
127.0.0.1:3000
to10.0.0.1
:Then edit your
/etc/hosts
or/private/etc/hosts
file and add the following line to map your domain to10.0.0.1
.After you save your hosts file flush your local DNS:
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.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 thepf.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 thepf.conf
file. Open thepf.conf
file with sudo and addrdr-anchor "redirection"
after the last rdr-anchor line (which isrdr-anchor "com.apple/*"
) and addload anchor "redirection" from "/etc/pf.anchors/redirection"
at the end.Ultimately, this is what the pf.conf file should look like:
And that's almost it. Just restart
pfctl
by issuingsudo pfctl -d
to disable it first and thensudo 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:and add the line
<string>-e</string>
to ultimately make it like this: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 withcsrutil 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 issuingcsrutil enable
.Explanation: One can check by issuing the
ifconfig
command that127.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 thepf.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.This worked well for me:
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
From 10.5 on, OS X comes with a new, application-oriented firewall instead of
ipfw
. But ipfw is still installed. If you have trouble with its syntax, check out graphical frontends likeWaterRoof
orFlying Buttress
.HTH, PEra
order of rules is important, make sure there is no "deny all" before your allow rules, or something like that.
Your command seems to be missing a rule number; try:
(if you aren't running as root, you'll have to prefix it with sudo). Another thing to check is that the firewall is enabled:
If it comes back with the value 0 (off), turn it on with:
... and then arrange for it to get reenabled when the computer reboots. The "proper" way to do this is probably to create a launchd item (Lingon makes this fairly easy). Or just use one of the GUI tools PEra mentioned, and let it take care of the details.