Geoip Filtering with Caddy and FirewallD
By Taha • 5 minutes read •
- GeoIP filtering is a security technique that controls access to a website, server or online resource based on the geographical location of the incoming IP address. This method is often used to restrict access from certain countries or regions associated with high levels of suspicious or malicious activity, such as spam, hacking attempts or unauthorised access.
- Today I’m going to explain how to set up GeoIP filtering with Caddy and FirewallD.
- I’ve explained how to set up Caddy in my previous articles: Setting Up Caddy Web Server
Step 1: Select a GeoIP Database for Caddy
I prefer the GeoLite2 database for Caddy. If you have a Maxmind membership you can use it too. If you don’t have a Maxmind membership, you can download the GeoLite2 database from the following link: https://github.com/P3TERX/GeoLite.mmdb
Note: This database is updated every 3 days.Copy the
GeoLite2-country.mmdb
URL from the releases page and download theGeoLite2-country.mmdb
file to your server.
Step 2: Install maxmind_geolocation Plugin for Caddy
To use the maxmind geolocation module with Caddy, you need to download the module with the following command:
Step 3: Set Up Caddy for GeoIP Filtering
Open the
Caddyfile
with your preferred text editor.Add the following lines to the
Caddyfile
:()
Create a new file named
Geofilter
in the/etc/caddy
directory.Then add the countries you want to allow to the
Geofilter
file. We do not want to block requests from local addresses. So we add local addresses to the Geofilter file as shown below. For example:Note
If you are using CloudFlare proxy, you should add the CloudFlare IP ranges to the
Geofilter
file. For example:If you want to display a custom error page for blocked countries, you can add the following lines to the end of the
Geofilter
fileThen save this file and open the
Caddyfile
again.Add the following line to the
Caddyfile
:Then save this file and restart Caddy.
Step 4: Test the GeoIP Filtering for Caddy
If you have a another server in a blocked country or if you have a VPN, you can test the GeoIP filtering by accessing your domain. I tested it with this tool.
Result:
Step 5: Set Up Cronjob for GeoIP Database Update
We can create a cronjob to automatically update the GeoLite2 database.
Create a new file named
geoupdate.sh
in the/usr/local/bin
directory.Add the following lines to the file.
#!/bin/bash &&
Then save the file and make it executable.
Test the script by running it manually.
Then check the GeoLite2 database file.
If the script runs successfully, we can add it to the crontab.
Add the following line to the crontab.
Note
This line will update the GeoLite2 database every Sunday at midnight.
Step 6: Select countries to Allow With FirewallD
The methods described up to this step apply to HTTPS connections. However, we cannot always use HTTPS connections. For example, if we are using a DNS server, we need to use port 53 independently of the Caddy. Or we need to use port 22 for SSH connections. We can use the blocking method through firewalld to block requests to the server port.
I prefer the ipdeny database this step.
Copy the links to the database files for the countries you want to authorise. Then download these databases using the following command:
Note: I will use the Germany and Turkey databases as an example.
Step 7: Set Up FirewallD for GeoIP Filtering
We don’t want to refuse connections from local addresses. So we create a new file called
local.zone
.Then we add the following lines to the
local.zone
file.Then we create a new ipset for the allowed countries.
We add the local addresses to the
ALLOWLIST
ipset.Then we create a new rich rule to allow a server port for the ALLOWLIST ipset.
# SSH # DNS # QUIC
Then we reload the firewall.
We can test these rules by sending a telnet command to another server that is located in a country that is not allowed (or we can use a VPN).
What is the difference between blocking between Caddy and FirewallD?
When using FirewallD for blocking, iptables works in the background and handles the blocking process at Layer 4 (transport layer). This means that the request is intercepted and blocked before it reaches the server’s application layer, providing a performance benefit by reducing the load on higher layers.
In contrast, when blocking with Caddy, the request proceeds through Layer 4 and reaches Layer 7 (Application Layer), where the application itself decides whether to block the request. Blocking at Layer 7 may consume slightly more resources, but it allows for more granular control, as the decision can be based on application-specific rules. However, it typically requires fewer performance resources for fine-grained control than Layer 4 blocking, especially for certain types of content filtering or geo-restriction.
Conclusion
- By implementing GeoIP filtering, organisations and administrators can limit the risks associated with untrusted regions and better protect their networks from cyber threats. This technology is often used in industries where data security is a priority, such as finance, healthcare and government. GeoIP filtering can be configured on firewalls, routers and specific applications, making it a flexible solution for securing network access based on geographical boundaries.