Learn about Centmin Mod LEMP Stack today
Register Now

Featured CSF How to block country traffic in CSF Firewall

Discussion in 'Centmin Mod User Tutorials & Guides' started by eva2000, Apr 11, 2019.

Thread Status:
Not open for further replies.
  1. eva2000

    eva2000 Administrator Staff Member

    53,243
    12,116
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,654
    Local Time:
    1:14 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+
    You can do country blocking at server's CSF Firewall level outlined at https://www.liquidweb.com/kb/how-to-block-traffic-by-country-in-the-csf-firewall/. The guide shows CSF Firewall gui control panel but Centmin Mod CSF Firewall doesn't use gui control panel so you need to edit CSF Firewall config file using linux text editor at /etc/csf/csf.conf from step 2 of that linked guide. The settings names in the article are still the same so you need to find those settings in /etc/csf/csf.conf.

    Backup CSF Firewall Configuration



    Before you edit /etc/csf/csf.conf, you will want to backup the existing configuration and be able to restore from backup if needed. You can read how to do this at How To Backup & Restore CSF Firewall Configuration Profiles.

    Blocking Country Traffic in CSF Firewall Configuration



    To deny access to the US, Great Britain, and Germany, you set CC_DENY to the following:
    Code (Text):
    CC_DENY=US,GB,DE


    After editing /etc/csf/csf.conf you need to restart CSF Firewall and LFD services via
    Code (Text):
    csf -ra


    However, country level blocking at CSF Firewall level can use alot of server resources for memory and cpu due to number of IPs belonging to a country level block.
    The resource usage and slowdowns can be reduced if you are using a non-OpenVZ server i.e. dedicated or Xen, KVM based VPS due to Linux Kernel level IPSET support which Centmin Mod automatically enables in CSF Firewall's IPSET support on initial installation. Non-Centmin Mod servers won't auto enable IPSET support in CSF Firewall though so if you're using other control panels beware. OpenVZ VPS does not have IPSET support so you can can't use it.

    If you have IPSET enabled, you can also list the CSF Firewall's IPSET created set names using ipset command (manual)
    Code (Text):
    ipset list -n
    

    which lists the following IPSET set names created by CSF Firewall. So IPv4 IPs banned/denied by CSF Firewall are hashed into the chain_DENY IPSET set. IPv6 IPs banned are hashed into chain_6_DENY set. Whitelisted allowed IPv4 IPs hashed into chain_ALLOW and whitelisted allowed IPv6 IPs are hashed into chain_6_ALLOW set.
    Code (Text):
    ipset list -n
    chain_DENY
    chain_6_DENY
    chain_ALLOWDYN
    chain_6_ALLOWDYN
    chain_ALLOW
    chain_6_ALLOW
    

    You can check statistics of how much memory is used and how many IPs are within each IPSET set using command below
    Code (Text):
    ipset list -n | while read s; do echo "----"; ipset list $s | head -n8; done
    

    example output
    Code (Text):
    ipset list -n | while read s; do echo "----"; ipset list $s | head -n8; done
    ----
    Name: chain_DENY
    Type: hash:net
    Revision: 6
    Header: family inet hashsize 1024 maxelem 65536
    Size in memory: 10584
    References: 2
    Number of entries: 171
    Members:
    ----
    Name: chain_6_DENY
    Type: hash:net
    Revision: 6
    Header: family inet6 hashsize 1024 maxelem 65536
    Size in memory: 1128
    References: 2
    Number of entries: 0
    Members:
    ----
    Name: chain_ALLOWDYN
    Type: hash:net
    Revision: 6
    Header: family inet hashsize 1024 maxelem 65536
    Size in memory: 344
    References: 2
    Number of entries: 0
    Members:
    ----
    Name: chain_6_ALLOWDYN
    Type: hash:net
    Revision: 6
    Header: family inet6 hashsize 1024 maxelem 65536
    Size in memory: 1128
    References: 2
    Number of entries: 0
    Members:
    ----
    Name: chain_ALLOW
    Type: hash:net
    Revision: 6
    Header: family inet hashsize 1024 maxelem 65536
    Size in memory: 1624
    References: 2
    Number of entries: 20
    Members:
    ----
    Name: chain_6_ALLOW
    Type: hash:net
    Revision: 6
    Header: family inet6 hashsize 1024 maxelem 65536
    Size in memory: 1912
    References: 2
    Number of entries: 7
    Members:
    



    Important



    Be very careful doing country level blocking because you can accidentally block legit traffic and connections required to maintain and secure your server's installed software.
    • For example, CSF Firewall gets automatic updates from download.configserver.com and they come from servers in a specific country. If you block the country in CSF Firewall where download.configserver.com is located, then you will not be able to get CSF Firewall updates on your server anymore. Centmin Mod 123.09beta01 and newer on initial install will try to whitelist the detected IPs for download.configserver.com server so that they do not get blocked by CSF Firewall. But download.configserver.com associated IPs can change so beware of this. Example of current download.configserver.com geo location for it's IP is DE country code = Germany
      Code (Text):
      dig +short A download.configserver.com | while read i; do curl -s https://ipinfo.io/$i; done
      {
        "ip": "85.10.199.177",
        "hostname": "download.configserver.com",
        "city": "Roesrath",
        "region": "North Rhine-Westphalia",
        "country": "DE",
        "loc": "50.8980,7.1759",
        "postal": "51503",
        "org": "AS24940 Hetzner Online GmbH"
      }
      
    • Other downloads made by Centmin Mod for updates to nginx, php or php extensions may also come from countries that get caught in a country level CSF Firewall block list. This will prevent you from updating those downloads too. Centmin Mod 123.09beta01 and newer on initial install will try to whitelist the detected IPs from nginx.org server so that they do not get blocked by CSF Firewall. However, Nginx has other downloads needed from other sources which may get blocked.
    • CSF Firewall advanced blocklists config at /etc/csf/csf.blocklists can optionally be enabled by end user and these blocklists are downloaded from 3rd party web sites. If you block a country where those blocklists are hosted, then you will not be able to get up to date blocklists for CSF Firewall operation.

    Alternatives



    A safer alternative if you want to block countries for your site/web app only, is to block from Nginx server level which you can do using Centmin Mod 123.09beta01 and newer and using optionally enabled GeoIP 2 Nginx module instead. See How to enable GeoIP 2 Lite Nginx Module Support ? This GeoIP 2 Nginx level country blocking method won't block server level downloads.
     
    Last edited: Apr 11, 2019
  2. eva2000

    eva2000 Administrator Staff Member

    53,243
    12,116
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,654
    Local Time:
    1:14 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+

    How To Block Country For Specific Ports Only



    For a more narrow focus, you can also configure CSF Firewall to only block specific country codes for specific TCP/UDP ports only via settings in /etc/csf/csf.conf CSF Firewall config file. As per above gotcha's be careful when you do this due to large number of IPs being blocked can can use alot of server resources and slow the server down if you're server doesn't have adequate resources and that you only do this on non-OpenVZ systems which support IPSET as outlined above.

    I recently spun up a Upcloud KVM VPS for Centmin Mod testing and noticed alot of failed connections, or non TLS cleartext session attempts/timeouts to pure-ftpd FTP server which pure-ftpd is configured to reject. Normally, I stop pure-ftpd ftp server on my installs and only enable it when I need to use it. But if that isn't an option for you, read on.
    Code (Text):
    grep -i pure-ftpd /var/log/messages | egrep -i 'Timeout|cleartext|weak ciphers'
    

    Code (Text):
    grep -i pure-ftpd /var/log/messages | egrep -i 'Timeout|cleartext|weak ciphers'  | tail -10
    Jun  2 10:12:22 [localhost] pure-ftpd: (?@5.113.190.206) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:12:27 [localhost] pure-ftpd: (?@5.117.179.57) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:13:06 [localhost] pure-ftpd: (?@5.127.17.190) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:14:41 [localhost] pure-ftpd: (?@5.124.224.242) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:14:47 [localhost] pure-ftpd: (?@95.38.215.219) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:15:16 [localhost] pure-ftpd: (?@5.115.179.111) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:15:37 [localhost] pure-ftpd: (?@5.106.148.86) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:27:47 [localhost] pure-ftpd: (?@137.97.154.129) [INFO] Timeout - try typing a little faster next time
    Jun  2 10:33:26 [localhost] pure-ftpd: (?@151.236.176.167) [WARNING] Sorry, cleartext sessions and weak ciphers are not accepted on this server.#012Please reconnect using TLS security mechanisms.
    Jun  2 10:56:51 [localhost] pure-ftpd: (?@83.120.67.100) [INFO] Timeout - try typing a little faster next time
    

    So I filtered the log /var/log/message for such connections and did a geoip ASN code and country code lookup via my own geoip lookup service I setup on a test Upcloud KVM VPS (using own service means not subject to 3rd parties API rate limits :)) for all the ips related to that filtered grep check and found alot are Arab Emirates and Iran country code based IPs
    Code (Text):
       208 IR 44244
        93 IR 197207
        32 AE 5384
        28 IR 58224
         7 IR 50810
         7 IR 31549
         6 IR 43754
         6 IR 12880
         5 IR 16322
    

    Blocking FTP Port 21 Only For Specific Countries



    So I decided to test out CSF Firewall's specific TCP/UDP port country locking on Upcloud KVM VPS and block Arab Emirates, Iran, China and Russia from connecting to FTP port 21 only.
    Code (Text):
    egrep 'CC_DENY_PORTS = |CC_DENY_PORTS_TCP =' /etc/csf/csf.conf
    CC_DENY_PORTS = "AE,IR,CN,RU"
    CC_DENY_PORTS_TCP = "21"
    

    Editing /etc/csf/csf.conf to set
    Code (Text):
    CC_DENY_PORTS = "AE,IR,CN,RU"
    CC_DENY_PORTS_TCP = "21"
    

    There's also equivalent for UDP ports with setting
    Code (Text):
    CC_DENY_PORTS_UDP = ""

    Example in /etc/csf/csf.conf CSF Firewall config file
    Code (Text):
    # This option denies access from the following countries to specific ports
    # listed in CC_DENY_PORTS_TCP and CC_DENY_PORTS_UDP
    #
    # Note: The rules for this feature are inserted after the allow and deny
    # rules to still allow allowing of IP addresses
    #
    # Each option is a comma separated list of CC's, e.g. "US,GB,DE"
    CC_DENY_PORTS = "AE,IR,CN,RU"
    
    # This option uses the same format as TCP_IN/UDP_IN. The ports listed should
    # NOT be removed from TCP_IN/UDP_IN
    #
    # An example would be to list port 21 here then counties listed in
    # CC_DENY_PORTS cannot access FTP
    CC_DENY_PORTS_TCP = "21"
    CC_DENY_PORTS_UDP = ""
    

    Then restart CSF Firewall
    Code (Text):
    csf -ra
    

    Check how many IP entries are added to IPSET chain sets created by CSF Firewall
    Code (Text):
    csf -ra 2>&1 | grep 'IPSET loading'
    csf: IPSET loading set cc_ae with 544 entries
    csf: IPSET loading set cc_ir with 1388 entries
    csf: IPSET loading set cc_cn with 7182 entries
    csf: IPSET loading set cc_ru with 9520 entries
    

    Verify that one of the IPs listed is now in CSF Firewall's IPSET chain sets using CSF -g grep flag
    Code (Text):
    csf -g 5.113.190.206
    
    Table  Chain            num   pkts bytes target     prot opt in     out     source               destination      
    No matches found for 5.113.190.206 in iptables
    
    
    IPSET: Set:cc_ir Match:5.113.190.206 Setting:CC_DENY_PORTS Country:IR
    
    
    ip6tables:
    
    Table  Chain            num   pkts bytes target     prot opt in     out     source               destination      
    No matches found for 5.113.190.206 in ip6tables
    

    Notice line confirming IP is in IPSET chain = cc_ir that was created on CSF Firewall restart
    Code (Text):
    IPSET: Set:cc_ir Match:5.113.190.206 Setting:CC_DENY_PORTS Country:IR


    Inspecting the IPSET lists info to show size in memory and number of IPs
    Code (Text):
    csf -r 2>&1 | grep 'IPSET loading set' > csf-list.txt
    

    Code (Text):
    while read b; do n=$(echo $b | awk '{print $5}'); c=$(echo $b | awk '{print $7}'); echo "------------"; i=$(ipset list $n | head -n5 | xargs); echo "$i number of ips: $c"; done < csf-list.txt
    

    Code (Text):
    while read b; do n=$(echo $b | awk '{print $5}'); c=$(echo $b | awk '{print $7}'); echo "------------"; i=$(ipset list $n | head -n5 | xargs); echo "$i number of ips: $c"; done < csf-list.txt
    ------------
    Name: cc_ae Type: hash:net Revision: 3 Header: family inet hashsize 1024 maxelem 65536 Size in memory: 30224 number of ips: 544
    ------------
    Name: cc_ir Type: hash:net Revision: 3 Header: family inet hashsize 1024 maxelem 65536 Size in memory: 40944 number of ips: 1388
    ------------
    Name: cc_cn Type: hash:net Revision: 3 Header: family inet hashsize 2048 maxelem 65536 Size in memory: 115472 number of ips: 7182
    ------------
    Name: cc_ru Type: hash:net Revision: 3 Header: family inet hashsize 2048 maxelem 65536 Size in memory: 133648 number of ips: 9520
    
     
Thread Status:
Not open for further replies.