6

I am trying to redirect the outbound traffic to destination port 80 to the local proxy port 127.0.0.1:8080 without success

/etc/pf.anchors/com.forwarding

rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080

/etc/pf.conf

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

Then:

sudo sysctl net.inet.ip.forwarding=1
sudo pfctl -ef /etc/pf.conf

The local traffic 127.0.0.1:80 is redirected to 127.0.0.1:8080, but not the external, the one towards internet.

3
  • For anyone that doesn’t need to artisanaly build a proxy from the ground up so they can master all the parts, there’s an app for this: charlesproxy.com
    – bmike
    Commented Dec 17, 2017 at 17:58
  • 1
    Thank you, but my purpose is not the proxy itself, but the most important thing is to make this rule work.
    – aminovich
    Commented Dec 17, 2017 at 21:55
  • Excellent - I just wanted people looking for an easy proxy to have that option. Knowledge is powerful and deep knowledge if this networking means you can do so many other things. Looking forward to an answer and perhaps to learn something myself
    – bmike
    Commented Dec 17, 2017 at 21:57

1 Answer 1

7

You can only redirect incoming traffic. Any outgoing traffic to port 80 isn't affected by your rdr rule.

To redirect outgoing traffic to port 80 you have to re-route it first to lo0 then redirect it to the proxy port:

The order in the config file is necessarily rdr incomming packets, then filter packets (like pass), but chronologically the 2nd rule will hit first (on en0), which will then activate the first rule (on lo0).

# Step "2". redirect those same packets that were routed to lo0 below
rdr pass log on lo0 proto tcp from any to any port 80 -> 127.0.0.1 port 8080
# Step "1". Route new IPv4 TCP connections leaving en0 to lo0
pass out on en0 route-to lo0 proto tcp from en0 to any port 80 keep state

in pf.conf this would look like this:

...
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
rdr pass log on lo0 proto tcp from any to any port 80 -> 127.0.0.1 port 8080
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
pass out on en0 route-to lo0 proto tcp from en0 to any port 80 keep state

In the above example I assume en0 is your only outbound en interface.

Unload your current pf.conf and stop pf: sudo pfctl -d. Then add the two additional lines above. After modifying pf.conf check the syntax of the file with sudo pfctl -vnf /etc/pf.conf which should result in the following output:

pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.

scrub-anchor "/*" all fragment reassemble
nat-anchor "/*" all
rdr-anchor "/*" all
rdr pass log on lo0 proto tcp from any to any port 80 -> 127.0.0.1 port 8080
anchor "/*" all
pass out on en0 route-to lo0 proto tcp from en0 to any port 80 flags S/SA keep state
dummynet-anchor "/*" all

and if successful load it with sudo pfctl -e -f /etc/pf.conf.


A proper system and proxy configuration (and well-behaving apps) don't require such pf rules!

1
  • Yeah! it works, many thanks for your explanations, it helps me a lot.
    – aminovich
    Commented Dec 18, 2017 at 8:18

You must log in to answer this question.

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