How do I drop outgoing packets to specific host/port?
I want to test something locally. For that, I'd like to be able to drop outgoing packets sent to a specific host/port. I tried messing around with pf rules using Murus (the non-free version), but have been unsuccessful.
I am comfortable in the terminal, but am unsure where to make any changes and how to apply them. I am familiar with iptables on linux.
Can I get some direction on how to achieve this?
Solution 1:
To permanently block outgoing traffic to specific domains and/or ports you should create a new anchor file and add it to pf.conf.
-
Create an anchor file org.user.block.out in /private/etc/pf.anchors
sudo touch /private/etc/pf.anchors/org.user.block.out
with the following content and a trailing empty line
mybadtcphosts = "{ www.domain.com, domain.com, 135.0.9.17, 10.0.0.17 }" mybadtcpports = "{ 443, 80 }" mybadudphosts = "{ www.domain3.com, domain3.com, 27.134.89.124, 192.168.5.37 }" mybadudpports = "{ 53, 5353 }" block drop out proto tcp from any to $mybadtcphosts port $mybadtcpports block drop out proto udp from any to $mybadudphosts port $mybadudpports
The additional domain names/IP addresses in mybad*hosts are just an example how to add additional domains. The same goes for the ports 80/5353 in mybad*ports.
A simple but less flexible solution is:
block drop out proto tcp from any to domain.com port 80
-
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/*" dummynet-anchor "com.apple/*" anchor "com.apple/*" anchor "org.user.block.out" load anchor "com.apple" from "/etc/pf.anchors/com.apple" load anchor "org.user.block.out" from "/etc/pf.anchors/org.user.block.out"
-
Parse and test your anchor file to make sure there are no errors:
sudo pfctl -vnf /etc/pf.anchors/org.user.block.out
-
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 if El Capitan is installed to accomplish this. After editing the file reenable SIP. After rebooting your Mac pf will be enabled (that's the -e option).
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.
Murus:
Open Murus. Click the gear in the configuration panel to create a custom rule:
Enter all necessary details:
Hit the blue button Add Custom PF rule and start PF in the upper right corner with the rightwards arrowhead (or "play" button).
Solution 2:
You could use the PF firewall:
Add this line to /etc/pf.conf to drop all packets to the given ip:port
block drop out quick proto tcp to 192.168.1.103 port 80
After changing pf.conf you should reload it with
sudo pfctl -f /etc/pf.conf
Eventually you will have to enable it with
sudo pfctl -e