Country Code Filtering Not Working

It seems like country code filtering is not working for me. I have setup a rule to block traffic to specific country codes. Here are my rules:

# show firewall ipv4 forward
 filter {
     default-action drop
     default-log
     description "FORWARD is traffic bound from one interface to another"
     rule 10 {
         action jump
         jump-target CONN_FILTER
     }
     rule 11 {
         action jump
         description "Block TO China, Venezuela, Russia"
         destination {
             geoip {
                 country-code cn
                 country-code ru
                 country-code ve
             }
         }
         jump-target BLOCKED_COUNTRIES
     }
     rule 12 {
         action jump
         description "Block from China, Venezuela, Russia"
         jump-target BLOCKED_COUNTRIES
         source {
             geoip {
                 country-code cn
                 country-code ru
                 country-code ve
             }
         }
     }

Here you can see I send all TO and FROM these countries to a rule called BLOCKED_COUNTRIES.

# show firewall ipv4 name BLOCKED_COUNTRIES
 default-action drop
 default-log
 description "Block traffic from the assigned country codes"

However, when monitoring DNS traffic, I see traffic specifically going to China unimpeded. I can in fact ping these Chinese IP’s successfully from a client on this network.
The IP’s:

1.12.0.4
1.12.0.1
1.12.0.29
1.12.0.71

Any ideas why it’s not blocked?

But before rules that use country code, you have:

rule 10 {
         action jump
         jump-target CONN_FILTER
     }

What happens there?

Should just allow existing connections:

# show firewall ipv4 name CONN_FILTER
 default-action return
 description "Allow existing connections block invalid"
 rule 10 {
     action accept
     state established
     state related
 }
 rule 20 {
     action drop
     log
     state invalid
 }

I searched for some other China based IP’s, and this one in particular is blocked and logged as being blocked by my country rule shown earlier (log is enabled):
221.192.199.49

So maybe the geo service doesn’t recognize the 1.12.0.* addresses as being Chinese?

Vyos uses this DB for country lookups: https://db-ip.com/

And you can check if IP address is present in the configuration generated by nftables.
0- References of named sets and elements (feature from nftables used here: Sets - nftables wiki

1- Identify named set :

# Example:
vyos@ROCK# sudo nft list table ip vyos_filter | grep GEO
        set GEOIP_CC_forward_filter_11 {
        set GEOIP_CC_forward_filter_12 {
        set GEOIP_CC_output_filter_22 {
                ip daddr @GEOIP_CC_forward_filter_11 counter packets 0 bytes 0 drop comment "ipv4-FWD-filter-11"
                ip saddr @GEOIP_CC_forward_filter_12 counter packets 0 bytes 0 drop comment "ipv4-FWD-filter-12"
                ip daddr @GEOIP_CC_output_filter_22 log prefix "[ipv4-OUT-filter-22-A]" counter packets 0 bytes 0 accept comment "ipv4-OUT-filter-22"
[edit]
vyos@ROCK# 
  1. Check if IP address (element) is part of those sets, or not:
# Example looking 10.0.0.1, which you know it shouldn't be present
vyos@ROCK# sudo nft get element ip vyos_filter GEOIP_CC_forward_filter_11 { 10.0 
Error: Could not process rule: No such file or directory
get element ip vyos_filter GEOIP_CC_forward_filter_11 { 10.0.0.1 }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[edit]
vyos@ROCK# 

# Example of IP that you've shared and you know it being blocked
vyos@ROCK# sudo nft get element ip vyos_filter GEOIP_CC_forward_filter_11 { 221. 
table ip vyos_filter {
        set GEOIP_CC_forward_filter_11 {
                type ipv4_addr
                flags interval
                elements = { 221.192.0.0-221.199.207.255 }
        }
}
[edit]
vyos@ROCK# 

Repeat using any IP you like and check output

This confirms what I am saying…

221.192.199.49 is being blocked
1.12.0.1 is not being blocked, but is in a blocked region.

What do I do to get proper blocking of those being missed?

What version of VyOS do you use?

When creating a geoip firewall rule it will be based on the IP-addresses included in /usr/share/vyos-geoip/dbip-country-lite.csv.gz

This is always updated to latest available at time of compile of the ISO your current install is based on.

You can also do it manually by download:

https://download.db-ip.com/free/dbip-country-lite-${DATE_SUFFIX}.csv.gz

or by issue this command (if your VyOS is connected to Internet which I assume it is since you do geoip filtering) when logged in to have VyOS do this for you (or through a script to do so like once a day or once a week or so):

update geoip

For this particular case it would be interresting to know if the ip such as 1.12.0.1 exists in the current version of /usr/share/vyos-geoip/dbip-country-lite.csv.gz or not?

Also related:

Free versions of the IP to Country database

The DB-IP Lite databases are subsets of the commercial database with reduced coverage and accuracy. Lite IP to location database downloads are updated monthly and distributed under the Creative Commons Attribution License.

Looks like the free edition except for not having the same coverage as their subscription edition also only updates once a month instead of once a day.

Note:

When I tried to download current version from IP to Country Lite Free Database Download which should be 26.2 MB I only received about 4 MB so perhaps something is broken with this file?

Scratch that, the sha1sum validates once the file is extracted.

Looking at the september version of the file:

https://download.db-ip.com/free/dbip-country-lite-2024-09.csv.gz

I find these hits for 1.12.*:

1.12.0.0,1.12.0.255,SG
1.12.1.0,1.12.2.255,CN
1.12.3.0,1.12.3.255,SG
1.12.4.0,1.12.5.255,CN
1.12.6.0,1.12.6.255,SG
1.12.7.0,1.12.8.255,CN
1.12.9.0,1.12.9.255,SG
1.12.10.0,1.12.10.255,CN
1.12.11.0,1.12.11.255,SG
1.12.12.0,1.12.13.255,CN
1.12.14.0,1.12.14.255,JP
1.12.15.0,1.12.15.255,US
1.12.16.0,1.12.33.255,CN
1.12.34.0,1.12.34.255,SG
1.12.35.0,1.15.255.255,CN

So it looks like your 1.12.0.* are being identified as SG aka Singapore.

Which is kind of odd since that whole 1.12.0.0/14 block belongs to a chinese ISP according to whois (and also seems to be routed like that when you for example traceroute 1.12.15.1 which according to this geodb should be in US):

inetnum:        1.12.0.0 - 1.15.255.255
netname:        TencentCloud
descr:          Tencent cloud computing (Beijing) Co., Ltd.
descr:          Floor 6, Yinke Building,38 Haidian St,
descr:          Haidian District Beijing
country:        CN
admin-c:        JT1125-AP
tech-c:         JX1747-AP
abuse-c:        AC1601-AP
status:         ALLOCATED PORTABLE
mnt-by:         MAINT-CNNIC-AP
mnt-irt:        IRT-TENCENTCLOUD-CN
mnt-lower:      MAINT-CNNIC-AP
mnt-routes:     MAINT-CNNIC-AP
last-modified:  2023-11-28T00:51:33Z
source:         APNIC

...

route:          1.12.0.0/14
origin:         AS45090
descr:          China Internet Network Information Center
                Floor1, Building No.1 C/-Chinese Academy of Sciences
                4, South 4th Street
                Haidian District,
mnt-by:         MAINT-CNNIC-AP
last-modified:  2020-02-25T01:10:58Z
source:         APNIC

So you should to file this as a report to db-ip.com.

Edit: I have sent a report myself just now (would be good if more than me do this) and got a reply that if they agree with the report the changes will be available within 15 days.

1 Like

Every time I commit after updating a firewall rule, I see this:

# commit
Updating GeoIP. Please wait...

I did grab that csv file, and I believe this is the relevant line:

1.12.0.0,1.12.0.255,SG

If I’m understanding right, that means this IP is understood to be in Singapore, even though it’s actually in China.

I think that line is just that the firewall script extracts the IP-addresses based on country code from the local geodb file - not that it will each time download the current file from db-ip.com.

But yes - your issue is that the free edition of db-ip.com geodb identifies 1.12.0.0 → 1.12.0.255 as Singapore (SG) and not China (CN). It also identifies 1.12.15.x as US and so on.

I have no idea if their commercial geodb knows better but I have filed this as a report to db-ip.com over at 1.12.15.1 - United States - China Internet Network Information Center - IP address geolocation (or whatever IP you lookup) and at the bottom you get a reportlink to fill out some more information at before sending the report. And it would probably help if you also file a report.

Edit:

Here it is in the sourcecode:

which ends up at:

which confirms that its the local geodb file that the firewall script updates from (that is based on your ruleset it will extract all IP-ranges that matches the countrycode and push those IP-ranges into the actual nftables ruleset).

Thanks for pointing this out - I too thought it was pulling the latest copy same as “update geoip”

edit: Any idea how to script it so that I can update it once a fortnight via system task-scheduler ?

The quick and dirty method would probably be to just grab the current months file the same way as the vyos-build does this:

#!/bin/sh

# Geolocation data provided by DB-IP.com
# License: https://creativecommons.org/licenses/by/4.0/ (CC BY 4.0)

DATE_SUFFIX=$(date +%Y-%m)
URL="https://download.db-ip.com/free/dbip-country-lite-${DATE_SUFFIX}.csv.gz"
OUT_PATH="/usr/share/vyos-geoip/dbip-country-lite.csv.gz"

mkdir -p $(dirname $OUT_PATH)
wget -O - $URL > $OUT_PATH

if [ $? -ne 0 ]; then
    echo "Failed to download GeoIP database"
    rm $OUT_PATH
fi

For a live system you probably also want to add some “dbip-country-lite.csv.gz.lastupdated” or such containing the ${DATE_SUFFIX} which you can check against before downloading approx 28MB every night since the free edition only updates once a month.

That is to save not only your bandwidth but also the bandwidth of this free service (and to lower the risk that they would ban you if you got multiple routers who suddently each night downloads the same file over and over again).

You could probably also add some more checks to fetch IP to Country Lite Free Database Download and parse the “Release” to not fetch a file you already fetched the previous night (since Im not sure they will update that file on the 1st every month so the above ${DATE_SUFFIX} method might be broken or out of sync).

Also adding some checksum control against “SHA1SUM” would probably be handy (note that their checksum is for the extracted file but can be dealt with a pipe or such).

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.