Murus firewall - redirect an ip to localhost web server
IMHO your web server environment is flawed because you may simply replace 35.166.133.11 by 192.168.1.2 in the sources instead of routing packets from 192.168.1.2 to lo0 (35.166.133.11 keep state) and later redirecting them from lo0 to the source en0(192.168.1.2) again.

But in other setups it may be useful. E.g. if you run a second web server mimicking the Amazon Linux AMI Test Page at localhost or 192.168.1.3/4/5.



rdr only accepts incoming packets. Thus, you have to first route those packets to lo0, then add an rdr rule there (which will catch them as they will be routed in from "somewhere") to send them to your local web server at 192.168.1.2.

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 en0 to 35.166.133.11 port 80 -&gt; 192.168.1.2 port 80
# Step "1". Route new IPv4 TCP connections leaving en0 to lo0
pass out on en0 route-to lo0 proto tcp from en0 to 35.166.133.11 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 en0 to 35.166.133.11 port 80 -&gt; 192.168.1.2 port 80
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 35.166.133.11 port 80 keep state


In the above example you would have to change the interface en0 to e.g. en1 if en0 doesn't have the IP 192.168.1.2 but en1 does.

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 inet proto tcp from 192.168.1.2 to 35.166.133.11 port = 80 -&gt; 192.168.1.2 port 80
anchor "/*" all
pass out on en0 route-to lo0 inet proto tcp from 192.168.1.2 to 35.166.133.11 port = 80 flags S/SA keep state
dummynet-anchor "/*" all


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

After shutting down the web server on port 80 you can test this with netcat:

In a terminal window enter sudo nc -l 80. In a second terminal window enter sudo nc 35.166.133.11 80. Now enter some text in the second nc session and hit the enter key. The text should appear in the first, "listening" nc session. You can also enter text in the listening session which should appear in the second window. To end the session enter ctrlD in either of the two nc sessions.