Block incoming connection from ALL IP of a country

I am new here. Requesting help to implement the iptables-mod-geoip module to block incoming connections from a chosen country. For this example, USA. I have followed this helpful blog which provides the step-by-step configuration process. Where the tutorial references CN (China) I have substituted it for US (USA) as denoted by the ISO 3166 country codes standard. The installation and configuration is complete however it would seem the necessary firewall "custom rule" is not invoked when a connection request is made from the filtered country.

I have configured the following custom rule using LuCI;

iptables -A INPUT -m geoip --src-cc US -j DROP

As a simple test, I am using this webpage test tool to select the external test location and point the test tool to my self-hosted website behind the router. The result is the connection is NOT blocked.

I have tried enabling WAN zone logging through LuCI however it didn't show any DROPped requests. I gather the issue is related to how iptables INPUT chain is prioritised, configured, etc.

Note that INPUT handles traffic directly to the router, while FORWARD handles the traffic forwarded into LAN. So likely you are configuring the wrong chain.

There is no reliable geoip that would 100% correctly identify addresses from a country. And it is possible to use VPN services etc. to make traffic appear to be from another country.

1 Like

Got it, thanks @hnyman added a new rule to handle the FORWARD chain and changed the iptables switch to INSERT (I) rather than APPEND (A) and it is now working as expected.

e.g. Firewall rules to block US inbound traffic;

iptables -I INPUT -m geoip --src-cc US -j DROP
iptables -I FORWARD -m geoip --src-cc US -j DROP

While Geo-IP rules will prevent the vast amount of traffic from Country X, it can't block all traffic, as @hnyman mentioned in regards to VPNs.

I use Sophos UTM for my WAN facing router, and it creates it's own GeoIP chain, of which contains the GeoIP rules.

  • For example:
    sophos-utm:/root # iptables --list-rules | grep GEO
    iptables -N  GEOIP_OUT
    iptables -N  GEOIP_REJECT
    iptables -A  OUTPUT  ! -o  lo                                                                          -m  conntrack   --ctstate INVALID,NEW,RELATED       -j  GEOIP_OUT
    iptables -A  GEOIP_OUT                       -p  tcp -m  tcp --sport       1:65535     --dport 3400                    -m        owner     --uid-owner 0   -j  RETURN
    iptables -A  GEOIP_OUT -d -p  tcp -m  tcp --sport       1:65535     --dport 587                                                         -j  RETURN
    iptables -A  GEOIP_OUT -d  -p  udp -m  udp --sport       1024:65535  --dport 162                                                         -j  RETURN
    iptables -A  GEOIP_OUT                       -p  udp -m  set --match-set   ZnYJhwlCS1N6GfRSqcFL9w dst  -m  udp         --sport   123:65535 --dport     123 -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  AI,AG,AW,BS,BB,BZ,BM,CA,KY,CR,GL,GD,GP,MQ,MX                                    -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  MS,NI,PA,PR,BL,KN,LC,MF,PM,VC,TT,TC,US,VG,VI                                    -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  AX,AL,AD,AT,BY,BE,BG,DK,EE,FO,FI,FR,DE,GI,GB                                    -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  GR,GG,VA,HU,IS,IE,IM,IT,JE,LV,LI,LT,LU,MK,MT                                    -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  MC,ME,NL,NO,PL,PT,SM,ES,SJ,SE,CH                                                -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  AS,AU,CK,FJ,GU,KI,MH,FM,NR,NC,NZ,NU,NF,MP,PW                                    -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  PG,PN,PF,WS,SB,TK,TO,TV,UM,VU,WF                                                -j  RETURN
    iptables -A  GEOIP_OUT -d -m  geoip   --source-country  AQ,BV,TF,HM,GS                                                                  -j  RETURN
    iptables -A  GEOIP_OUT                                                                                                   -m      owner     --uid-owner 810 -j  RETURN
    iptables -A  GEOIP_OUT                       -p  tcp -m  tcp --sport       1024:65535  --dport 53                                                          -j  RETURN
    iptables -A  GEOIP_OUT                       -p  udp -m  udp --sport       1024:65535  --dport 53                                                          -j  RETURN
    iptables -A  GEOIP_OUT                       -p  tcp -m  tcp --sport       1:65535     -m  multiport   --dports 80,443   -m      owner     --uid-owner 0   -j  RETURN
    iptables -A  GEOIP_REJECT                                                              -m  limit       --limit  1/sec    -m      logmark   --logmark 60019 -j  NFLOG   -iptables -Nflog-prefix  "<[[---  GEOIP_DROP ---]]> : "
    iptables -A  GEOIP_REJECT                    -p  tcp                                                                                                       -j  REJECT  --reject-with   tcp-reset
    iptables -A  GEOIP_REJECT                                                                                                                                  -j  REJECT  --reject-with   icmp-port-unreachable

For logging, you're better off creating your own log chain for the inbound requests going to your web server

 #::: Traffic Rules :::#
 # LuCI: Network - Firewall - Custom Rules
   # These rules make the following assumptions:
     # WAN Interface:      eth0
     # Web Server IP:
     # Web Server Ports:   80 ; 8080 ; 443 ; 10443

     # Establish Custom Zones #
 iptables  -N  Web_Server
 iptables  -N  LOG-WS

     # Establish Rules #
 iptables  -A  web-server  -d  -i eth0   -m  multiport   --dports  80,443,8080,10443                             -j  LOG-Web_Server

     # Apply Rules #
 iptables  -I  INPUT       -d  -i eth0   -m  multiport   --dports  80,443,8080,10443   -m  state   --state NEW   -j  Web_Server

     # Log Traffic #
 iptables  -A  LOG-Web_Server                                                                                                     -j  LOG   --log-prefix    "<[[---  Web Server Traffic ---]]> : "    --log-level 4  
1 Like

Wow you're blocking a wide range of countries! ... Thanks @JW0914 for the tips! ...

Hi, sorry for the late reply, but Im doing as you said and it is not only blocking incoming, but also outgoing.

How could you access after you blocked US, I cant open any US website

2 may have wished to make a new thread...

Correct. If you block one direction, that's still one direction blocked; you won't get traffic.

  • nslookup
  • Allow IPs
  • Done

well i guess it was more helpful to keep the same thread, being related to the same topic

ok, now i understood that if i go to a US website. that website will be sending me the data, and for obvious reason if im blocking incomming i will not get the page

thanks for the help!

1 Like

What could i do if i want to block every country and just allowing my own country for a specific vlan?
for blocking most countrys i guess should be something similar to this + adding the interface for the vlan?

and for allowing my country should be something like this?
iptables -i eth0.10 -I INPUT -m geoip --src-cc EC -j ALLOW
iptables -i eth0.10 -I FORWARD -m geoip --src-cc EC -j ALLOW

FYI banip supports geo-ip blacklisting.

1 Like

great to know, i will do my research about it!!


This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.