pf-badhost is a simple, easy to use badhost blocker that uses the power of the pf firewall to block many of the internet's biggest irritants. Annoyances such as ssh bruteforcers are largely eliminated. Shodan scans and bots looking for webservers to abuse are stopped dead in their tracks. When used to filter outbound traffic, pf-badhost blocks many seedy, spooky malware containing and/or compromised webhosts.
Filtering performance is exceptional, as the badhost list is stored in a pf table. To quote the OpenBSD FAQ page regarding tables: "the lookup time on a table holding 50,000 addresses is only slightly more than for one holding 50 addresses."
pf-badhost is simple and powerful. The blocklists are pulled from quality, trusted sources. The 'Firehol', 'Emerging Threats' and 'Binary Defense' block lists are used as they are popular, regularly updated lists of the internet's most egregious offenders. The pf-badhost.sh script can easily be expanded to use additional or alternate blocklists.
pf-badhost works best when used in conjunction with unbound-adblock for the ultimate badhost blocking.
How To
• Create a new user (we’ll call ours “_pfbadhost”)
# adduser _pfbadhost
# ftp https://www.geoghegan.ca/scripts/pf-badhost.sh
# mv pf-badhost.sh /usr/local/bin/
# chown root:bin /usr/local/bin/pf-badhost.sh
# vi /etc/doas.conf
permit nopass _pfbadhost cmd cp args /tmp/pf-badhost.txt /etc/
permit nopass _pfbadhost cmd pfctl args -t pfbadhost -T replace -f /etc/pf-badhost.txt
# crontab -u _pfbadhost -e
@midnight /bin/sh /usr/local/bin/pf-badhost.sh
table <pfbadhost> persist file “/etc/pf-badhost.txt”
block in quick on egress from <pfbadhost> to any
block out quick on egress from any to <pfbadhost>
• login to user “_pfbadhost”
# su _pfbadhost
$ sh /usr/local/bin/pf-badhost.sh
# pfctl -f /etc/pf.conf
$ sh /usr/local/bin/pf-badhost.sh
With the nightly cron job, the list will be be regularly updated with the latest known bad hosts.
Note: If you are trying to run pf-badhost on a LAN or are using NAT, you will want to add a rule to your pf.conf appearing BEFORE the pf-badhost rules allowing traffic to and from your local subnet so that you can still access your gateway and any DNS servers.
Something like this should do:
# vi /etc/pf.conf
pass in quick on egress from 192.168.17.0/24
pass out quick on egress from any to 192.168.17.0/24
table persist file “/etc/pf-badhost.txt”
block in quick on egress from <pfbadhost> to any
block out quick on egress from any to <pfbadhost>
# vi /etc/doas.conf
permit nopass _pfbadhost cmd pfctl args -t pfbadhost -T delete 192.168.0.0/16
# vi /usr/local/bin/pf-badhost.sh
# Move banlist into /etc and reload the pf table
mv /tmp/banlist/pf-badhost.txt /tmp/
doas cp /tmp/pf-badhost.txt /etc/
doas pfctl -t pfbadhost -T replace -f /etc/pf-badhost.txt
doas pfctl -t pfbadhost -T delete 192.168.0.0/16
# Copyright 2018 Jordan Geoghegan
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# Download some of the most popular IP Blocklists, you can add any lists here
# you like as long as they have similar formatting to the other lists.
# Make temp folder to hold all files
mkdir /tmp/pfbadhost
# Download popular IP blocklists and parse
cd /tmp/pfbadhost
ftp https://www.binarydefense.com/banlist.txt
ftp https://rules.emergingthreats.net/blockrules/compromised-ips.txt
ftp https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt
ftp https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level3.netset
ftp https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level2.netset
ftp https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset
perl -lne 'print if ! /^\s*(#.*)?$/' *.txt *.netset | sort -uV > pf-badhost.txt
# Block Shodan
ftp https://isc.sans.edu/api/threatlist/shodan/shodan.txt
egrep -o '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}' shodan.txt >> pf-badhost.txt
# Move banlist into /etc and reload the pf table
mv /tmp/pfbadhost/pf-badhost.txt /tmp/
doas cp /tmp/pf-badhost.txt /etc/
doas pfctl -t pfbadhost -T replace -f /etc/pf-badhost.txt
# Clean up after ourselves
rm -r /tmp/pfbadhost
rm /tmp/pf-badhost.txt