Geoip-shell: flexible geoip blocker for Linux

Hi folks,

Here is a project I've been developing for the past few months.

The idea is making geoip blocking easy on (almost) any Linux system (including OpenWrt), no matter which hardware, while also being reliable and providing flexible configuration options for the advanced users.

OpenWrt packages are available from my Github repo.

[ update April 22nd 2024 ] geoip-shell has been merged into OpenWrt packages repo. I'm currently still providing the .ipk packages from my Github repo since they include important changes which the downstream version still has not incorporated, and because the packages are currently only unavailable from the development OpenWrt branch, and because the ipk's intended for iptables-based systems are unlikely to get backported to earlier OpenWrt releases which support iptables and firewall3.

The project currently doesn't have a Luci interface. It does have a good and easy to use command-line interface. If there will be significant interest, I'll consider making a Luci interface for it.

Installation and uninstallation is either via an -install and an -uninstall scripts, or install via the ipk package and uninstall via opkg.

Actual blocking is done by the netfilter kernel component. geoip-shell creates a convenient interface with it, plus support for persistence and ip lists updates.

The ip lists can be fetched either from ipdeny (default for OpenWrt) or from RIPE (default for all other systems).

I regularly test on a VM with OpenWrt 23.05.2 and on my WNDR3700 v2 router with OpenWrt from around 2021 (with SFE patches), as well as on my Debian and Linux Mint machines.

Please let me know if you find any bugs or have a feature request, or if you have any questions, or simply if you find this project useful.

image

Here is the link:

https://github.com/friendly-bits/geoip-shell

OpenWrt-specific documentation for geoip-shell:

https://github.com/friendly-bits/geoip-shell/blob/main/OpenWrt/README.md

P.s. yes, there are some other projects capable of doing geoip blocking. I don't want to go into comparison here, I'll just say - this is a very different approach.

P.p.s. Post updated on April 22, 2024.

7 Likes

very good jobs bro, thanks for all

1 Like

I really like the concept of your project. From looking at your screenshot, it appears that you are taking a whitelist approach of approved GEOs to allow rather than the user having to specify all the countries to block.
Much quicker and easier to configure that way.

Kudos! :+1:

1 Like

Off topic: what countries do you allow or block and why? External links to read about this are welcome as well.

1 Like
install: Error: cron is not running.
install: Enable the cron service before using this script.
install: Or install geoip-shell with options '-n' '-s disable' which will disable persistence and autoupdates.


my first error but don't worry

1 Like

The project does rely on cron for autoupdates. Please make sure that the cron service is enabled. If you need more help, let me know.

/etc/init.d/cron enable
/etc/init.d/cron start

Also I'll fix the error message as on OpenWrt you don't need cron for persistence. So if you don't need autoupdates, you can install with the option '-s disable' and still have persistence. Technically you can also manually initiate updates if you really want to by issuing this command:
geoip-shell-run.sh update

Edit: there is a bug which is preventing installation with '-s disable' on OpenWrt. Working on a fix right now.

Edit2: all fixed in v0.2.4.1 release.

1 Like

Both approaches are possible with geoip-shell. You can install in either the whitelist or the blacklist mode. People who need more control can also specify which ports geoip blocking applies (or doesn't apply) to.

1 Like

Personally, I'm running a web-based application for my business which I only need available for myself and only in my country. So for me, the choice is easy - I'm using geoip-shell in whitelist mode, and the only country in the whitelist is my country.

1 Like

seems works

IPv4/IPv6 traffic table "geoip-shell"
Traffic filter chain "GEOIP-BASE"
Hook: prerouting (Capture incoming packets before any routing decision), Priority: -150
Policy: accept (Continue processing unmatched packets)
Rule matches	Rule actions
#Rule comment: geoip-shell_enableAny packet	Continue in GEOIP-SHELL
Rule container chain "GEOIP-SHELL"
Rule matches	Rule actions
#Rule comment: geoip-shell_aux_est-relIngress device name is eth1Conntrack state is one of established, relatedestablished
related	Accept packet
1 Like

I wonder where you got this report from?

Generally if you want to view the rules in the GEOIP-SHELL chain in a convenient way, you can use the command
geoip-shell status -v

This also shows statistics for packets/bytes matched and the detailed count of ip ranges for each country in the whitelist/blacklist.

in firewall

Geoip blocking status report:

Geoip blocking mode: whitelist
Ip lists source: ipdeny
Country codes in the whitelist: DE ✔
IP families in firewall rules: ipv4 ipv6 ✔
Geoip rules applied to network interfaces: eth1

Protocols:
tcp: Geoip is applied to all ports
udp: Geoip is applied to all ports

Geoip firewall chain enabled: ✔
Whitelist blocking rule: ✔

Firewall rules in the GEOIP-SHELL chain:
------------------------------------------------------------------------------------------------------------------------------                                                                       --------------------------------
packets  bytes      ipv  verdict prot dports                  interfaces                       extra
------------------------------------------------------------------------------------------------------------------------------                                                                       --------------------------------
---      ---        both ACCEPT  all  all                     eth1                             ct state established,related co                                                                       mment geoip-shell_aux_est-rel
0        0B         ipv4 ACCEPT  all  all                     eth1                             saddr @DE_ipv4_2024-02-28_geoip                                                                       -shell
0        0B         ipv6 ACCEPT  all  all                     eth1                             saddr @DE_ipv6_2024-02-28_geoip                                                                       -shell
146      11.1KiB    both DROP    all  all                     eth1                             comment geoip-shell_whitelist_b                                                                       lock

Ip ranges count in active geoip sets:
DE: ipv4 - 7147, ipv6 - 2942

Total number of ip ranges: 10089

1 Like

This looks correct, provided that eth1 is your WAN interface.
The geoip-shell status command also checks things essential for geoip blocking (including comparing the firewall rules and sets with the config, checking for existence of important rules in the firewall, checking the init script etc). If it says "No problems detected" then you should be fine.

1 Like

Just released an update, v0.2.5, with following changes:

  • The install script now supports fully interactive mode where no command line arguments need to be passed
  • The install script now also supports fully non-interactive mode where no questions are asked (but it fails if required args are not passed)
  • LAN subnets can now be specified regardless of whether geoip rules are applied to specific interfaces or not
  • Independently of LAN subnets, implemented support for specifying trusted subnets to exclude from geoip blocking
  • Some backend functions have been made more robust

(the documentation is not yet up-to-date but you can run the -install script with the -h option to see the updated usage options)

1 Like

Can you tell me the command to get this? Or if you saw this in the Luci interface then exactly where (I can't find this in Luci)? This looks kinda garbled and I'd like to see if I can fix that (and also just for general information).

hi antho I saw this in status firewall, I created a script months ago which blocks all game servers and only allows those I want to play I will share it later if necessary and if any users are interested

1 Like

Aha, now I found it. I was worried that it looks garbled in the LuCi interface but it actually looks fine.

2 Likes

In the meanwhile, I added OpenWrt-specific documentation for geoip-shell:

https://github.com/friendly-bits/geoip-shell/blob/main/OpenWrt/README.md

(while also slowly catching up with the general documentation)

1 Like

I'm kinda in the process of preparing the app for more general use now, so in the future it will support fetching from multiple sources at once. Gonna take some time to implement this but eventually it should be able to do more stuff besides geoblocking.

2 Likes

Update: still working on the new features. In the meantime, there have been a couple of releases, mainly focusing on reliability and bug fixes. Current version (v0.2.7) should be pretty stable and reliable. There is an open issue which I'm waiting for the reporter to confirm is fixed, but from my testing it is.

2 Likes

So the reporter confirmed the issue as resolved. Also the documentation is now up-to-date, and I added some more useful info to it, including a section in NOTES.md which describes the firewall rules structure created by geoip-shell.