################################################################### # pf-badhost 0.6 OpenBSD Installation Instructions # Copyright 2018-2021 Jordan Geoghegan ################################################################### ################################################################### # Table of Contents: ################################################################### * Upgrade Instructions (upgrade from 0.5) * Fresh Install Instructions * Post Install Notes ################################################################### # Upgrade from pf-badhost 0.5 ################################################################### 1) Download updated script: $ ftp https://geoghegan.ca/pub/pf-badhost/0.6/pf-badhost.sh 2) Install script with appropriate permissions # install -m 755 -o root -g bin pf-badhost.sh /usr/local/bin/pf-badhost 3) Update doas permissions: $ cat /etc/doas.conf ... permit root permit nopass _pfbadhost cmd /sbin/pfctl args -nf /etc/pf.conf permit nopass _pfbadhost cmd /sbin/pfctl args -t pfbadhost -T replace -f /etc/pf-badhost.txt permit nopass _pfbadhost cmd /sbin/pfctl args -t pfbadhost -vT show permit nopass _pfbadhost cmd /sbin/pfctl args -t pfbadhost -T flush # Optional rules for SSH authlog scanning permit nopass _pfbadhost cmd /usr/bin/zcat args -f /var/log/authlog permit nopass _pfbadhost cmd /usr/bin/zcat args -f /var/log/authlog.0.gz ... 4) Update pf.conf. The rules you added to your pf.conf when you installed pf-badhost should be updated to include the following: ... set limit table-entries 500000 table persist counters file "/etc/pf-badhost.txt" block in quick on egress from block out quick on egress to ... 5) pf-badhost has undergone some major changes. Please see the changelog and man page for details. pf-badhost now receives all configuration input via commandline flags. As a result, the "User Configuration Area" has been made optional, and moved to an external file that can be referenced with the '-C' flag. Users are now encouraged to use pf-badhost in a commandline driven fashion. You will need to update your cronjob to reflect these changes in configuration semantics. -- A list of blocklists maintained by members of the pf-badhost community may be found here: https://geoghegan.ca/pub/pf-badhost/data/community_lists.txt A list of common, popular blocklists may be found here: https://geoghegan.ca/pub/pf-badhost/data/popular_lists.txt An example configuration file to be loaded with '-C' may be found here: https://geoghegan.ca/pub/pf-badhost/data/pf-badhost.conf Please read the man page for information on how to configure pf-badhost. The manpage can be found here: https://geoghegan.ca/pub/pf-badhost/0.6/man/man.txt To receive notification of new pf-badhost releases and updates please send an email to 'announce@geoghegan.ca' with a subject line and body of "subscribe pf-badhost" ################################################################### # Fresh Installation Guide ################################################################### 1) Create a new user (we'll call ours "_pfbadhost"): The user should be created with a default shell of "nologin", home folder set to /var/empty/ with no password specified (disables password logins) # useradd -s /sbin/nologin -d /var/empty _pfbadhost 2) Download script: $ ftp https://geoghegan.ca/pub/pf-badhost/0.6/pf-badhost.sh 3) Install script with appropriate permissions: # install -m 755 -o root -g bin pf-badhost.sh /usr/local/bin/pf-badhost 4) Create required files: # install -m 640 -o _pfbadhost -g wheel /dev/null /etc/pf-badhost.txt # install -d -m 755 -o root -g wheel /var/log/pf-badhost # install -m 640 -o _pfbadhost -g wheel /dev/null /var/log/pf-badhost/pf-badhost.log # install -m 640 -o _pfbadhost -g wheel /dev/null /var/log/pf-badhost/pf-badhost.log.0.gz 5.a) OPTIONAL: Install RipGrep, mawk and/or aria2c/wget for greatly improved performance: Note: RipGrep is not available on all CPU architectures, use 'ugrep' if affected. # pkg_add ripgrep mawk aria2 wget 5.b) OPTIONAL: Install subnet aggregation utilities: Note: See 'Post Install Notes' section below for info on installing optional utilities. # pkg_add aggregate6 6) Give user "_pfbadhost" strict doas permission for the exact commands the script needs run as superuser. NOTE: Unlike "sudo", _ALL_ users must be explicitly granted permission to use doas, even the root user. $ cat /etc/doas.conf ... permit root permit nopass _pfbadhost cmd /sbin/pfctl args -nf /etc/pf.conf permit nopass _pfbadhost cmd /sbin/pfctl args -t pfbadhost -T replace -f /etc/pf-badhost.txt # Optional rules for authlog scanning permit nopass _pfbadhost cmd /usr/bin/zcat args -f /var/log/authlog permit nopass _pfbadhost cmd /usr/bin/zcat args -f /var/log/authlog.0.gz ... 7) Add the following lines to your pf.conf: (Putting it higher-up/earlier in the ruleset is recommended) ... set limit table-entries 500000 table persist counters file "/etc/pf-badhost.txt" block in quick on egress from block out quick on egress to ... 8) Reload your pf rule set: # pfctl -f /etc/pf.conf 9) Run pfbadhost as user "_pfbadhost": # doas -u _pfbadhost pf-badhost Note: All configuration options must be passed via commandline options. Please read the manpage for a list of all available configuration options. You can enable additional features such as IPv6, Subnet Aggregation, Geo-Blocking, Bogon Filtering and Authlog Scanning by passing the appropriate flag on the commandline. 10) Edit _pfbadhost users crontab to run pf-badhost every night: # crontab -u _pfbadhost -e ... ~ 0~1 * * * -s pf-badhost ... Note: If you're running an OpenBSD release older than 6.7 you'll have to use a workaround: ... @daily sleep $(echo $((RANDOM\%7200+1))) ; pf-badhost ... Please see the crontab(5) man page for further info Yay! pf-badhost is now installed! With the nightly cron job, the list will be regularly updated with the latest blocklist data. Please read the man page for information on how to configure pf-badhost. The manpage can be found here: https://geoghegan.ca/pub/pf-badhost/0.6/man/man.txt To receive notification of new pf-badhost releases and updates please send an email to 'announce@geoghegan.ca' with a subject line and body of "subscribe pf-badhost" ################################################################### # Post Install Notes: ################################################################### x) pf-badhost is highly configurable and extensible, please read the man page for a list of configuration options and usage examples. x) A list of blocklists run by members of the pf-badhost community may be found here: https://geoghegan.ca/pub/pf-badhost/data/community_lists.txt A list of common, popular blocklists may be found here: https://geoghegan.ca/pub/pf-badhost/data/popular_lists.txt An example configuration file to be loaded with '-C' may be found here: https://geoghegan.ca/pub/pf-badhost/data/pf-badhost.conf x) The script is able to autodetect which (if any) subnet aggregation utilities are installed and will try to "Do The Right Thing(tm)" and fallback to the best available option. If no subnet aggregation utility is found, the script will fallback to using a pure Perl IPv4 aggregator if Perl is installed. Despite its name, "aggregate6" supports both IPv4 and IPv6 addresses and is written in Python, whereas the "aggregate" utility supports only IPv4 addresses and is written in C and uses significantly less memory but runs much slower. For greatly improved performance, aggregate6 can be run with Pypy. If both utilities are installed, the C based "aggregate" utility will be preferred for IPv4 aggregation, but the script will happily function if only one or the other is installed (or neither). --- Note: Subnet aggregation can be enabled with the '-A' switch on the commandline. * "aggregate" can be installed via: # pkg_add aggregate * "aggregate6" can be installed via: # pkg_add aggregate6 * For greatly improved aggregation performance, run aggregate6 with Pypy: # pkg_add pypy # pypy -m pip install wheel aggregate6 # ln -s /usr/local/pypy/bin/aggregate6 /usr/local/bin/aggregate6 * The experimental aggregator "aggy" can be installed like so: ... # pkg_add go $ ftp https://geoghegan.ca/pub/aggy/0.1/aggy.go $ go build aggy.go # install -m 755 -o root -g bin aggy /usr/local/bin/aggy ... x) Regarding Cron Jobs: With the new default cron job, pf-badhost will be run every night at some point between midnight and 2AM, and thus distribute the load of thousands of queries from numerous users over a 2 hour period rather than a matter of seconds. This ensures that use of pf-badhost remains respectful of blocklist provider resources. If you would like to update pf-badhost blocklists at a more frequent interval you can use a modified cron job: --- It is essential that you make use of the crontab randomization feature to ensure use of pf-badhost remains respecful of blocklist provider resources. --- The following example runs pf-badhost every 3 hours at a random minute (this avoids flooding the server with traffic at exactly XX:00) --- Run pf-badhost every 3 hours Example: (you can change '/3' to '/4' to run every 4 hours) Note: Use of the '-s' switch prevents 2 instances of pf-badhost from being run at the same time - which is a good thing. # crontab -u _pfbadhost -e ... ~ */3 * * * -s pf-badhost ...