惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
博客园_首页
H
Help Net Security
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
B
Blog
I
InfoQ
SecWiki News
SecWiki News
T
Tailwind CSS Blog
Spread Privacy
Spread Privacy
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
N
Netflix TechBlog - Medium
P
Palo Alto Networks Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
M
MIT News - Artificial intelligence
S
Schneier on Security
T
Threat Research - Cisco Blogs
F
Fortinet All Blogs
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
MyScale Blog
MyScale Blog
The Cloudflare Blog
Recent Announcements
Recent Announcements
Security Latest
Security Latest
G
GRAHAM CLULEY
IT之家
IT之家
Y
Y Combinator Blog
The Last Watchdog
The Last Watchdog
腾讯CDC
Google DeepMind News
Google DeepMind News
V
V2EX
S
Securelist
TaoSecurity Blog
TaoSecurity Blog
B
Blog RSS Feed
S
SegmentFault 最新的问题
博客园 - 叶小钗
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
Project Zero
Project Zero
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
F
Full Disclosure

IT Notes - pf

IT Notes
IT Notes
Stefano Marinelli · 2024-06-16 · via IT Notes - pf

In recent times, there has been an exponential increase in malicious (or simply rude) traffic from specific countries. Alternatively, sometimes we simply do not need visitors from other parts of the world accessing our server for various reasons.

On FreeBSD, this operation is very simple, and I have been using a reliable and secure system to manage it automatically for a long time. Of course, as with all geolocation blocks, there is never certainty about the result, as sometimes certain IP blocks officially belong to one country but are actually used by another, or users can resort to VPNs to bypass these types of blocks. However, it remains a valid method to filter out unwanted traffic, especially when it comes to rogue bots that do not respect the robots.txt file and bombard our machines with repeated requests, generating real DDoS attacks.

Installation of ipdbtools

First, install the ipdbtools package (http://www.freshports.org/sysutils/ipdbtools):

pkg install ipdbtools

Next, download the updated global lists:

/usr/local/bin/ipdb-update.sh

Configuring pf

Then, modify the pf configuration. To do this, add the following line at the beginning of the filtering part of your firewall configuration (/etc/pf.conf):

block drop log quick from <blocked_countries>

At this point, simply type:

service pf reload

to reload the pf configuration and start considering the values in the <blocked_countries> table.

If you do not already have a pf.conf because the only requirement was this, simply insert this line in an empty pf.conf and then run:

service pf enable
service pf start

Updating the Blocked Countries List

Next, create a file (in my case, I called it /usr/local/sbin/update_blocked_countries.sh) with content similar to the one below. Replace "CC" with the country codes you want to block. For example, to block France, Germany, and Italy, insert "FR:DE:IT".

UPDATE: pf seems to have difficulty processing very large lists, resulting in errors. For this reason, I modified the following script to insert the lists in 'chunks,' in order to prevent the procedure from failing.

#!/bin/sh

# Original file containing the IP addresses
original_file="/var/db/blocked_countries.txt"

# Generate the blocked countries file
/usr/local/bin/ipup -p -t CC > $original_file

# Number of records per batch
batch_size=10000

# Temporary file for the current batch
temp_file="/tmp/blocked_countries_temp.txt"

# Initialize the line counter
line_count=0

# Function to add a batch of records
add_batch() {
    echo "Adding records from $temp_file to pf table..."
    /sbin/pfctl -t blocked_countries -T add -f "$temp_file"
    if [ $? -ne 0 ]; then
        echo "Error adding records from $temp_file. Exiting."
        exit 1
    fi
    # Empty the temporary file
    > $temp_file
}

# Replace the table with an empty file to avoid conflicts
echo -n > /tmp/empty_blocked_countries.txt
/sbin/pfctl -t blocked_countries -T replace -f /tmp/empty_blocked_countries.txt

# Read the original file line by line
while IFS= read -r line; do
    # Add the line to the temporary file
    echo "$line" >> "$temp_file"
    line_count=$((line_count + 1))

    # If we've reached the batch size, add the records and reset the counter
    if [ $line_count -ge $batch_size ]; then
        add_batch
        line_count=0
    fi
done < "$original_file"

# Add any remaining records
if [ $line_count -gt 0 ]; then
    add_batch
fi

echo "All records added successfully."

Make it executable:

chmod a+rx /usr/local/sbin/update_blocked_countries.sh

Running the command /usr/local/sbin/update_blocked_countries.sh will show the status of the operation, for example:

314159 addresses added.

This means that the list has been generated for the inserted country codes, and pf has updated the <blocked_countries> table.

It is advisable to update the lists occasionally since IP ranges "move" from one country to another.

Automating with Cron

We can use cron to perform this task. Edit the file /etc/crontab by adding a line like:

55 9 * * *    root    /usr/local/bin/ipdb-update.sh > /dev/null 2>&1 && /usr/local/sbin/update_blocked_countries.sh

In this example, at 9:55 every day, the databases will be updated, lists generated, and fed to pf.

This setup will also work correctly on a read-only FreeBSD system on UFS, as described in a previous article. The only precaution in this case is to ensure the crontab runs at every boot since, on every machine restart, the contents of /var will be erased and recreated from scratch. Therefore, also add a line like:

@reboot    root    /usr/local/bin/ipdb-update.sh > /dev/null 2>&1 && /usr/local/sbin/update_blocked_countries.sh

Additionally, in a read-only system, you need to add a mount for tmpfs for the /usr/local/etc/ipdb/IPRanges directory in the /etc/fstab file to make it writable:

tmpfs /usr/local/etc/ipdb/IPRanges/     tmpfs rw 0 0