67

The old utility ipfw was discouraged in recent versions of Mac OS X and is now gone from El Capitan.

What is the modern way to do port forwarding in El Capitan?

I simply want port 80 to forward to port 8080.

klanomath
  • 66,391
  • 9
  • 130
  • 201
Basil Bourque
  • 12,634

4 Answers4

94

To forward all port 80 traffic to port 8080, you can enter the following from the Terminal command line.

echo "
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
" | sudo pfctl -ef -

Taken from https://salferrarello.com/mac-pfctl-port-forwarding/

37

The modern way to forward ports in El Capitan is using pf. In the example below all port 80 requests are forwarded to port 8080 on the same host. Please adjust the redirections to your needs.

  1. Create an anchor file org.user.forwarding in /private/etc/pf.anchors

    sudo touch /private/etc/pf.anchors/org.user.forwarding
    

    with the following content and a trailing empty line

    rdr pass on lo0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
    rdr pass on en0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
    rdr pass on en1 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
    

    or

    rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
    
  2. Modify the file /private/etc/pf.conf but keep a trailing empty line

    original file:

    scrub-anchor "com.apple/*"
    nat-anchor "com.apple/*"
    rdr-anchor "com.apple/*"
    dummynet-anchor "com.apple/*"
    anchor "com.apple/*"
    load anchor "com.apple" from "/etc/pf.anchors/com.apple"
    

    to

    scrub-anchor "com.apple/*"
    nat-anchor "com.apple/*"
    rdr-anchor "com.apple/*"
    rdr-anchor "org.user.forwarding"
    dummynet-anchor "com.apple/*"
    anchor "com.apple/*"
    load anchor "com.apple" from "/etc/pf.anchors/com.apple"
    load anchor "org.user.forwarding" from "/etc/pf.anchors/org.user.forwarding"
    
  3. Parse and test your anchor file to make sure there are no errors:

    sudo pfctl -vnf /etc/pf.anchors/org.user.forwarding
    
  4. Now modify /System/Library/LaunchDaemons/com.apple.pfctl.plist from

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

    to

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

    You have to disable System Integrity Protection to accomplish this. After editing the file reenable SIP. After rebooting your Mac pf will be enabled (that's the -e option).

    In macOS 10.15 Catalina (and its read-only system volume) you have to edit the launch daemon in Recovery Mode. SIP is disabled by default in Recovery Mode - so no need to execute csrutil:

    /Volumes/Name_of_boot_volume/usr/bin/nano /Volumes/Name_of_boot_volume/System/Library/LaunchDaemons/com.apple.pfctl.plist
    

    with the default boot volume name Macintosh HD this is:

    /Volumes/Macintosh\ HD/usr/bin/nano /Volumes/Macintosh\ HD/System/Library/LaunchDaemons/com.apple.pfctl.plist
    

    Alternatively you may create your own launch daemon similar to the answer here: Using Server 5.0.15 to share internet WITHOUT internet sharing.

After a system update or upgrade some of the original files above may have been replaced and you have to reapply all changes.

If you want to forward across different interfaces you have to enable this in /etc/sysctl.conf:

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
klanomath
  • 66,391
  • 9
  • 130
  • 201
  • 9
    Why isn't there a simple command to do this anymore? It's too complicated now. – Dr.Knowitall Aug 05 '16 at 21:55
  • @klanomath -- this works and i can forward port x to port y on 127.0.0.1 etc, but i am unable to forward ports to my windows vm running on paralles desktop, Any idea ? here's my question http://stackoverflow.com/questions/40695684/osx-elcapitan-portforwarding-to-parallels-vm-using-pfctl – Sudhir N Nov 19 '16 at 17:30
  • Does not seem to work when forwarding port to a VM which is running on parallels desktop – Sudhir N Nov 19 '16 at 18:17
  • @sudhir You did not successfully link to your new Question. By default a Parallels VM is not visible to the network, as a security precaution. You can change a setting in the VM’s configuration to make the VM visible. And remember, ping is your friend in diagnosing network problems. – Basil Bourque Feb 28 '17 at 20:05
  • 1
    @suhir's question: https://apple.stackexchange.com/questions/262708/os-x-el-capitan-port-forwarding-to-parallels-vm-using-pfctl – Efren Jun 06 '17 at 06:52
  • @klanomath What is the "one command" we should "see below"? I do not follow. – Basil Bourque Jun 06 '17 at 07:55
  • @BasilBourque When I wrote the comment, Sal Ferrarello's answer had less up-votes than mine ;-). It doesn't survive a restart though and you have to enter it again after a reboot... – klanomath Jun 06 '17 at 08:01
  • @klanomath Thanks. FYI, you can link to another Answer using the URL found in the "share" link on that Answer. Ex: See the Answer by Sal Ferrarello – Basil Bourque Jun 06 '17 at 08:13
  • @BasilBourque I was in a hurry probably and just wrote a quick and dirty comment (without a proper link)... – klanomath Jun 06 '17 at 08:18
  • I'm running Puma-dev which runs its HTTPS on 9283. I added in org.user.forwarding : rdr pass on lo0 inet proto tcp from any to any port 443 -> 127.0.0.1 port 9283 and the relative anchors in pf.conf, restarted them with the commands sudo pfctl -f /etc/pf.conf . But when I try to access the website via mywebsite.dev I get no server response. But if I explicitly write the port, it works. What perchance might I be missing here? – Trip Jan 04 '18 at 12:47
  • I am on High Sierra and am getting a syntax error when I test (step #3) - I copy/pasted the above into /private/etc/pf.anchors/org.user.forwarding - any suggestions as to what to look for? – allicarn Jan 29 '18 at 17:55
  • @allicarn Did you add an empty new line (1x enter key) at the end of both files? – klanomath Jan 29 '18 at 18:09
  • That was it! Sorry, I missed it in your instructions. Thanks! – allicarn Jan 30 '18 at 14:16
  • The method of editing /System/Library/LaunchDaemons/com.apple.pfctl.plist doesn't work in Catalina due to the read-only file system (even with SIP disabled) – James Cushing Apr 01 '20 at 11:03
  • 1
    @JamesCushing In Catalina you can edit it booted to Recovery Mode! Added a description in my answer... – klanomath Apr 01 '20 at 11:26
9

To extend solution from @sal-ferrarello answer, I created two super-basic Shell Scripts to enable or disable redirecting without compromising already existing entries in pf.

I. First find what entries do you already have with:

sudo pfctl -s nat

My output was like:

No ALTQ support in kernel
ALTQ related functions disabled
nat-anchor "com.apple/*" all
rdr-anchor "com.apple/*" all

What interests us is actual entries so ommit first two info lines.

II. Create enable.sh script:

#!/bin/sh
echo "
nat-anchor \"com.apple/*\" all
rdr-anchor \"com.apple/*\" all
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
" | sudo pfctl -ef -
sudo pfctl -s nat

First two lines after echo are the entries that were already there. Third line is with new redirect – in this case 80 to 8080. At the end we call sudo pfctl -s nat to see if changes were applied.

III. Create disable.sh script:

Similar to enable.sh we create script, but without 80->8080 redirect, but with previous already existing entries:

#!/bin/sh
echo "
nat-anchor \"com.apple/*\" all
rdr-anchor \"com.apple/*\" all
" | sudo pfctl -ef -
sudo pfctl -s nat
cadavre
  • 191
2

I've developed an App for port forwarding on macOS. You can check it out here:

https://github.com/hronro/iPortForwarder

It allows you to easily forward a single port or a range of ports without modifying the system firewall.

scrrenshot

hronro
  • 121