Skip to content

Instantly share code, notes, and snippets.

@mkorthof
Last active May 5, 2023 00:28
Show Gist options
  • Save mkorthof/3033ff64c4a5b4bd31336d422104d543 to your computer and use it in GitHub Desktop.
Save mkorthof/3033ff64c4a5b4bd31336d422104d543 to your computer and use it in GitHub Desktop.
Block countries using iptables + ipset + ipdeny.com -> moved to https://github.com/mkorthof/ipset-country
@HHawk
Copy link

HHawk commented Aug 5, 2019

Hi Marius,

Thank you for response. :-)

I tried the new version, but I am still getting errors, however I think it's a typo:

./ipset-country
./ipset-country: line 149: /sbin/ip}tables-restore: No such file or directory
./ipset-country: line 149: /sbin/ip6}tables-restore: No such file or directory
ip6tables v1.4.21: unknown reject type "icmp-port-unreachable"
Try `ip6tables -h' or 'ip6tables --help' for more information.

It's missing a "{" in there right? I changed it to have a { on those two locatations and re-run the script.
So I changed:
iptres="/sbin/$ipt}tables-restore"
to:
iptres="/sbin/${ipt}tables-restore"

And this is the result:

./ipset-country
ip6tables v1.4.21: unknown reject type "icmp-port-unreachable"
Try `ip6tables -h' or 'ip6tables --help' for more information.
ip6tables v1.4.21: unknown reject type "icmp-port-unreachable"
Try `ip6tables -h' or 'ip6tables --help' for more information.

No clue why I am getting "ip6tables v1.4.21: unknown reject type "icmp-port-unreachable"", but probably that's my own conifguration error. I will look this up myself. :-)

Output: /var/log/ipset-country.log

2019-08-05 09:57:00 ipset: create set "ipv4-china" - OK
2019-08-05 09:57:01 zonefile: get "ipv4-cn-aggregated.zone" - OK
2019-08-05 09:57:10 ipset: add "ipv4-cn-aggregated.zone" to "ip-china" - OK - 5180 entries
2019-08-05 09:57:10 iptables: found - OK
2019-08-05 09:57:10 iptables: restore - OK
2019-08-05 09:57:10 iptables: create log chain - OK
2019-08-05 09:57:10 iptables: append log rule - OK, append reject rule - OK
2019-08-05 09:57:10 iptables: insert ipset rule - OK
2019-08-05 09:57:10 ipset: create set "ipv6-china" - OK
2019-08-05 09:57:10 zonefile: get "ipv6-cn.zone" - OK
2019-08-05 09:57:13 ipset: add "ipv6-cn.zone" to "ip6-china" - OK - 1750 entries
2019-08-05 09:57:13 ip6tables: found - OK
2019-08-05 09:57:13 ip6tables: restore - OK
2019-08-05 09:57:13 ip6tables: create log chain - OK
2019-08-05 09:57:13 ip6tables: append log rule - OK, append reject rule - NOK
2019-08-05 09:57:13 ip6tables: insert ipset rule - OK
2019-08-05 09:57:13 ipset: create set "ipv4-russia" - OK
2019-08-05 09:57:14 zonefile: get "ipv4-ru-aggregated.zone" - OK
2019-08-05 09:57:28 ipset: add "ipv4-ru-aggregated.zone" to "ip-russia" - OK - 8032 entries
2019-08-05 09:57:28 iptables: found - OK
2019-08-05 09:57:28 iptables: restore - OK
2019-08-05 09:57:28 iptables: create log chain - OK
2019-08-05 09:57:28 iptables: append log rule - OK, append reject rule - OK
2019-08-05 09:57:28 iptables: insert ipset rule - OK
2019-08-05 09:57:28 ipset: create set "ipv6-russia" - OK
2019-08-05 09:57:29 zonefile: get "ipv6-ru.zone" - OK
2019-08-05 09:57:33 ipset: add "ipv6-ru.zone" to "ip6-russia" - OK - 2284 entries
2019-08-05 09:57:33 ip6tables: found - OK
2019-08-05 09:57:33 ip6tables: restore - OK
2019-08-05 09:57:33 ip6tables: create log chain - OK
2019-08-05 09:57:33 ip6tables: append log rule - OK, append reject rule - NOK
2019-08-05 09:57:33 ip6tables: insert ipset rule - OK

Sidenote; I just come to understand now that "NOK" means "Not OK", right? Don't know why I didn't understand that before. Guess I am an idiot sometimes. :S
Anyways, that error is probably related to the unknown reject rule. As mentioned I will look that up, to see why it's in there or what added it.

Output of the command "ipset -t list" is:

Name: ipv4-china
Type: hash:net
Revision: 6
Header: family inet hashsize 2048 maxelem 65536
Size in memory: 11000
References: 0
Number of entries: 5180

Name: ipv6-china
Type: hash:net
Revision: 6
Header: family inet6 hashsize 1024 maxelem 65536
Size in memory: 98264
References: 0
Number of entries: 1750

Name: ipv4-russia
Type: hash:net
Revision: 6
Header: family inet hashsize 4096 maxelem 65536
Size in memory: 2744
References: 1
Number of entries: 8032

Name: ipv6-russia
Type: hash:net
Revision: 6
Header: family inet6 hashsize 1024 maxelem 65536
Size in memory: 111480
References: 1
Number of entries: 2284

I also ran the command "ip6tables -L" and this is the output:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all      anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     ipv6-icmp    anywhere             anywhere
ACCEPT     all      anywhere             anywhere
ACCEPT     tcp      anywhere             anywhere             state NEW tcp dpt:ssh
ACCEPT     udp      anywhere             fe80::/64            udp dpt:dhcpv6-client state NEW
LOGIPS     tcp      anywhere             anywhere             match-set ipv6-russia src
REJECT     all      anywhere             anywhere             reject-with icmp6-adm-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all      anywhere             anywhere             reject-with icmp6-adm-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain LOGIPS (1 references)
target     prot opt source               destination
LOG        all      anywhere             anywhere             limit: avg 10/min burst 5 LOG level info prefix "IPS REJECT: "

While typing the above, I did a search on "icmp-port-unreachable", apparently there was a (another) small typo with your script.
Line 163 has the following:
elif [ "$proto" = "ipv4" ]; then rj="icmp6-port-unreachable"; fi
I changed that to:
elif [ "$proto" = "ipv6" ]; then rj="icmp6-port-unreachable"; fi
and re-ran the script again.

This time were no errors!

Also /var/log/ipset-country.log showed no errors anymore:

2019-08-05 10:08:04 ipset: create set "ipv4-china" - OK
2019-08-05 10:08:05 zonefile: get "ipv4-cn-aggregated.zone" - OK
2019-08-05 10:08:14 ipset: add "ipv4-cn-aggregated.zone" to "ip-china" - OK - 5180 entries
2019-08-05 10:08:14 iptables: found - OK
2019-08-05 10:08:14 iptables: restore - OK
2019-08-05 10:08:14 iptables: create log chain - OK
2019-08-05 10:08:14 iptables: append log rule - OK, append reject rule - OK
2019-08-05 10:08:14 iptables: insert ipset rule - OK
2019-08-05 10:08:14 ipset: create set "ipv6-china" - OK
2019-08-05 10:08:15 zonefile: get "ipv6-cn.zone" - OK
2019-08-05 10:08:18 ipset: add "ipv6-cn.zone" to "ip6-china" - OK - 1750 entries
2019-08-05 10:08:18 ip6tables: found - OK
2019-08-05 10:08:18 ip6tables: restore - OK
2019-08-05 10:08:18 ip6tables: create log chain - OK
2019-08-05 10:08:18 ip6tables: append log rule - OK, append reject rule - OK
2019-08-05 10:08:18 ip6tables: insert ipset rule - OK
2019-08-05 10:08:18 ipset: create set "ipv4-russia" - OK
2019-08-05 10:08:19 zonefile: get "ipv4-ru-aggregated.zone" - OK
2019-08-05 10:08:33 ipset: add "ipv4-ru-aggregated.zone" to "ip-russia" - OK - 8032 entries
2019-08-05 10:08:33 iptables: found - OK
2019-08-05 10:08:33 iptables: restore - OK
2019-08-05 10:08:33 iptables: create log chain - OK
2019-08-05 10:08:33 iptables: append log rule - OK, append reject rule - OK
2019-08-05 10:08:33 iptables: insert ipset rule - OK
2019-08-05 10:08:33 ipset: create set "ipv6-russia" - OK
2019-08-05 10:08:33 zonefile: get "ipv6-ru.zone" - OK
2019-08-05 10:08:38 ipset: add "ipv6-ru.zone" to "ip6-russia" - OK - 2284 entries
2019-08-05 10:08:38 ip6tables: found - OK
2019-08-05 10:08:38 ip6tables: restore - OK
2019-08-05 10:08:38 ip6tables: create log chain - OK
2019-08-05 10:08:38 ip6tables: append log rule - OK, append reject rule - OK
2019-08-05 10:08:38 ip6tables: insert ipset rule - OK

ip6tables -L shows the following:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all      anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     ipv6-icmp    anywhere             anywhere
ACCEPT     all      anywhere             anywhere
ACCEPT     tcp      anywhere             anywhere             state NEW tcp dpt:ssh
ACCEPT     udp      anywhere             fe80::/64            udp dpt:dhcpv6-client state NEW
LOGIPS     tcp      anywhere             anywhere             match-set ipv6-russia src
REJECT     all      anywhere             anywhere             reject-with icmp6-adm-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all      anywhere             anywhere             reject-with icmp6-adm-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain LOGIPS (1 references)
target     prot opt source               destination
LOG        all      anywhere             anywhere             limit: avg 10/min burst 5 LOG level info prefix "IPS REJECT: "
REJECT     all      anywhere             anywhere             reject-with icmp6-port-unreachable

So everything seems in order now, right?
Though I think one thing is strange. In "ip6tables -L" I only see the following:
LOGIPS tcp anywhere anywhere match-set ipv6-russia src
but I don't see a china reference in there. Or is this normal behaviour?

Sorry for the very long reply/post, but I am trying to be as helpful as I can.

Regards

@mkorthof
Copy link
Author

Hi @HHawk

Thanks again for testing and showing the output.

You are correct about that var. I found another issue: the script does a iptables-restore between countries. So only last ipv4/6 is added.

Ive fixed that now so it restores once and rewrote the thing a bit; and tested on centos7/rhel8. It also supports firewalld now.

I’ll try pushing the new fixed ver later this week.

@HHawk
Copy link

HHawk commented Aug 15, 2019

Hi @mkorthof (Marius),

Sidenote; seems you're Dutch, right? Based on your name. Only noticed it now. ;-)

You're most welcome. I am trying to give as much details as possible, as this is a great script! And it's getting better every time!
You don't want to know how many "attacks" are being made on my servers. Mostly China and Russia (frequently). Also a few US IP's, but I don't want to block the US completely though.

It's getting more and more important to block certain countries to relieve server load.

Looking forward to the fixes / adjustments. Will try again afterwards. I will be going on vacation for ~2.5 weeks, so I might be a bit slow in replying.

Regards

@vk3heg
Copy link

vk3heg commented Aug 18, 2019

HI Guys.

I have just tried this on my Debian9 system and get the following errors:

./ipset-country.sh: line 148: /etc/iptables/rules.v4: No such file or directory
./ipset-country.sh: line 148: /etc/iptables/rules.v6: No such file or directory
ip6tables v1.6.0: unknown reject type "icmp-port-unreachable"
Try ip6tables -h' or 'ip6tables --help' for more information. ip6tables v1.6.0: Invalid rule number 0'
Try `ip6tables -h' or 'ip6tables --help' for more information.

A section of the logfile has:
2019-08-18 21:44:14 zonefile: get "ipv4-vn-aggregated.zone" - OK
2019-08-18 21:44:15 ipset: add "ipv4-vn-aggregated.zone" to "ip-vietname" - OK - 553 entries
2019-08-18 21:44:15 iptables: found - OK
2019-08-18 21:44:15 iptables: restore - NOK
2019-08-18 21:44:15 iptables: create log chain - already exists
2019-08-18 21:44:15 iptables: append log rule - already exists, append reject rule - already exists
2019-08-18 21:44:15 iptables: insert ipset rule - already exists
2019-08-18 21:44:15 ipset: create set "ipv6-vietname" - OK
2019-08-18 21:44:16 zonefile: get "ipv6-vn.zone" - OK
2019-08-18 21:44:16 ipset: add "ipv6-vn.zone" to "ip6-vietname" - OK - 176 entries
2019-08-18 21:44:16 ip6tables: found - OK
2019-08-18 21:44:16 ip6tables: restore - NOK
2019-08-18 21:44:16 ip6tables: create log chain - already exists
2019-08-18 21:44:16 ip6tables: append log rule - already exists, append reject rule - NOK
2019-08-18 21:44:16 ip6tables: insert ipset rule - NOK
2019-08-18 21:44:16 ipset: create set "ipv4-south_africa" - OK
2019-08-18 21:44:17 zonefile: get "ipv4-za-aggregated.zone" - OK
2019-08-18 21:44:19 ipset: add "ipv4-za-aggregated.zone" to "ip-south_africa" - OK - 1134 entries
2019-08-18 21:44:19 iptables: found - OK
2019-08-18 21:44:19 iptables: restore - NOK
2019-08-18 21:44:19 iptables: create log chain - already exists
2019-08-18 21:44:19 iptables: append log rule - already exists, append reject rule - already exists
2019-08-18 21:44:19 iptables: insert ipset rule - already exists
2019-08-18 21:44:19 ipset: create set "ipv6-south_africa" - OK
2019-08-18 21:44:20 zonefile: get "ipv6-za.zone" - OK
2019-08-18 21:44:20 ipset: add "ipv6-za.zone" to "ip6-south_africa" - OK - 284 entries
2019-08-18 21:44:20 ip6tables: found - OK
2019-08-18 21:44:20 ip6tables: restore - NOK
2019-08-18 21:44:20 ip6tables: create log chain - already exists
2019-08-18 21:44:20 ip6tables: append log rule - already exists, append reject rule - NOK
2019-08-18 21:44:20 ip6tables: insert ipset rule - NOK

Thanks,
Stephen

@mkorthof
Copy link
Author

mkorthof commented Sep 5, 2019

@HHawk @vk3heg fixed version is available now.

  • tested on debian 10 and centos 7
  • blocking multiple countries should work
  • it will check if INPUT chain exists in iptables
  • cleaned it up a bit
  • using firewalld is also supported now

@HHawk
Copy link

HHawk commented Nov 8, 2019

Hi mkorthof!

Sorry for the late response and feedback.

I had finally some time to test your excellent script again. So far it's working GREAT!
I cannot see any errors. Great work! Two thumbs up!

Regards,
HHawk

@Sevyron
Copy link

Sevyron commented Nov 12, 2019

Hey kor, iv been using your work for some time on, but recently the main web were we get all the zones ipv4s it's down for some reason idk why, but i tried to add a different source url-get but im facing the md5sum verification, would you add an option on the script to either check or not the md5sum?

i'm trying to add zones from ipverse dut net and yea, other than that, you did it just fine men! n.n

@mkorthof
Copy link
Author

Hey kor, iv been using your work for some time on, but recently the main web were we get all the zones ipv4s it's down for some reason idk why, but i tried to add a different source url-get but im facing the md5sum verification, would you add an option on the script to either check or not the md5sum?

i'm trying to add zones from ipverse dut net and yea, other than that, you did it just fine men! n.n

I noticed this also and switched to ipverse.net too and had to comment md5 checks in func_zf() function because ipverse does not supply md5 checksums. Looks like ipdeny is back now, but I'll add an option to disable md5 checks anyways.

If you have further issues feel free to create an issue at the repo (https://github.com/mkorthof/ipset-country/issues)

@rshackleford2020
Copy link

This is a great little script, very easy to set up and use. It only took a few minutes to get it up and running on Debian 10. Wouldn't DROP be preferable to REJECT though in the iptables rules? (Maybe make it a config choice?)

@mkorthof
Copy link
Author

Wouldn't DROP be preferable to REJECT though in the iptables rules? (Maybe make it a config choice?)

Added as issue #1

@SushantRathore-Admin
Copy link

Hi everyone,

I am using ipset on Amazon Linux 2, its working well. i have created SETNAME( web-access-block) and also added one ip (192.168.0.10) in web-access-block ipset file.

My questions are :-

  1. How i will know that, When had i add any ip in SETNAME( web-access-block) ?
  2. Can i release ip from SETNAME( web-access-block). which i was added 30 days ago, using script or any others way ?

Please help me.
Thanks
Sushant Kr Kunwar

@mkorthof
Copy link
Author

Hi @SushantRathore-Admin,
I don't think your questions are in any way related to the script that used to be posted in this gist.
If you have any issues specifically related to ipset-country feel free to create an issue for the repo linked on top.

@Horsyy
Copy link

Horsyy commented Apr 15, 2021

So recently i tried to setup the ipset-country, all works fine but.. i am running a FiveM server so when the server tries to send a heartbeat, it fails with the error:

Failed to connect to api.steampowered.com port 443
Failed to connect to keymaster.fivem.net port 443

What can i do to fix this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment