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.

0

4 Answers 4

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/

4
  • 1
    Worked perfectly! Aug 19, 2016 at 14:30
  • 22
    and from the mentioned article, to remove it, sudo pfctl -F all -f /etc/pf.conf, and to display your current port forwarding rules, sudo pfctl -s nat
    – Brad Parks
    Jan 17, 2017 at 14:46
  • 5
    keep in mind that this solution doesn't add rules but replaces any other rule loaded before, including the pf.conf file Jan 28, 2018 at 21:54
  • Caution, this answer breaks access directly to port 8080 in weird ways. This answer is better: apple.stackexchange.com/a/332603
    – Scott B
    Feb 14, 2023 at 17:58
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
15
  • 9
    Why isn't there a simple command to do this anymore? It's too complicated now. Aug 5, 2016 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 stackoverflow.com/questions/40695684/…
    – Sudhir N
    Nov 19, 2016 at 17:30
  • Does not seem to work when forwarding port to a VM which is running on parallels desktop
    – Sudhir N
    Nov 19, 2016 at 18:17
  • 1
    @suhir's question: apple.stackexchange.com/questions/262708/…
    – Efren
    Jun 6, 2017 at 6:52
  • 1
    @JamesCushing In Catalina you can edit it booted to Recovery Mode! Added a description in my answer...
    – klanomath
    Apr 1, 2020 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
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .