The best way to do this is to define a table and create a rule to block the hosts, in pf.conf
:
table <badhosts> persist
block on fxp0 from <badhosts> to any
And then dynamically add/delete IP addresses from it:
$ pfctl -t badhosts -T add 1.2.3.4
$ pfctl -t badhosts -T delete 1.2.3.4
Other 'table' commands include flush
(remove all), replace
and show
. See man pfctl
for more.
If you want a more permanent list you can keep it in one (or more) files. In pf.conf
:
table <badhosts> persist file "/etc/badguys1" file "/etc/badguys2"
block on fxp0 from <badhosts> to any
You can also add hostnames instead of IP addresses. See the "Tables" section of man pf.conf
and man pfctl
.
Note: The examples above assume that the internet-facing interface is fxp0
, please change according to your setup. Also, keep in mind that the rules in pf.conf
are evaluated sequentially and for block
or pass
rules its the last matching rule that applies. With this ruleset
table <badhosts> persist
block on fxp0 from <badhosts> to any
pass inet tcp from 192.168.0.0/24 to any port 80
and after adding 1.2.3.4 and 192.168.0.10 to the badhosts
table
$ pfctl -t badhosts -T add 1.2.3.4
$ pfctl -t badhosts -T add 192.168.0.10
all traffic from 1.2.3.4 and 192.168.0.10 will be blocked but the second host will be able to make connections to other machines' port 80 because the pass
rule matches and overrides the block
rule.