0

my goal is to drop with iptables more or less every request from non-german countries.

the best solution that is working in 2022 is this five year old script.

(Source: https://www.cyberciti.biz/faq/block-entier-country-using-iptables/)

with the help of this script-template and some iptables tutorials I'm able to allow (more or less accurate) only German IP-Ranges.

This is my modified script: (it's not optimized yet, but should block every non-german IP-Requests)

ISO="de"

IPT=/sbin/iptables WGET=/usr/bin/wget EGREP=/bin/egrep

SPAMLIST="countrydrop" ZONEROOT="/root/iptables" DLROOT="http://www.ipdeny.com/ipblocks/data/countries"

[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT

$IPT -F

$IPT -N $SPAMLIST

for c in $ISO do tDB=$ZONEROOT/$c.zone $WGET -O $tDB $DLROOT/$c.zone BADIPS=$(egrep -v "^#|^$" $tDB) for ipblock in $BADIPS do $IPT -A $SPAMLIST ! -s $ipblock -j DROP done done exit 0

but if I let the script run, it creates the rule and then I want to make the default rule "incoming traffic" to drop, he locks me instantly out.

I know, IP tables is processing the rules from top to button, but now I'm not sure how to handle it in the script.

Or do I don't need to make the default incoming chain/rule to block everything, because I already blocked everything except German IP Adresses? Or should I put the default drop on top of the script? this is how I'd edit the default incoming rule:

iptables --policy INPUT DROP

... but it feels kinda bad, if I let the default incoming rule untouched .. what do you think?

in the end I'd like to:

  • block everything by default
    • except German IP Adresses
    • and open about ~5 ports (only for German IP-Adresses)

If I could handle this in only one script, that's always running on boot, I'd be really happy! :-)

P.S: I'm sure, I'm not the only one who is looking for a up2date solution for this task, it would be awesome if some people could help to find a solution for this case :-)

Doug Smythies
  • 15,448
  • 5
  • 44
  • 61
  • You need to allow your own traffic back into your computer. You need a sudo iptables -A INPUT -i $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT rule first in your INPUT chain. where $EXTIF is your network interface card name. You also need a lo ACCEPT rule, sudo iptables -A INPUT -i lo -j ACCEPT. Myself, I would use ipset to do what you are attempting. I would also ACCEPT packets from Germany, and let the others fall to the default DROP rule, as it'll be more efficient. – Doug Smythies Jun 03 '22 at 15:48
  • I had to test it but due to recent changes for the ipdeny site I had to add stuff to my script. I wrote a country block script awhile ago. You are more than welcome to check it out. https://askubuntu.com/a/983591/231142 – Terrance Jun 03 '22 at 16:23
  • @DougSmythies thanks for your idea! maybe my script is buggy, because after adding your rules to the beginning of the script, I can still ping my VPS from different locations- if I use the script linked in the post from cyberciti and put in every country except mine, then it really works and I can not ping it- but this script works with blacklisting- so he add almost thousands of ranges except Germany and starting the script takes about an hour .. – ubuntu4life Jun 03 '22 at 17:34
  • Sorry, meant to enter this comment hours ago, but never hit "enter". This line $IPT -A $SPAMLIST ! -s $ipblock -j DROP should be this $IPT -A $SPAMLIST -s $ipblock -j ACCEPT. There are other issues, but I'll have to come back to it later. – Doug Smythies Jun 03 '22 at 20:38
  • @DougSmythies thanks for your quick response! I've just added $IPT --policy INPUT DROP $IPT -A INPUT -i $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -i lo -j ACCEPT

    ... to my script, but I can still access or ping my VPS from different locations :/ I guess this topic is kinda complicated. I found this script-template https://github.com/mkorthof/ipset-country which should be the perfect solution for everyone with this problem- but even this script doesn't work that well. If you still have an idea, how to solve this kinda shortly with my script, let me know

    – ubuntu4life Jun 03 '22 at 22:23
  • @ubuntu4life You can take a look at my script that I linked to in my comment above. It maybe takes like 5 or 10 minutes to complete during a bootup or running it manually. – Terrance Jun 04 '22 at 01:03
  • Doesn't the existence of VPN services make this "restriction" impossible? Using NordVPN for example, I, in Canada, can appear to come from Germany, with NordVPN's german IP address. You can't tell me apart from true Germans. – waltinator Jun 04 '22 at 03:45
  • @waltinator ithe reason to block countries by IP-Adresses is to block 90%+ of bots from others countries. Of corse one funny boi can use a vpn or maybe many more. but my idea is to block most of the trash crawlers out there; if you check the logs, most "attacks" come from china and russia, so the don't seem to care about faking their IP adress – ubuntu4life Jun 04 '22 at 09:05

1 Answers1

0

There are multiple issues with your script. This answer uses your basic structure, however it is recommended that you use ipset for your allow list instead (in future I might add a ipset method to this answer). Modified script:

#!/bin/bash

ISO="de"

IPT=/sbin/iptables WGET=/usr/bin/wget EGREP=/bin/egrep

ALLOWLIST="countryaccept" ZONEROOT="/home/doug/iptables/misc/ask1412134/iptables" DLROOT="http://www.ipdeny.com/ipblocks/data/countries" UNIVERSE="0.0.0.0/0"

The network interface card is set for my test computer. Change to users NIC name.

NIC=br0

echo ask1412134 begin.

[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT

set default policy to ACCEPT while we build the list

$IPT -P INPUT ACCEPT

flush all rules

$IPT -F

$IPT -N $ALLOWLIST

build the list

for c in $ISO do tDB=$ZONEROOT/$c.zone $WGET -O $tDB $DLROOT/$c.zone GOODIPS=$(egrep -v "^#|^$" $tDB) for ippermit in $GOODIPS do $IPT -A $ALLOWLIST -s $ippermit -j ACCEPT done done

add the usual INPUT ACCEPT rules

loopback interfaces are valid.

$IPT -A INPUT -i lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT

Allow any related traffic coming back to the server in.

$IPT -A INPUT -i $NIC -m state --state ESTABLISHED,RELATED -j ACCEPT

All other traffic needs to be verified as being from Germany

$IPT -A INPUT -i $NIC -j $ALLOWLIST

SPECIAL: For my test computer:

Allow new SSH connections from my desktop

The end user will remove this.

$IPT -A INPUT -i $NIC -s 192.168.111.122 -d 192.168.111.136 -p tcp --dport 22 -j ACCEPT

For unknown reasons the INPUT chain policy packet counter is not incrementing,

even though it seems to be working fine. Specifically add a log-n-drop rule pair here.

$IPT -A INPUT -j LOG --log-prefix "IBLOCK:" --log-level info $IPT -A INPUT -j DROP

Now we are ready for DROP default policy

$IPT -P INPUT DROP

echo ask1412134 done.

Example use:

doug@s19:~/iptables/misc/ask1412134$ sudo iptables -xvnL | head -20
Chain INPUT (policy DROP 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination
       2      100 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
     154     9024 ACCEPT     all  --  br0    *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
     208    42712 countryaccept  all  --  br0    *       0.0.0.0/0            0.0.0.0/0
       0        0 ACCEPT     tcp  --  br0    *       192.168.111.122      192.168.111.136      tcp dpt:22
     208    42712 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 6 prefix "IBLOCK:"
     208    42712 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination

Chain countryaccept (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * * 192.69.234.0/24 0.0.0.0/0 0 0 ACCEPT all -- * * 198.176.223.0/24 0.0.0.0/0 0 0 ACCEPT all -- * * 198.176.224.0/22 0.0.0.0/0

and, where I had a ping going from an unauthorized computer:

doug@s19:~/iptables/misc/ask1412134$ grep IBLOCK /var/log/syslog
Jun  4 08:20:11 s19 kernel: [686010.878096] IBLOCK:IN=br0 OUT= MAC=3c:7c:3f:0d:99:83:b8:27:eb:f7:ec:c9:08:00 SRC=192.168.111.133 DST=192.168.111.136 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=39198 DF PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1056
Jun  4 08:20:12 s19 kernel: [686011.918074] IBLOCK:IN=br0 OUT= MAC=3c:7c:3f:0d:99:83:b8:27:eb:f7:ec:c9:08:00 SRC=192.168.111.133 DST=192.168.111.136 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=39211 DF PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1057
Jun  4 08:20:13 s19 kernel: [686012.709961] IBLOCK:IN=br0 OUT= MAC=ff:ff:ff:ff:ff:ff:84:ea:ed:46:57:cc:08:00 SRC=0.0.0.0 DST=255.255.255.255 LEN=576 TOS=0x00 PREC=0x00 TTL=64 ID=0 PROTO=UDP SPT=68 DPT=67 LEN=556
Jun  4 08:20:13 s19 kernel: [686012.958083] IBLOCK:IN=br0 OUT= MAC=3c:7c:3f:0d:99:83:b8:27:eb:f7:ec:c9:08:00 SRC=192.168.111.133 DST=192.168.111.136 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=39224 DF PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1058
Jun  4 08:20:14 s19 kernel: [686013.998108] IBLOCK:IN=br0 OUT= MAC=3c:7c:3f:0d:99:83:b8:27:eb:f7:ec:c9:08:00 SRC=192.168.111.133 DST=192.168.111.136 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=39269 DF PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1059
Jun  4 08:20:15 s19 kernel: [686015.038138] IBLOCK:IN=br0 OUT= MAC=3c:7c:3f:0d:99:83:b8:27:eb:f7:ec:c9:08:00 SRC=192.168.111.133 DST=192.168.111.136 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=39345 DF PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1060
Doug Smythies
  • 15,448
  • 5
  • 44
  • 61