rpthms / nft-geo-filter Goto Github PK
View Code? Open in Web Editor NEWAllow/deny traffic in nftables using country specific IP blocks
License: MIT License
Allow/deny traffic in nftables using country specific IP blocks
License: MIT License
Hi
I only want to put a simple filter, but I get nft error.
Command:
root@xxx:/home/xxx/nft-geo-filter# ./nft-geo-filter --allow HU
Response:
ERROR - show_subprocess_run_error - Failed to run: (1, ['/usr/sbin/nft', 'add', 'chain', 'inet', 'geo-filter', 'filter-chain', '{', 'type', 'filter', 'hook', 'prerouting', 'priority', 'filter', '-', '200;', 'policy', 'drop;', '}'])
ERROR - show_subprocess_run_error - Command exit status: 1
ERROR - show_subprocess_run_error - Command stdout: b''
ERROR - show_subprocess_run_error - Command stderr: b'Error: syntax error, unexpected string, expecting - or number\nadd chain inet geo-filter filter-chain { type filter hook prerouting priority filter - 200; policy drop; }\n ^^^^^^\n'
Failed to add the target nftables chain
I get only en empty geo-filter table:
table inet geo-filter {
}
Hi,
this is a request for an enhancement. The idea is to add a --dry-run
option that outputs the new rules to stdout without actually changing anything, that would be useful to check the output of the command before actually running it.
When blocking the following countries:
/usr/local/bin/nft-geo-filter --table-family netdev --table-name SOMETHING --interface xxxxx --no-ipv6 --provider ipverse.net CN RU RO TR IR ID MY VN TH SG IN UA
As soon as I add RO or TR to the list, I get
ERROR - update_filter_set - Could not add the "tr" IPv4 blocks to the filter-v4 set in SPAMMERS
WARNING - restore_old_sets - No old sets detected. Setting the SPAMMERS table as dormant!
ERROR - show_subprocess_run_error - Failed to run: (1, ['/usr/sbin/nft', '-f', '/tmp/tmpegg9lql6/tmp08la9pc5'])
ERROR - show_subprocess_run_error - Command exit status: 1
ERROR - show_subprocess_run_error - Command stdout:
ERROR - show_subprocess_run_error - Command stderr:
/tmp/tmpegg9lql6/tmp08la9pc5:2:5-13: Error: Could not process rule: Directory not empty
set filter-v4 {
^^^^^^^^^
Using only RO or TR works fine.
Using CN RU TH MY SG works fine.
But not CN RU RO TR IR ID MY VN TH SG IN UA
Any hint what could be the problem?
If you're applying firewall rules when the machine comes up (as I imagine most people are) the machine's internet access may not be available. It would make sense to store the raw JSON files from the IP sources in /var
so firewall rules can be applied even when the network is down. nft-geo-filter will have to gain the ability to potentially refresh those files as well.
Hi!
Could it be useful to have a fallback provider in case ipdeny.com is not reachable (for whatever reason -I saw the "dormant" when downloading- )?
In a script I started to write (not finished, I found this! ) I had used:
which I used exclusively in case the first one was not available.
(often there are discrepancies between the IPs of the two services)
Thank you,
Riccardo
line 428-430 must be updated from
OLD
provider_url = 'http://ipverse.net/ipblocks/data/countries/{}.zone'
else:
provider_url = 'http://ipverse.net/ipblocks/data/countries/{}-ipv6.zone'`
NEW
provider_url = 'https://raw.githubusercontent.com/ipverse/rir-ip/master/country/{}/ipv4-aggregated.txt'
else:
provider_url = 'https://raw.githubusercontent.com/ipverse/rir-ip/master/country/{}/ipv6-aggregated.txt'
Hello, I installed the latest script today on a Debian 10.5. My aim was to allow incoming traffic to local webserver only from Austria.
/usr/local/bin/nft-geo-filter/nft-geo-filter --table-family netdev --table-name AT-filter --interface enp1s0 --allow AT
Then I listed the nft tables and the newly added AT-filter table.
root@apu:/usr/local/bin/nft-geo-filter# nft list tables
table ip filter
table ip6 filter
table ip nat
table netdev AT-filter
root@apu:/usr/local/bin/nft-geo-filter# nft list table netdev AT-filter
table netdev AT-filter {
set filter-v4 {
type ipv4_addr
flags interval
auto-merge
elements = { 2.56.160.0/22, 2.56.208.0/22,
... all the other ipv4 subnets....
217.196.144.0/20, 217.199.80.0/20 }
}
set filter-v6 {
type ipv6_addr
flags interval
auto-merge
elements = { 2001:628::/29,
2001:678:d::/48,
... all the other ipv6 subnets....
2a0f:f080::/29 }
}
chain filter-chain {
type filter hook ingress device enp1s0 priority -200; policy drop;
ip6 saddr fe80::/10 accept
ip saddr { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 } accept
meta protocol != { ip, ip6 } accept
ip saddr @filter-v4 accept
ip6 saddr @filter-v6 accept
}
}
Afterwards I wanted to allow another country: /usr/local/bin/nft-geo-filter/nft-geo-filter --table-family netdev --table-name SK-filter --interface enp1s0 --allow SK
and then I was cut out of the server and can't connect via ssh from private IP subnet from range 192.168.0.0/16.
Any idea what could go wrong here? I'm also using docker on this server.
Hi,
SSL Cert of ipdeny.com has just expired yesterday. Since then the script does not work.
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1056)>
Can you please suggest a workaround until they renew their cert?
Regards,
Zsolt
I am really appreciating your work for nft-geo-filter. good job.
Can you please help me out?
When we are trying to add new nft rule then all previous added rules are flushed automatically. So I want to know how can we stop it.
Can we manage it with Database or with text file? like if we can store data somewhere.
Since my BAD-GUYS list is getting longer and longer, I was wandering if there is a way to get an individual IP list into that script too?
Let's say I block Monaco and I want to block some IPs / IP ranges from US but I don't want to block the whole US. At the moment I edit another simple script to add those lines
so my idea was to have a file/list with just bad IPs / ranges that are blocked with the countries.
1.2.3.4/25
10.20.30.40/24
probably there is already a much smarter way to do it.
all the best
Am I wrong or the provided systemd timer script should also include the Unit?
i.e.
[Timer]
OnBootSec=1min
OnUnitActiveSec=12h
Unit=nft-geo-filter.service
nice tool BTW, thanks!
Hi. I'm faced an issue when nft-geo-filter configured as asystemd timer and started at the moment, when connection to internet was lost. Table with IPs to block was cleared, but not restored so I became unprotected. Could the table be cleared after the new list downloaded or at least to check network connection before cleaning?
Is it possible to allow multiple countries in same time?
Is allow to HU DE and MC and deny any others?
nft-geo-filter --allow --allow-established MC HU DE
Thanx!
Hello , firstly I really appreciated by your work on GEO filter . but at a time it's only taking one rule, also if I want to allow two countries IPs suppose US, CN and only My public ip (IN) Then how it will work ?
I just updated to the latest version of your script and started using ipverse.net since ipdeny is having issues with the ssl. So I ran the script with the following options:
/usr/local/bin/nft-geo-filter --table-family netdev --table-name SPAMMERS --interface eth0 --no-ipv6 --provider ipverse.net CN RU RO UA TR IR ID MY VN TH SG IN
I get that error message showing up:
ERROR - update_filter_set - Could not add the "ua" IPv4 blocks to the filter-v4 set in SPAMMERS
WARNING - restore_old_sets - No old sets detected. Setting the SPAMMERS table as dormant!
ERROR - show_subprocess_run_error - Failed to run: (1, ['/usr/sbin/nft', '-f', '/tmp/tmpo797kab5/tmpetgiynsf'])
ERROR - show_subprocess_run_error - Command exit status: 1
ERROR - show_subprocess_run_error - Command stdout:
ERROR - show_subprocess_run_error - Command stderr:
netlink: Error: Could not process rule: No space left on device
Although it looks like, all IPS and country blocks where added correctly. Not sure what to do with that messages.
I can not use UA (Ukraine) in the country list. If I remove UA from the block list, everything is working fine.
Let me share one more idea*.
If you want to allow traffic from a small number of zones (using the --allow parameter) you are still often dependent on services that reside in other countries (even if only to update your system).
In this case you need to use --allow-established: that means you can't use the netdev table.
It would be very efficient to be able to declare a different set of countries to block directly in the netdev table (the ones where you are sure there are no useful services, the ones where most attacks come from...).
At the end you would have a set of countries that are definitely blocked in an efficient way by netdev and a set of allowed ones.
All countries excluded from these sets would be blocked but reachable.
I imagine such a setup would be more complex and alter the simplicity of this script, but... here it is.
Thanks you,
Riccardo
Hi alls,
Thanks for your script.
By running these options #./nft-geo-filter --log-drop --allow --allow-established FR i have the following errors. And of course like it can't add private network exception I loose my connection.
#./nft-geo-filter --log-drop --allow --allow-established FR
ERROR - add_allow_rules - Failed to add the rule to allow private IPv4 address ranges in geo-filter's filter-chain
ERROR - show_subprocess_run_error - Failed to run: (-6, ['/usr/sbin/nft', 'insert', 'rule', 'inet', 'geo-filter', 'filter-chain', 'ip', 'saddr', '{', '10.0.0.0/8,', '127.0.0.0/8,', '172.16.0.0/12,', '192.168.0.0/16', '}', 'accept'])
ERROR - show_subprocess_run_error - Command exit status: -6
ERROR - show_subprocess_run_error - Command stdout:
ERROR - show_subprocess_run_error - Command stderr:
BUG: unhandled op 4
nft: evaluate.c:1502: interval_set_eval: Assertion `0' failed.
I added RO for Romania and not all ip block listed on the denyip site are included in the script.
For example: 89.33.192.205 the blocks are included on their site, but it's not in the elements
RO blocks:
https://www.ipdeny.com/ipblocks/data/aggregated/ro-aggregated.zone
CentOS 8 distro:
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="8"
[root@mail bin]# python3 --version
Python 3.6.8
Do I have to open some ports first, so the script is working? port 80/443 are restricted to only a range of IPs at the moment.
[root@mail bin]# nft-geo-filter --table-family netdev --interface eth0 MC Traceback (most recent call last): File "/usr/local/bin/nft-geo-filter", line 406, in if gFilter.add_table() == -1: File "/usr/local/bin/nft-geo-filter", line 81, in add_table subprocess.run(nft_command.split(), capture_output=True, check=True) File "/usr/lib64/python3.6/subprocess.py", line 423, in run with Popen(*popenargs, **kwargs) as process: TypeError: init() got an unexpected keyword argument 'capture_output'
Hello
Thank you for your work on this application. I have a question concerning allowing outgoing traffic. Taking MC as an example, suppose I allow incoming traffic only from within MC
nft-geo-filter --allow MC
this entails that no incoming or outgoing traffic is allowed to non-MC addresses. But suppose I would still like to allow outgoing traffic to the rest of the world (ie packets originating from my machine). How can I achieve this? I tried adding
ct state established,related accept
to the chain 'filter-chain' (assuming default names in this example), but it did not make a difference.
Is there a way to make this work? It would be great to have an option for this in the program.
Thank you
This is a feature request, to block all IP's of a provider (ISP). Sometimes bad requests are coming from a specific provider, so it would be great to block all their IP's based on their ASN name or number. Is there any chance to do that?
all the best
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.