🛜Blocking (or Allowing) whole Countries or a Provider or a Network with your Ubiquiti Edgerouter

I recently picked up a nice second hand Ubiquiti Edgerouter X from Marktplaats, which is the Dutch Craigslist. I wanted to play with a firewall in my network. This quickly became a complete rebuild of the network with multiple Vlans in my house. Which was enjoyable because exploring and learning is always a good thing.

This learning also counts for the firewall in the Edgerouter (which runs EdgeOS). I had some experience with firewalls in a very far past with a product called Checkpoint Firewall-1. I am unsure if it still exists. The company Checkpoint still does, though.

Playing around with the firewall wasn’t very hard. Of course, you need to learn the interface and the possibilities of the Firewall. I checked three videos on YouTube to get a head start. This video jumpstarted the head start for me.

As I progressed and got all the firewall rules in place as I wanted them, I really wanted to block off certain countries to be able to reach my webserver, which is behind a nginx reverse-proxy. The Ubiquiti doesn’t have preloaded sets of country networks. And I would rather not add all the networks used by a country manually. This is a daunting task. If I check for my country for example, there are 5999 networks (date:2024-01-18). This is impossible. So this must be done smarter.

Adding a complete country to a network-group in EdgeOS

For this solution, we lean heavily on te website http://www.ipdeny.com/ with the following script I wrote.

I saved this script on the Edgerouter in my $HOME directory with the following name: create_networkgroup_countrycode.sh

#!/bin/sh

# Name: creete_networkgroup_asn.sh
# Coder: Marco Janssen (mastodon [@marc0janssen@mastodon.online](https://micro.blog/marc0janssen@mastodon.online))
# date: 2024-01-17 21:30:00
# update: 2024-01-31 21:39:00

if [ $# -eq 0 ]; then
	echo "No parameters provided. Provide a countrycode. Example nl or de"
else
	countrycode="$1"
	NOW=$(date +"%Y%m%d")
	
	echo "*** Downloading networkaddress blocks for countrycode $countrycode"
	curl "http://www.ipdeny.com/ipblocks/data/countries/$countrycode.zone" -o "./$countrycode.zone" -s
	
	echo "*** Writing networkgroup script"
	echo "delete firewall group network-group $countrycode.zone" > "./networkgroup-$countrycode.$NOW.sh"
	echo "set firewall group network-group $countrycode.zone description \"All networks $countrycode\" on $NOW" >> "./networkgroup-$countrycode.$NOW.sh"
	sed -e "s/^/set firewall group network-group $countrycode.zone network /" "./$countrycode.zone" >> "./networkgroup-$countrycode.$NOW.sh"
	cp "./networkgroup-$countrycode.$NOW.sh" nwgs.sh
	
	echo "*** Archiving zone-list"
	mv "$countrycode.zone" "$countrycode.zone.$NOW"
	
	echo 
	echo "Now execute the following commands on the prompt of your Edgerouter"
	echo 
	echo "configure"
	echo ". ./nwgs.sh"
	echo "commit"
	echo "save"
	echo "exit"
fi

What will this script do?

  1. It will check if you give it a parameter with a single country code. For example, nl or dk or de.
  2. Then it will try to download the network address blocks for the country-code and save it in a file. For The Netherlands (if you give it country-code nl) it will create a file called “nl.zone”.
  3. Then it will try to write a script for you which creates a network group in the Edgerouter. The file will be called “networkgroup-nl.<date>.sh (if you give it country-code nl).
  4. The script which is generated in step 3 will be copied to a shorter name “nwgs.sh” for your convenience. You can archive the longer one in step 3 and use the shorter one in this step.
  5. The zone list used in step 3 will also be archiving for you in a format “nl.zone.<date>” (if you give it country-code nl).
  6. Finally, you get further instructions to use the script and create the network-group.

Running the script

  1. Get this script on your Edgerouter (ssh, scp, sftp) and place it in a directory of your likings. I place it in my $HOME on the router.

  2. Name the script “create_networkgroup_countrycode.sh”

  3. Make sure the script is executable: chmod +x ./create_networkgroup_countrycode.sh

  4. Run the script (in this example for The Netherlands, i.e., nl):
    ./create_networkgroup_countrycode.sh nl

  5. Execute the following commands after the script has run.

    configure . ./nwgs.sh commit save exit

A note of warning

For The Netherlands alone it will add 5999 networks to your Edgerouter. (Date: 2024-01-18). To run the generated network group script with the above command . ./nwgs.sh will take you some 18 minutes on the router. The following step commit will take you another 9 minutes on the router. If you now open your Edgerouter GUI, you will see the steps created a network-group called “nl.zone” of 5999 items. To open this group in the GUI takes a long(er) time. A reboot of the router takes 25 minutes with 5999 networks, don’t think your router is bricked…. It just needs loads of time to boot with this kind of lists.

What is next?

Now you have your network-group called “nl.zone” (for this example) in the Edgerouter. You can use it like any other resource in a firewall rule. You can now allow this network-group through your firewall and block all others that are not in this group (so allow only this country to your webserver or whatever). Or you can block this network-group from your webserver and allow all other countries. It’s up to you.

Adding a complete provider to a network-group in EdgeOS

Maybe for you, it is not necessary to allow or block complete countries. I started using the following method, to only allow certain providers in my country to reach my webserver. Why? First, I only share this content with family members so not all networks are needed to achieve this. Second I did not like the long boot times of the Edgerouter with a complete country list. It was not necessary for me to allow a complete country to my server, I just wanted my family members. Why didn’t you just allow their home IP address of their ISP, you would say? Well, they are dynamic, and I would rather not revise the rules often. So I allow their complete provider.

For this solution, I used to following URL’s, but maybe you have beter ones on the internet.

https://www.nirsoft.net/countryip/nl_owner.html

https://asntool.com/

https://www.textcleanr.com/

https://networksdb.io/

  1. Nirsoft gives a nice overview of all the providers with the IP-addressblocks.
  2. ASNTOOL helps to get all the networks in an Autonomous System.
  3. TEXTCLEAR helps to clean up the list you get from ASNTOOL.
  4. NETWORKSDB is an example of a website to find your ASN.

ASN stands for Autonomous System Number in networks. It is a unique identifier that is globally available and allows an autonomous system (AS) to exchange routing information with other ASes. An AS is a large network or group of networks that operates under a single routing policy. Each AS is assigned a unique ASN, which is a number used to differentiate and identify the AS in the global routing system. ASNs are essential for network operators to control routing within their networks and facilitate the exchange of routing information.

Save the following script in the $HOME of your Edgerouter (or any directory of your likings). And give it the name “create_networkgroup_asn.sh”.

#!/bin/bash

# Name: create_networkgroup_asn.sh
# Coder: Marco Janssen (mastodon [@marc0janssen@mastodon.online](https://micro.blog/marc0janssen@mastodon.online))
# date: 2024-01-17 21:30:00
# update: 2024-01-31 20:50:00

print_usage() {
  echo "No parameters provided. Provide an ASN with IP blocks. Example: AS1136."
}

create_networkgroup_script() {
  local asn
  local temp_filename
  local output_filename
  local archive_filename
  local networkgroup_script_filename
  
  asn="$1"
  temp_filename=".temp.txt"
  output_filename="$asn.txt"
  archive_filename="$asn.$NOW.txt"
  networkgroup_script_filename="networkgroup-$asn.$NOW.sh"

  echo "*** Writing new $asn output"
  whois -h whois.radb.net -- "-i origin $asn" | grep -Eo "([0-9.]+){4}/[0-9]+" | uniq -s 0 > "$temp_filename"

  echo "*** Getting owner of $asn"
  local owner
  owner=$(whois -h whois.radb.net -- "-i origin $asn" | grep "^descr:" | awk '{print $2}' | sort | uniq -c | sort -nr | head -1 | awk '{ print $NF }')
  echo "--- Owner of $asn: $owner"

  echo "*** Checking for changes in $asn"
  if [[ -f "$output_filename" && $(diff "$output_filename" "$temp_filename") == "" ]]; then
    echo "--- No Changes in $asn"
    
    echo "*** Cleaning temporary output"
    rm "$temp_filename"
    
  else
    echo "*** Writing networkgroup script for $asn"
    cat <<EOF >"$networkgroup_script_filename"
delete firewall group network-group $asn
set firewall group network-group $asn description "All networks $asn by $owner on $NOW"
$(sed -e "s/^/set firewall group network-group $asn network /" "$temp_filename")
EOF

    cp "$networkgroup_script_filename" nwgs.sh

    echo "*** Archiving $asn output"
    cp "$temp_filename" "$archive_filename"
    mv "$temp_filename" "$output_filename"

    echo 
    echo "Now execute the following commands on the prompt of your Edgerouter"
    echo 
    echo "configure"
    echo ". ./nwgs.sh"
    echo "commit"
    echo "save"
    echo "exit"    
  fi
}

main() {
  if [[ $# -eq 0 ]]; then
    print_usage
  else
    
    NOW=$(date +"%Y%m%d")
    ASN="$1"
    
    readonly NOW
    readonly ASN
    
    create_networkgroup_script "$ASN"
  fi
}

main "$@"

What will this script do?

  1. It will check if you give it a parameter with the name your ASN. For example, AS1136.
  2. Write a textfile with all the networks in the AS
  3. Try to get the owner of an AS
  4. Then it will try to write a script for you which creates a network group in the Edgerouter. The file will be called “networkgroup-AS1136.<date>.sh (if you give it ASN AS1136).
  5. The script which is generated in step 4 will be copying to a shorter name “nwgs.sh” for your convenience. You can archive the longer one in step 4 and use the shorter one in this step.
  6. Finally, you get further instructions to use the script and create the net-workgroup.

Running the script

  1. Find the ASN you like to use for your network group. This can be done, for example, with the following site to find your ASN: https://networksdb.io/

    Another way to get and ASN for your desired provider is to look up their IPblocks. I do this with a site from Nirsoft, https://www.nirsoft.net/countryip/nl.html. Here with the IPblocks for The Netherlands. If you want to have the ASN for a provider called “Alma International B.V.” for example, you just take the first available IP-address in their block “2.16.0.1”.

  2. Get the above script on your Edgerouter (ssh, scp, sftp) and place it in a directory of your likings. I place it in my $HOME on the router.

  3. Name the script “create_networkgroup_asn.sh”

  4. Make sure the script is executable: chmod +x ./create_networkgroup_asn.sh

  5. Run the script (in this example for Alma International B.V., i.e., AS20940):
    ./create_networkgroup_asn.sh AS20940

  6. Execute the following commands after the script has run.

    configure . ./nwgs.sh commit save exit

A note

These network-groups are considerably smaller, I don’t really notice any extra boottime of the router.

What is next?

Now you have your network-group called “AS20940” (for this example) in the Edgerouter. You can use like it like any other resource in a firewall rule. You can now allow this network-group through your firewall and block all others that are not in this group (so allow only this provider to your webserver or whatever). Or you can block this network-group from your webserver and allow all other providers. It’s up to you.