GeoIP
OpenWRT doesn’t ship with GeoIP capabilities, but you can add it with the IP set extras script. This is a somewhat legacy approach, but the GUI requires it, and OpenWRT translates it modern nft named sets under the hood.
# At the command line
opkg update
opkg install ipset resolveip
# Install ipset-extras via their install script
wget -U "" -O ipset-extras.sh "https://openwrt.org/_export/code/docs/guide-user/advanced/ipset_extras?codeblock=0"
chmod +x ipset-extras.sh
./ipset-extras.sh
# Logout and back in to enable the extension from the /etc/profile.d folder
exit
# Configure an IP set for the US
uci set dhcp.us="ipset"
uci add_list dhcp.us.name="US"
uci add_list dhcp.us.name="US6"
uci add_list dhcp.us.geoip="us"
uci commit dhcp
# Populate IP sets
ipset setup
# Check set creation worked
nft list sets
# Install hotplug-extras for persistence
wget -U "" -O hotplug-extras.sh "https://openwrt.org/_export/code/docs/guide-user/advanced/hotplug_extras?codeblock=0"
chmod +x ./hotplug-extras.sh
./hotplug-extras.sh
When adding a port forward, the Advanced tab will now have the “Use ipset” populated and you can select “US”
You can also invert the rule by typing in “! US” - an important feature that doesn’t jump out at you.
This inversion is best with with a list of who you don’t want. Here’s an example of a set for the worst 5 countries for probes.
# Configure an IP set for the worst countries for probes and hacks - the axis of hacks
uci set dhcp.axis="ipset"
uci add_list dhcp.axis.name="axis"
uci add_list dhcp.axis.name="axis6"
uci add_list dhcp.axis.geoip="cn"
uci add_list dhcp.axis.geoip="in"
uci add_list dhcp.axis.geoip="ne"
uci add_list dhcp.axis.geoip="ng"
uci add_list dhcp.axis.geoip="ru"
uci commit dhcp
ipset setup
Troubleshooting
No NFT Sets Generated:
The script that generates the sets is sensitive to the value you put in `dhcp.axis.name=“value”. Try avoiding spaces and numbers and that ‘6’ is at the end of the second value.
Why are we adding these to DHCP:
I don’t know. The documentation adds them there. In the code, the script loads them from there. I tried adding them to the Firewall section just for fun and it didn’t work. I suspect if I knew more it would make sense.
Notes
The installation uses <www.ipdeny.com> and adds a cronjob that updates the list daily at 3 AM.
There are other tools, such as geopip-shell or ban ip, but these are more of an all-or-nothing solution and can’t be used with individual firewall rules. There is also the python utility from the netfilter team and misc bash scripts, but these lack easy OpenWRT integration.
The authors of nftables have a page[^5] on GeoIP, but it’s about tagging packets. OpenWRT expects named sets and you can’t easily construct that from a map.
[^5] https://wiki.nftables.org/wiki-nftables/index.php/GeoIP_matching
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.