Block China with iptables












9















I just logged in on a GitLab server and noticed that it had 18.974 failed logins since I last checked the server - almost 5 days. I checked the Ip's and it seems that almost all of them were from China and tried to gain access with SSH and Brute Force. I started to block some Ip's but then i realized that it is a huge waste of time and a better idea would be to block the entire country.



Is there any way i can block ALL China or any other country with iptables?



I found some articles on the internet but almost all of them are bash scripts. I'm a newbie on Linux so i don't really understand all those scripts. I find iptables really interesting and i want to learn more about it.



Any ideas ?
Thank you!










share|improve this question


















  • 4





    I solved the same problem in a different way. I hardened SSH on my customer's GitLab server by turning off password and challenge based authentication and only allow login with SSL keys. Maybe that would work in your situation? Blocking IP ranges might reduce the "noise" but it won't give you real protection against brute forcing.

    – blendenzo
    Jan 5 '17 at 13:47











  • so far it didn't worked. the gitlab server is still up and i had 0 break-in. Ssh acces are made only with ssh-keys and i disabled the root login. It's just that i want to learn iptables so bad..

    – Caranfil Alegzandru
    Jan 5 '17 at 14:08






  • 1





    You can also switch your ssh to a non-default port in your router. That dropped my ssh bot attack attempts from hundreds per day to zero.

    – Organic Marble
    Jan 5 '17 at 14:34
















9















I just logged in on a GitLab server and noticed that it had 18.974 failed logins since I last checked the server - almost 5 days. I checked the Ip's and it seems that almost all of them were from China and tried to gain access with SSH and Brute Force. I started to block some Ip's but then i realized that it is a huge waste of time and a better idea would be to block the entire country.



Is there any way i can block ALL China or any other country with iptables?



I found some articles on the internet but almost all of them are bash scripts. I'm a newbie on Linux so i don't really understand all those scripts. I find iptables really interesting and i want to learn more about it.



Any ideas ?
Thank you!










share|improve this question


















  • 4





    I solved the same problem in a different way. I hardened SSH on my customer's GitLab server by turning off password and challenge based authentication and only allow login with SSL keys. Maybe that would work in your situation? Blocking IP ranges might reduce the "noise" but it won't give you real protection against brute forcing.

    – blendenzo
    Jan 5 '17 at 13:47











  • so far it didn't worked. the gitlab server is still up and i had 0 break-in. Ssh acces are made only with ssh-keys and i disabled the root login. It's just that i want to learn iptables so bad..

    – Caranfil Alegzandru
    Jan 5 '17 at 14:08






  • 1





    You can also switch your ssh to a non-default port in your router. That dropped my ssh bot attack attempts from hundreds per day to zero.

    – Organic Marble
    Jan 5 '17 at 14:34














9












9








9


4






I just logged in on a GitLab server and noticed that it had 18.974 failed logins since I last checked the server - almost 5 days. I checked the Ip's and it seems that almost all of them were from China and tried to gain access with SSH and Brute Force. I started to block some Ip's but then i realized that it is a huge waste of time and a better idea would be to block the entire country.



Is there any way i can block ALL China or any other country with iptables?



I found some articles on the internet but almost all of them are bash scripts. I'm a newbie on Linux so i don't really understand all those scripts. I find iptables really interesting and i want to learn more about it.



Any ideas ?
Thank you!










share|improve this question














I just logged in on a GitLab server and noticed that it had 18.974 failed logins since I last checked the server - almost 5 days. I checked the Ip's and it seems that almost all of them were from China and tried to gain access with SSH and Brute Force. I started to block some Ip's but then i realized that it is a huge waste of time and a better idea would be to block the entire country.



Is there any way i can block ALL China or any other country with iptables?



I found some articles on the internet but almost all of them are bash scripts. I'm a newbie on Linux so i don't really understand all those scripts. I find iptables really interesting and i want to learn more about it.



Any ideas ?
Thank you!







networking server ssh iptables firewall






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 5 '17 at 13:40









Caranfil AlegzandruCaranfil Alegzandru

1442312




1442312








  • 4





    I solved the same problem in a different way. I hardened SSH on my customer's GitLab server by turning off password and challenge based authentication and only allow login with SSL keys. Maybe that would work in your situation? Blocking IP ranges might reduce the "noise" but it won't give you real protection against brute forcing.

    – blendenzo
    Jan 5 '17 at 13:47











  • so far it didn't worked. the gitlab server is still up and i had 0 break-in. Ssh acces are made only with ssh-keys and i disabled the root login. It's just that i want to learn iptables so bad..

    – Caranfil Alegzandru
    Jan 5 '17 at 14:08






  • 1





    You can also switch your ssh to a non-default port in your router. That dropped my ssh bot attack attempts from hundreds per day to zero.

    – Organic Marble
    Jan 5 '17 at 14:34














  • 4





    I solved the same problem in a different way. I hardened SSH on my customer's GitLab server by turning off password and challenge based authentication and only allow login with SSL keys. Maybe that would work in your situation? Blocking IP ranges might reduce the "noise" but it won't give you real protection against brute forcing.

    – blendenzo
    Jan 5 '17 at 13:47











  • so far it didn't worked. the gitlab server is still up and i had 0 break-in. Ssh acces are made only with ssh-keys and i disabled the root login. It's just that i want to learn iptables so bad..

    – Caranfil Alegzandru
    Jan 5 '17 at 14:08






  • 1





    You can also switch your ssh to a non-default port in your router. That dropped my ssh bot attack attempts from hundreds per day to zero.

    – Organic Marble
    Jan 5 '17 at 14:34








4




4





I solved the same problem in a different way. I hardened SSH on my customer's GitLab server by turning off password and challenge based authentication and only allow login with SSL keys. Maybe that would work in your situation? Blocking IP ranges might reduce the "noise" but it won't give you real protection against brute forcing.

– blendenzo
Jan 5 '17 at 13:47





I solved the same problem in a different way. I hardened SSH on my customer's GitLab server by turning off password and challenge based authentication and only allow login with SSL keys. Maybe that would work in your situation? Blocking IP ranges might reduce the "noise" but it won't give you real protection against brute forcing.

– blendenzo
Jan 5 '17 at 13:47













so far it didn't worked. the gitlab server is still up and i had 0 break-in. Ssh acces are made only with ssh-keys and i disabled the root login. It's just that i want to learn iptables so bad..

– Caranfil Alegzandru
Jan 5 '17 at 14:08





so far it didn't worked. the gitlab server is still up and i had 0 break-in. Ssh acces are made only with ssh-keys and i disabled the root login. It's just that i want to learn iptables so bad..

– Caranfil Alegzandru
Jan 5 '17 at 14:08




1




1





You can also switch your ssh to a non-default port in your router. That dropped my ssh bot attack attempts from hundreds per day to zero.

– Organic Marble
Jan 5 '17 at 14:34





You can also switch your ssh to a non-default port in your router. That dropped my ssh bot attack attempts from hundreds per day to zero.

– Organic Marble
Jan 5 '17 at 14:34










4 Answers
4






active

oldest

votes


















6














Using iptables to automatically identify, and thereafter block, bad guys for ssh can be done using the recent module. The following segment must come after your generic ESTABLISHED,RELATED line:



...
$IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT
...
# Secure Shell on port 22.
#
# Sometimes I uncomment the next line to simply disable external SSH access.
# Particulalry useful when I am rebooting often, thereby losing my current BADGUY table.
# $IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 22 -j DROP

# Dynamic Badguy List. Detect and DROP Bad IPs that do password attacks on SSH.
# Once they are on the BADGUY list then DROP all packets from them.
# Sometimes make the lock time very long. Typically to try to get rid of coordinated attacks from China.
$IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j LOG --log-prefix "SSH BAD:" --log-level info
$IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j DROP
$IPTABLES -A INPUT -i $EXTIF -p tcp -m tcp --dport 22 -m recent --set --name BADGUY_SSH -j ACCEPT


Now, the recent (the last year or two) problem with China is that they have become very clever and very often once they get blocked from one IP address they simply switch to another on the same sub-net and continue. This runs the risk of running out of default recent table entries (I think the default is 200). I monitor this and then look up the actual IP segment, and permanently block the entire segment. In my case, I do not care about collateral damage, i.e. blocking someone innocent:



#
# After a coordinated attack involving several sub-nets from China, they are now banned forever.
# List includes sub-nets from unknown origin, and perhaps Hong Kong
#
$IPTABLES -A INPUT -i $EXTIF -s 1.80.0.0/12 -d $UNIVERSE -j DROP
$IPTABLES -A INPUT -i $EXTIF -s 27.148.0.0/14 -d $UNIVERSE -j DROP
$IPTABLES -A INPUT -i $EXTIF -s 27.152.0.0/13 -d $UNIVERSE -j DROP
$IPTABLES -A INPUT -i $EXTIF -s 43.229.0.0/16 -d $UNIVERSE -j DROP
$IPTABLES -A INPUT -i $EXTIF -s 43.255.0.0/16 -d $UNIVERSE -j DROP
...


Where in the above:



# The location of the iptables program
#
IPTABLES=/sbin/iptables

#Setting the EXTERNAL and INTERNAL interfaces and addresses for the network
#
EXTIF="enp4s0"
INTIF="enp2s0"
EXTIP="...deleted..."
INTNET="192.168.111.0/24"
INTIP="192.168.111.1/32"
UNIVERSE="0.0.0.0/0"


You can get the entire list of IP addresses for China, or any country, in iptables, or other, format here. However the list is both surprisingly long and rather dynamic. Myself, I decided not to block the entire list.






share|improve this answer


























  • This ^ ! Might be the best answer I've ever received. It might be a dumb question, but i guess all these rules go into a bash script, right? I still have some problems understanding iptables but I find it fascinating.

    – Caranfil Alegzandru
    Jan 6 '17 at 10:13











  • Yes, I use a bash script. Some, and I used too also, use a direct iptables restore method, which is faster to load. I changed because I include some non-iptables commands in the same script.

    – Doug Smythies
    Jan 6 '17 at 14:56



















5














China block using ipset



You can't manually add a few thousand IP addresses to your iptables, and even doing it automatically is a bad idea because it can cause a lot of CPU load (or so I've read). Instead we can use ipset which is designed for this sort of thing. ipset handles big lists of ip addresses; you just create a list and then tell iptables to use that list in a rule.



Note; I assume that the entirety of the following is done as root. Adjust accordingly if your system is based on sudo.



apt-get install ipset


Next, I wrote a small Bash script to do all the work, which you should be able to understand from the comments in it. Create a file:



nano /etc/block-china.sh


Here's what you want to paste into it:



# Create the ipset list
ipset -N china hash:net

# remove any old list that might exist from previous runs of this script
rm cn.zone

# Pull the latest IP set for China
wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

# Add each IP address from the downloaded list into the ipset 'china'
for i in $(cat /etc/cn.zone ); do ipset -A china $i; done

# Restore iptables
/sbin/iptables-restore < /etc/iptables.firewall.rules


Save the file. Make it executable:



chmod +x /etc/block-china.sh


This hasn't done anything yet, but it will in a minute when we run the script. First, we need to add a rule into iptables that refers to this new ipset list the script above defines:



nano /etc/iptables.firewall.rules


Add the following line:



-A INPUT -p tcp -m set --match-set china src -j DROP


Save the file. To be clear, my full iptables.firewall.rules now looks like this:



*filter

# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT

# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Block anything from China
# These rules are pulled from ipset's china list
# The source file is at /etc/cn.zone (which in turn is generated by a shell script at /etc/block-china.sh )
-A INPUT -p tcp -m set --match-set china src -j DROP

# Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Allow SSH connections
#
# The -dport number should be the same port number you set in sshd_config
#
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

# Allow ping
-A INPUT -p icmp -j ACCEPT

# Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT


Right now, nothing has changed with the server because no new rules have been applied; to do so, run the block-china.sh script:



/etc/block-china.sh


This should show some output as it pulls a fresh list of Chinese based IPs and then, after a few seconds or so, it will complete and drop you back to a command prompt.



To test if it worked, run:



iptables -L


You should now see a new rule blocking China – the output ought to look like this:



Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere loopback/8 reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
DROP tcp -- anywhere anywhere match-set china src
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT icmp -- anywhere anywhere
LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
DROP all -- anywhere anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere


Almost done! This works, and will continue to work on re-boots. But, IP addresses change and that list will grow stale over time. If you want to pull and apply an updated list of IPs you can just run the block-china.sh script again.



We can also set the machine to do that automatically via a cron job:



crontab -e


Add a line such as this:



* 5 * * * /etc/block-china.sh


This will run /etc/block-china.sh at 5am every day. The user running the script will need to be root or have root privileges.



source






share|improve this answer
























  • Why limit it to only tcp protocol? It seems to work without specifying protocol. Suggest to use the newer aggregated lists, as they are much shorter: wget http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone

    – Doug Smythies
    Dec 20 '18 at 0:40











  • There is nothing here that restores the ipset after re-boot.

    – Doug Smythies
    Dec 21 '18 at 19:59



















4














You may want to install something like fail2ban so that it blocks ips that attempt to log into your server and fail.






share|improve this answer
























  • i could also use csf firewall and block every country i want from the config files. The thing is that i really want to use iptables so i can learn more about it.

    – Caranfil Alegzandru
    Jan 5 '17 at 14:07











  • You would have to see what countries have what ip address blocks assigned to them to figure out who to block. Not sure if it would be super accurate or not though. You can use iptables -L to show current iptables rules, iptables-save to show what commands were run to create said rules, then design your own rules and test using test machines to learn about it. That is how I learned it.

    – Kyle H
    Jan 5 '17 at 14:39



















0














You can use the geoip-module for iptables:
https://linoxide.com/linux-how-to/block-ips-countries-geoip-addons/




Once our system is upgraded and dependencies are installed, we'll now
install the xtables-addons in our machine. To do so, we'll download
the latest tarball from the official xtables-addons project site using
wget. Once it's downloaded, we'll extract the tarball, then compile
and install it in our machine.



wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.13.tar.xz
tar xf xtables-addons-2.13.tar.xz
cd xtables-addons-2.13
./configure
make
make install [...]


Next, we'll run a module called xt_geoip that comes with the
xtables-addons extension which downloads the GeoIP database from
MaxMind and converts it into a binary form recognized by xt_geoip.
Once it's downloaded, we'll build it and move them to the required
xt_geoip path ie /usr/share/xt_geoip.



cd geoip
./xt_geoip_dl
./xt_geoip_build GeoIPCountryWhois.csv
mkdir -p /usr/share/xt_geoip/
cp -r {BE,LE} /usr/share/xt_geoip/


Here's the basic syntax for using iptables with geoip module in order
to block traffic originating from or destined to a country. Here, we
need to use two-letter ISO3166 code in place of country , for eg., US
for United States, IE for Ireland, IN for India, CN for China and so
on.



iptables -m geoip --src-cc country[,country...] --dst-cc country[,country...]






share|improve this answer

























    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "89"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f868334%2fblock-china-with-iptables%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    Using iptables to automatically identify, and thereafter block, bad guys for ssh can be done using the recent module. The following segment must come after your generic ESTABLISHED,RELATED line:



    ...
    $IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT
    ...
    # Secure Shell on port 22.
    #
    # Sometimes I uncomment the next line to simply disable external SSH access.
    # Particulalry useful when I am rebooting often, thereby losing my current BADGUY table.
    # $IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 22 -j DROP

    # Dynamic Badguy List. Detect and DROP Bad IPs that do password attacks on SSH.
    # Once they are on the BADGUY list then DROP all packets from them.
    # Sometimes make the lock time very long. Typically to try to get rid of coordinated attacks from China.
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j LOG --log-prefix "SSH BAD:" --log-level info
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j DROP
    $IPTABLES -A INPUT -i $EXTIF -p tcp -m tcp --dport 22 -m recent --set --name BADGUY_SSH -j ACCEPT


    Now, the recent (the last year or two) problem with China is that they have become very clever and very often once they get blocked from one IP address they simply switch to another on the same sub-net and continue. This runs the risk of running out of default recent table entries (I think the default is 200). I monitor this and then look up the actual IP segment, and permanently block the entire segment. In my case, I do not care about collateral damage, i.e. blocking someone innocent:



    #
    # After a coordinated attack involving several sub-nets from China, they are now banned forever.
    # List includes sub-nets from unknown origin, and perhaps Hong Kong
    #
    $IPTABLES -A INPUT -i $EXTIF -s 1.80.0.0/12 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.148.0.0/14 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.152.0.0/13 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.229.0.0/16 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.255.0.0/16 -d $UNIVERSE -j DROP
    ...


    Where in the above:



    # The location of the iptables program
    #
    IPTABLES=/sbin/iptables

    #Setting the EXTERNAL and INTERNAL interfaces and addresses for the network
    #
    EXTIF="enp4s0"
    INTIF="enp2s0"
    EXTIP="...deleted..."
    INTNET="192.168.111.0/24"
    INTIP="192.168.111.1/32"
    UNIVERSE="0.0.0.0/0"


    You can get the entire list of IP addresses for China, or any country, in iptables, or other, format here. However the list is both surprisingly long and rather dynamic. Myself, I decided not to block the entire list.






    share|improve this answer


























    • This ^ ! Might be the best answer I've ever received. It might be a dumb question, but i guess all these rules go into a bash script, right? I still have some problems understanding iptables but I find it fascinating.

      – Caranfil Alegzandru
      Jan 6 '17 at 10:13











    • Yes, I use a bash script. Some, and I used too also, use a direct iptables restore method, which is faster to load. I changed because I include some non-iptables commands in the same script.

      – Doug Smythies
      Jan 6 '17 at 14:56
















    6














    Using iptables to automatically identify, and thereafter block, bad guys for ssh can be done using the recent module. The following segment must come after your generic ESTABLISHED,RELATED line:



    ...
    $IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT
    ...
    # Secure Shell on port 22.
    #
    # Sometimes I uncomment the next line to simply disable external SSH access.
    # Particulalry useful when I am rebooting often, thereby losing my current BADGUY table.
    # $IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 22 -j DROP

    # Dynamic Badguy List. Detect and DROP Bad IPs that do password attacks on SSH.
    # Once they are on the BADGUY list then DROP all packets from them.
    # Sometimes make the lock time very long. Typically to try to get rid of coordinated attacks from China.
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j LOG --log-prefix "SSH BAD:" --log-level info
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j DROP
    $IPTABLES -A INPUT -i $EXTIF -p tcp -m tcp --dport 22 -m recent --set --name BADGUY_SSH -j ACCEPT


    Now, the recent (the last year or two) problem with China is that they have become very clever and very often once they get blocked from one IP address they simply switch to another on the same sub-net and continue. This runs the risk of running out of default recent table entries (I think the default is 200). I monitor this and then look up the actual IP segment, and permanently block the entire segment. In my case, I do not care about collateral damage, i.e. blocking someone innocent:



    #
    # After a coordinated attack involving several sub-nets from China, they are now banned forever.
    # List includes sub-nets from unknown origin, and perhaps Hong Kong
    #
    $IPTABLES -A INPUT -i $EXTIF -s 1.80.0.0/12 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.148.0.0/14 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.152.0.0/13 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.229.0.0/16 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.255.0.0/16 -d $UNIVERSE -j DROP
    ...


    Where in the above:



    # The location of the iptables program
    #
    IPTABLES=/sbin/iptables

    #Setting the EXTERNAL and INTERNAL interfaces and addresses for the network
    #
    EXTIF="enp4s0"
    INTIF="enp2s0"
    EXTIP="...deleted..."
    INTNET="192.168.111.0/24"
    INTIP="192.168.111.1/32"
    UNIVERSE="0.0.0.0/0"


    You can get the entire list of IP addresses for China, or any country, in iptables, or other, format here. However the list is both surprisingly long and rather dynamic. Myself, I decided not to block the entire list.






    share|improve this answer


























    • This ^ ! Might be the best answer I've ever received. It might be a dumb question, but i guess all these rules go into a bash script, right? I still have some problems understanding iptables but I find it fascinating.

      – Caranfil Alegzandru
      Jan 6 '17 at 10:13











    • Yes, I use a bash script. Some, and I used too also, use a direct iptables restore method, which is faster to load. I changed because I include some non-iptables commands in the same script.

      – Doug Smythies
      Jan 6 '17 at 14:56














    6












    6








    6







    Using iptables to automatically identify, and thereafter block, bad guys for ssh can be done using the recent module. The following segment must come after your generic ESTABLISHED,RELATED line:



    ...
    $IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT
    ...
    # Secure Shell on port 22.
    #
    # Sometimes I uncomment the next line to simply disable external SSH access.
    # Particulalry useful when I am rebooting often, thereby losing my current BADGUY table.
    # $IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 22 -j DROP

    # Dynamic Badguy List. Detect and DROP Bad IPs that do password attacks on SSH.
    # Once they are on the BADGUY list then DROP all packets from them.
    # Sometimes make the lock time very long. Typically to try to get rid of coordinated attacks from China.
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j LOG --log-prefix "SSH BAD:" --log-level info
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j DROP
    $IPTABLES -A INPUT -i $EXTIF -p tcp -m tcp --dport 22 -m recent --set --name BADGUY_SSH -j ACCEPT


    Now, the recent (the last year or two) problem with China is that they have become very clever and very often once they get blocked from one IP address they simply switch to another on the same sub-net and continue. This runs the risk of running out of default recent table entries (I think the default is 200). I monitor this and then look up the actual IP segment, and permanently block the entire segment. In my case, I do not care about collateral damage, i.e. blocking someone innocent:



    #
    # After a coordinated attack involving several sub-nets from China, they are now banned forever.
    # List includes sub-nets from unknown origin, and perhaps Hong Kong
    #
    $IPTABLES -A INPUT -i $EXTIF -s 1.80.0.0/12 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.148.0.0/14 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.152.0.0/13 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.229.0.0/16 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.255.0.0/16 -d $UNIVERSE -j DROP
    ...


    Where in the above:



    # The location of the iptables program
    #
    IPTABLES=/sbin/iptables

    #Setting the EXTERNAL and INTERNAL interfaces and addresses for the network
    #
    EXTIF="enp4s0"
    INTIF="enp2s0"
    EXTIP="...deleted..."
    INTNET="192.168.111.0/24"
    INTIP="192.168.111.1/32"
    UNIVERSE="0.0.0.0/0"


    You can get the entire list of IP addresses for China, or any country, in iptables, or other, format here. However the list is both surprisingly long and rather dynamic. Myself, I decided not to block the entire list.






    share|improve this answer















    Using iptables to automatically identify, and thereafter block, bad guys for ssh can be done using the recent module. The following segment must come after your generic ESTABLISHED,RELATED line:



    ...
    $IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT
    ...
    # Secure Shell on port 22.
    #
    # Sometimes I uncomment the next line to simply disable external SSH access.
    # Particulalry useful when I am rebooting often, thereby losing my current BADGUY table.
    # $IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 22 -j DROP

    # Dynamic Badguy List. Detect and DROP Bad IPs that do password attacks on SSH.
    # Once they are on the BADGUY list then DROP all packets from them.
    # Sometimes make the lock time very long. Typically to try to get rid of coordinated attacks from China.
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j LOG --log-prefix "SSH BAD:" --log-level info
    $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 3 --seconds 90000 --name BADGUY_SSH -j DROP
    $IPTABLES -A INPUT -i $EXTIF -p tcp -m tcp --dport 22 -m recent --set --name BADGUY_SSH -j ACCEPT


    Now, the recent (the last year or two) problem with China is that they have become very clever and very often once they get blocked from one IP address they simply switch to another on the same sub-net and continue. This runs the risk of running out of default recent table entries (I think the default is 200). I monitor this and then look up the actual IP segment, and permanently block the entire segment. In my case, I do not care about collateral damage, i.e. blocking someone innocent:



    #
    # After a coordinated attack involving several sub-nets from China, they are now banned forever.
    # List includes sub-nets from unknown origin, and perhaps Hong Kong
    #
    $IPTABLES -A INPUT -i $EXTIF -s 1.80.0.0/12 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.148.0.0/14 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 27.152.0.0/13 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.229.0.0/16 -d $UNIVERSE -j DROP
    $IPTABLES -A INPUT -i $EXTIF -s 43.255.0.0/16 -d $UNIVERSE -j DROP
    ...


    Where in the above:



    # The location of the iptables program
    #
    IPTABLES=/sbin/iptables

    #Setting the EXTERNAL and INTERNAL interfaces and addresses for the network
    #
    EXTIF="enp4s0"
    INTIF="enp2s0"
    EXTIP="...deleted..."
    INTNET="192.168.111.0/24"
    INTIP="192.168.111.1/32"
    UNIVERSE="0.0.0.0/0"


    You can get the entire list of IP addresses for China, or any country, in iptables, or other, format here. However the list is both surprisingly long and rather dynamic. Myself, I decided not to block the entire list.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 5 '17 at 16:54

























    answered Jan 5 '17 at 16:41









    Doug SmythiesDoug Smythies

    7,28131530




    7,28131530













    • This ^ ! Might be the best answer I've ever received. It might be a dumb question, but i guess all these rules go into a bash script, right? I still have some problems understanding iptables but I find it fascinating.

      – Caranfil Alegzandru
      Jan 6 '17 at 10:13











    • Yes, I use a bash script. Some, and I used too also, use a direct iptables restore method, which is faster to load. I changed because I include some non-iptables commands in the same script.

      – Doug Smythies
      Jan 6 '17 at 14:56



















    • This ^ ! Might be the best answer I've ever received. It might be a dumb question, but i guess all these rules go into a bash script, right? I still have some problems understanding iptables but I find it fascinating.

      – Caranfil Alegzandru
      Jan 6 '17 at 10:13











    • Yes, I use a bash script. Some, and I used too also, use a direct iptables restore method, which is faster to load. I changed because I include some non-iptables commands in the same script.

      – Doug Smythies
      Jan 6 '17 at 14:56

















    This ^ ! Might be the best answer I've ever received. It might be a dumb question, but i guess all these rules go into a bash script, right? I still have some problems understanding iptables but I find it fascinating.

    – Caranfil Alegzandru
    Jan 6 '17 at 10:13





    This ^ ! Might be the best answer I've ever received. It might be a dumb question, but i guess all these rules go into a bash script, right? I still have some problems understanding iptables but I find it fascinating.

    – Caranfil Alegzandru
    Jan 6 '17 at 10:13













    Yes, I use a bash script. Some, and I used too also, use a direct iptables restore method, which is faster to load. I changed because I include some non-iptables commands in the same script.

    – Doug Smythies
    Jan 6 '17 at 14:56





    Yes, I use a bash script. Some, and I used too also, use a direct iptables restore method, which is faster to load. I changed because I include some non-iptables commands in the same script.

    – Doug Smythies
    Jan 6 '17 at 14:56













    5














    China block using ipset



    You can't manually add a few thousand IP addresses to your iptables, and even doing it automatically is a bad idea because it can cause a lot of CPU load (or so I've read). Instead we can use ipset which is designed for this sort of thing. ipset handles big lists of ip addresses; you just create a list and then tell iptables to use that list in a rule.



    Note; I assume that the entirety of the following is done as root. Adjust accordingly if your system is based on sudo.



    apt-get install ipset


    Next, I wrote a small Bash script to do all the work, which you should be able to understand from the comments in it. Create a file:



    nano /etc/block-china.sh


    Here's what you want to paste into it:



    # Create the ipset list
    ipset -N china hash:net

    # remove any old list that might exist from previous runs of this script
    rm cn.zone

    # Pull the latest IP set for China
    wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

    # Add each IP address from the downloaded list into the ipset 'china'
    for i in $(cat /etc/cn.zone ); do ipset -A china $i; done

    # Restore iptables
    /sbin/iptables-restore < /etc/iptables.firewall.rules


    Save the file. Make it executable:



    chmod +x /etc/block-china.sh


    This hasn't done anything yet, but it will in a minute when we run the script. First, we need to add a rule into iptables that refers to this new ipset list the script above defines:



    nano /etc/iptables.firewall.rules


    Add the following line:



    -A INPUT -p tcp -m set --match-set china src -j DROP


    Save the file. To be clear, my full iptables.firewall.rules now looks like this:



    *filter

    # Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
    -A INPUT -i lo -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT

    # Accept all established inbound connections
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    # Block anything from China
    # These rules are pulled from ipset's china list
    # The source file is at /etc/cn.zone (which in turn is generated by a shell script at /etc/block-china.sh )
    -A INPUT -p tcp -m set --match-set china src -j DROP

    # Allow all outbound traffic - you can modify this to only allow certain traffic
    -A OUTPUT -j ACCEPT

    # Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
    -A INPUT -p tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp --dport 443 -j ACCEPT

    # Allow SSH connections
    #
    # The -dport number should be the same port number you set in sshd_config
    #
    -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

    # Allow ping
    -A INPUT -p icmp -j ACCEPT

    # Log iptables denied calls
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

    # Drop all other inbound - default deny unless explicitly allowed policy
    -A INPUT -j DROP
    -A FORWARD -j DROP

    COMMIT


    Right now, nothing has changed with the server because no new rules have been applied; to do so, run the block-china.sh script:



    /etc/block-china.sh


    This should show some output as it pulls a fresh list of Chinese based IPs and then, after a few seconds or so, it will complete and drop you back to a command prompt.



    To test if it worked, run:



    iptables -L


    You should now see a new rule blocking China – the output ought to look like this:



    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere
    REJECT all -- anywhere loopback/8 reject-with icmp-port-unreachable
    ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
    DROP tcp -- anywhere anywhere match-set china src
    ACCEPT tcp -- anywhere anywhere tcp dpt:http
    ACCEPT tcp -- anywhere anywhere tcp dpt:https
    ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
    DROP all -- anywhere anywhere

    Chain FORWARD (policy ACCEPT)
    target prot opt source destination
    DROP all -- anywhere anywhere

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere


    Almost done! This works, and will continue to work on re-boots. But, IP addresses change and that list will grow stale over time. If you want to pull and apply an updated list of IPs you can just run the block-china.sh script again.



    We can also set the machine to do that automatically via a cron job:



    crontab -e


    Add a line such as this:



    * 5 * * * /etc/block-china.sh


    This will run /etc/block-china.sh at 5am every day. The user running the script will need to be root or have root privileges.



    source






    share|improve this answer
























    • Why limit it to only tcp protocol? It seems to work without specifying protocol. Suggest to use the newer aggregated lists, as they are much shorter: wget http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone

      – Doug Smythies
      Dec 20 '18 at 0:40











    • There is nothing here that restores the ipset after re-boot.

      – Doug Smythies
      Dec 21 '18 at 19:59
















    5














    China block using ipset



    You can't manually add a few thousand IP addresses to your iptables, and even doing it automatically is a bad idea because it can cause a lot of CPU load (or so I've read). Instead we can use ipset which is designed for this sort of thing. ipset handles big lists of ip addresses; you just create a list and then tell iptables to use that list in a rule.



    Note; I assume that the entirety of the following is done as root. Adjust accordingly if your system is based on sudo.



    apt-get install ipset


    Next, I wrote a small Bash script to do all the work, which you should be able to understand from the comments in it. Create a file:



    nano /etc/block-china.sh


    Here's what you want to paste into it:



    # Create the ipset list
    ipset -N china hash:net

    # remove any old list that might exist from previous runs of this script
    rm cn.zone

    # Pull the latest IP set for China
    wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

    # Add each IP address from the downloaded list into the ipset 'china'
    for i in $(cat /etc/cn.zone ); do ipset -A china $i; done

    # Restore iptables
    /sbin/iptables-restore < /etc/iptables.firewall.rules


    Save the file. Make it executable:



    chmod +x /etc/block-china.sh


    This hasn't done anything yet, but it will in a minute when we run the script. First, we need to add a rule into iptables that refers to this new ipset list the script above defines:



    nano /etc/iptables.firewall.rules


    Add the following line:



    -A INPUT -p tcp -m set --match-set china src -j DROP


    Save the file. To be clear, my full iptables.firewall.rules now looks like this:



    *filter

    # Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
    -A INPUT -i lo -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT

    # Accept all established inbound connections
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    # Block anything from China
    # These rules are pulled from ipset's china list
    # The source file is at /etc/cn.zone (which in turn is generated by a shell script at /etc/block-china.sh )
    -A INPUT -p tcp -m set --match-set china src -j DROP

    # Allow all outbound traffic - you can modify this to only allow certain traffic
    -A OUTPUT -j ACCEPT

    # Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
    -A INPUT -p tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp --dport 443 -j ACCEPT

    # Allow SSH connections
    #
    # The -dport number should be the same port number you set in sshd_config
    #
    -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

    # Allow ping
    -A INPUT -p icmp -j ACCEPT

    # Log iptables denied calls
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

    # Drop all other inbound - default deny unless explicitly allowed policy
    -A INPUT -j DROP
    -A FORWARD -j DROP

    COMMIT


    Right now, nothing has changed with the server because no new rules have been applied; to do so, run the block-china.sh script:



    /etc/block-china.sh


    This should show some output as it pulls a fresh list of Chinese based IPs and then, after a few seconds or so, it will complete and drop you back to a command prompt.



    To test if it worked, run:



    iptables -L


    You should now see a new rule blocking China – the output ought to look like this:



    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere
    REJECT all -- anywhere loopback/8 reject-with icmp-port-unreachable
    ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
    DROP tcp -- anywhere anywhere match-set china src
    ACCEPT tcp -- anywhere anywhere tcp dpt:http
    ACCEPT tcp -- anywhere anywhere tcp dpt:https
    ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
    DROP all -- anywhere anywhere

    Chain FORWARD (policy ACCEPT)
    target prot opt source destination
    DROP all -- anywhere anywhere

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere


    Almost done! This works, and will continue to work on re-boots. But, IP addresses change and that list will grow stale over time. If you want to pull and apply an updated list of IPs you can just run the block-china.sh script again.



    We can also set the machine to do that automatically via a cron job:



    crontab -e


    Add a line such as this:



    * 5 * * * /etc/block-china.sh


    This will run /etc/block-china.sh at 5am every day. The user running the script will need to be root or have root privileges.



    source






    share|improve this answer
























    • Why limit it to only tcp protocol? It seems to work without specifying protocol. Suggest to use the newer aggregated lists, as they are much shorter: wget http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone

      – Doug Smythies
      Dec 20 '18 at 0:40











    • There is nothing here that restores the ipset after re-boot.

      – Doug Smythies
      Dec 21 '18 at 19:59














    5












    5








    5







    China block using ipset



    You can't manually add a few thousand IP addresses to your iptables, and even doing it automatically is a bad idea because it can cause a lot of CPU load (or so I've read). Instead we can use ipset which is designed for this sort of thing. ipset handles big lists of ip addresses; you just create a list and then tell iptables to use that list in a rule.



    Note; I assume that the entirety of the following is done as root. Adjust accordingly if your system is based on sudo.



    apt-get install ipset


    Next, I wrote a small Bash script to do all the work, which you should be able to understand from the comments in it. Create a file:



    nano /etc/block-china.sh


    Here's what you want to paste into it:



    # Create the ipset list
    ipset -N china hash:net

    # remove any old list that might exist from previous runs of this script
    rm cn.zone

    # Pull the latest IP set for China
    wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

    # Add each IP address from the downloaded list into the ipset 'china'
    for i in $(cat /etc/cn.zone ); do ipset -A china $i; done

    # Restore iptables
    /sbin/iptables-restore < /etc/iptables.firewall.rules


    Save the file. Make it executable:



    chmod +x /etc/block-china.sh


    This hasn't done anything yet, but it will in a minute when we run the script. First, we need to add a rule into iptables that refers to this new ipset list the script above defines:



    nano /etc/iptables.firewall.rules


    Add the following line:



    -A INPUT -p tcp -m set --match-set china src -j DROP


    Save the file. To be clear, my full iptables.firewall.rules now looks like this:



    *filter

    # Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
    -A INPUT -i lo -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT

    # Accept all established inbound connections
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    # Block anything from China
    # These rules are pulled from ipset's china list
    # The source file is at /etc/cn.zone (which in turn is generated by a shell script at /etc/block-china.sh )
    -A INPUT -p tcp -m set --match-set china src -j DROP

    # Allow all outbound traffic - you can modify this to only allow certain traffic
    -A OUTPUT -j ACCEPT

    # Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
    -A INPUT -p tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp --dport 443 -j ACCEPT

    # Allow SSH connections
    #
    # The -dport number should be the same port number you set in sshd_config
    #
    -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

    # Allow ping
    -A INPUT -p icmp -j ACCEPT

    # Log iptables denied calls
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

    # Drop all other inbound - default deny unless explicitly allowed policy
    -A INPUT -j DROP
    -A FORWARD -j DROP

    COMMIT


    Right now, nothing has changed with the server because no new rules have been applied; to do so, run the block-china.sh script:



    /etc/block-china.sh


    This should show some output as it pulls a fresh list of Chinese based IPs and then, after a few seconds or so, it will complete and drop you back to a command prompt.



    To test if it worked, run:



    iptables -L


    You should now see a new rule blocking China – the output ought to look like this:



    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere
    REJECT all -- anywhere loopback/8 reject-with icmp-port-unreachable
    ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
    DROP tcp -- anywhere anywhere match-set china src
    ACCEPT tcp -- anywhere anywhere tcp dpt:http
    ACCEPT tcp -- anywhere anywhere tcp dpt:https
    ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
    DROP all -- anywhere anywhere

    Chain FORWARD (policy ACCEPT)
    target prot opt source destination
    DROP all -- anywhere anywhere

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere


    Almost done! This works, and will continue to work on re-boots. But, IP addresses change and that list will grow stale over time. If you want to pull and apply an updated list of IPs you can just run the block-china.sh script again.



    We can also set the machine to do that automatically via a cron job:



    crontab -e


    Add a line such as this:



    * 5 * * * /etc/block-china.sh


    This will run /etc/block-china.sh at 5am every day. The user running the script will need to be root or have root privileges.



    source






    share|improve this answer













    China block using ipset



    You can't manually add a few thousand IP addresses to your iptables, and even doing it automatically is a bad idea because it can cause a lot of CPU load (or so I've read). Instead we can use ipset which is designed for this sort of thing. ipset handles big lists of ip addresses; you just create a list and then tell iptables to use that list in a rule.



    Note; I assume that the entirety of the following is done as root. Adjust accordingly if your system is based on sudo.



    apt-get install ipset


    Next, I wrote a small Bash script to do all the work, which you should be able to understand from the comments in it. Create a file:



    nano /etc/block-china.sh


    Here's what you want to paste into it:



    # Create the ipset list
    ipset -N china hash:net

    # remove any old list that might exist from previous runs of this script
    rm cn.zone

    # Pull the latest IP set for China
    wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

    # Add each IP address from the downloaded list into the ipset 'china'
    for i in $(cat /etc/cn.zone ); do ipset -A china $i; done

    # Restore iptables
    /sbin/iptables-restore < /etc/iptables.firewall.rules


    Save the file. Make it executable:



    chmod +x /etc/block-china.sh


    This hasn't done anything yet, but it will in a minute when we run the script. First, we need to add a rule into iptables that refers to this new ipset list the script above defines:



    nano /etc/iptables.firewall.rules


    Add the following line:



    -A INPUT -p tcp -m set --match-set china src -j DROP


    Save the file. To be clear, my full iptables.firewall.rules now looks like this:



    *filter

    # Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
    -A INPUT -i lo -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT

    # Accept all established inbound connections
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    # Block anything from China
    # These rules are pulled from ipset's china list
    # The source file is at /etc/cn.zone (which in turn is generated by a shell script at /etc/block-china.sh )
    -A INPUT -p tcp -m set --match-set china src -j DROP

    # Allow all outbound traffic - you can modify this to only allow certain traffic
    -A OUTPUT -j ACCEPT

    # Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
    -A INPUT -p tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp --dport 443 -j ACCEPT

    # Allow SSH connections
    #
    # The -dport number should be the same port number you set in sshd_config
    #
    -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

    # Allow ping
    -A INPUT -p icmp -j ACCEPT

    # Log iptables denied calls
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

    # Drop all other inbound - default deny unless explicitly allowed policy
    -A INPUT -j DROP
    -A FORWARD -j DROP

    COMMIT


    Right now, nothing has changed with the server because no new rules have been applied; to do so, run the block-china.sh script:



    /etc/block-china.sh


    This should show some output as it pulls a fresh list of Chinese based IPs and then, after a few seconds or so, it will complete and drop you back to a command prompt.



    To test if it worked, run:



    iptables -L


    You should now see a new rule blocking China – the output ought to look like this:



    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere
    REJECT all -- anywhere loopback/8 reject-with icmp-port-unreachable
    ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
    DROP tcp -- anywhere anywhere match-set china src
    ACCEPT tcp -- anywhere anywhere tcp dpt:http
    ACCEPT tcp -- anywhere anywhere tcp dpt:https
    ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
    DROP all -- anywhere anywhere

    Chain FORWARD (policy ACCEPT)
    target prot opt source destination
    DROP all -- anywhere anywhere

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere


    Almost done! This works, and will continue to work on re-boots. But, IP addresses change and that list will grow stale over time. If you want to pull and apply an updated list of IPs you can just run the block-china.sh script again.



    We can also set the machine to do that automatically via a cron job:



    crontab -e


    Add a line such as this:



    * 5 * * * /etc/block-china.sh


    This will run /etc/block-china.sh at 5am every day. The user running the script will need to be root or have root privileges.



    source







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jul 2 '17 at 3:48









    Surjit SidhuSurjit Sidhu

    7316




    7316













    • Why limit it to only tcp protocol? It seems to work without specifying protocol. Suggest to use the newer aggregated lists, as they are much shorter: wget http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone

      – Doug Smythies
      Dec 20 '18 at 0:40











    • There is nothing here that restores the ipset after re-boot.

      – Doug Smythies
      Dec 21 '18 at 19:59



















    • Why limit it to only tcp protocol? It seems to work without specifying protocol. Suggest to use the newer aggregated lists, as they are much shorter: wget http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone

      – Doug Smythies
      Dec 20 '18 at 0:40











    • There is nothing here that restores the ipset after re-boot.

      – Doug Smythies
      Dec 21 '18 at 19:59

















    Why limit it to only tcp protocol? It seems to work without specifying protocol. Suggest to use the newer aggregated lists, as they are much shorter: wget http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone

    – Doug Smythies
    Dec 20 '18 at 0:40





    Why limit it to only tcp protocol? It seems to work without specifying protocol. Suggest to use the newer aggregated lists, as they are much shorter: wget http://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone

    – Doug Smythies
    Dec 20 '18 at 0:40













    There is nothing here that restores the ipset after re-boot.

    – Doug Smythies
    Dec 21 '18 at 19:59





    There is nothing here that restores the ipset after re-boot.

    – Doug Smythies
    Dec 21 '18 at 19:59











    4














    You may want to install something like fail2ban so that it blocks ips that attempt to log into your server and fail.






    share|improve this answer
























    • i could also use csf firewall and block every country i want from the config files. The thing is that i really want to use iptables so i can learn more about it.

      – Caranfil Alegzandru
      Jan 5 '17 at 14:07











    • You would have to see what countries have what ip address blocks assigned to them to figure out who to block. Not sure if it would be super accurate or not though. You can use iptables -L to show current iptables rules, iptables-save to show what commands were run to create said rules, then design your own rules and test using test machines to learn about it. That is how I learned it.

      – Kyle H
      Jan 5 '17 at 14:39
















    4














    You may want to install something like fail2ban so that it blocks ips that attempt to log into your server and fail.






    share|improve this answer
























    • i could also use csf firewall and block every country i want from the config files. The thing is that i really want to use iptables so i can learn more about it.

      – Caranfil Alegzandru
      Jan 5 '17 at 14:07











    • You would have to see what countries have what ip address blocks assigned to them to figure out who to block. Not sure if it would be super accurate or not though. You can use iptables -L to show current iptables rules, iptables-save to show what commands were run to create said rules, then design your own rules and test using test machines to learn about it. That is how I learned it.

      – Kyle H
      Jan 5 '17 at 14:39














    4












    4








    4







    You may want to install something like fail2ban so that it blocks ips that attempt to log into your server and fail.






    share|improve this answer













    You may want to install something like fail2ban so that it blocks ips that attempt to log into your server and fail.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 5 '17 at 13:47









    Kyle HKyle H

    91737




    91737













    • i could also use csf firewall and block every country i want from the config files. The thing is that i really want to use iptables so i can learn more about it.

      – Caranfil Alegzandru
      Jan 5 '17 at 14:07











    • You would have to see what countries have what ip address blocks assigned to them to figure out who to block. Not sure if it would be super accurate or not though. You can use iptables -L to show current iptables rules, iptables-save to show what commands were run to create said rules, then design your own rules and test using test machines to learn about it. That is how I learned it.

      – Kyle H
      Jan 5 '17 at 14:39



















    • i could also use csf firewall and block every country i want from the config files. The thing is that i really want to use iptables so i can learn more about it.

      – Caranfil Alegzandru
      Jan 5 '17 at 14:07











    • You would have to see what countries have what ip address blocks assigned to them to figure out who to block. Not sure if it would be super accurate or not though. You can use iptables -L to show current iptables rules, iptables-save to show what commands were run to create said rules, then design your own rules and test using test machines to learn about it. That is how I learned it.

      – Kyle H
      Jan 5 '17 at 14:39

















    i could also use csf firewall and block every country i want from the config files. The thing is that i really want to use iptables so i can learn more about it.

    – Caranfil Alegzandru
    Jan 5 '17 at 14:07





    i could also use csf firewall and block every country i want from the config files. The thing is that i really want to use iptables so i can learn more about it.

    – Caranfil Alegzandru
    Jan 5 '17 at 14:07













    You would have to see what countries have what ip address blocks assigned to them to figure out who to block. Not sure if it would be super accurate or not though. You can use iptables -L to show current iptables rules, iptables-save to show what commands were run to create said rules, then design your own rules and test using test machines to learn about it. That is how I learned it.

    – Kyle H
    Jan 5 '17 at 14:39





    You would have to see what countries have what ip address blocks assigned to them to figure out who to block. Not sure if it would be super accurate or not though. You can use iptables -L to show current iptables rules, iptables-save to show what commands were run to create said rules, then design your own rules and test using test machines to learn about it. That is how I learned it.

    – Kyle H
    Jan 5 '17 at 14:39











    0














    You can use the geoip-module for iptables:
    https://linoxide.com/linux-how-to/block-ips-countries-geoip-addons/




    Once our system is upgraded and dependencies are installed, we'll now
    install the xtables-addons in our machine. To do so, we'll download
    the latest tarball from the official xtables-addons project site using
    wget. Once it's downloaded, we'll extract the tarball, then compile
    and install it in our machine.



    wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.13.tar.xz
    tar xf xtables-addons-2.13.tar.xz
    cd xtables-addons-2.13
    ./configure
    make
    make install [...]


    Next, we'll run a module called xt_geoip that comes with the
    xtables-addons extension which downloads the GeoIP database from
    MaxMind and converts it into a binary form recognized by xt_geoip.
    Once it's downloaded, we'll build it and move them to the required
    xt_geoip path ie /usr/share/xt_geoip.



    cd geoip
    ./xt_geoip_dl
    ./xt_geoip_build GeoIPCountryWhois.csv
    mkdir -p /usr/share/xt_geoip/
    cp -r {BE,LE} /usr/share/xt_geoip/


    Here's the basic syntax for using iptables with geoip module in order
    to block traffic originating from or destined to a country. Here, we
    need to use two-letter ISO3166 code in place of country , for eg., US
    for United States, IE for Ireland, IN for India, CN for China and so
    on.



    iptables -m geoip --src-cc country[,country...] --dst-cc country[,country...]






    share|improve this answer






























      0














      You can use the geoip-module for iptables:
      https://linoxide.com/linux-how-to/block-ips-countries-geoip-addons/




      Once our system is upgraded and dependencies are installed, we'll now
      install the xtables-addons in our machine. To do so, we'll download
      the latest tarball from the official xtables-addons project site using
      wget. Once it's downloaded, we'll extract the tarball, then compile
      and install it in our machine.



      wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.13.tar.xz
      tar xf xtables-addons-2.13.tar.xz
      cd xtables-addons-2.13
      ./configure
      make
      make install [...]


      Next, we'll run a module called xt_geoip that comes with the
      xtables-addons extension which downloads the GeoIP database from
      MaxMind and converts it into a binary form recognized by xt_geoip.
      Once it's downloaded, we'll build it and move them to the required
      xt_geoip path ie /usr/share/xt_geoip.



      cd geoip
      ./xt_geoip_dl
      ./xt_geoip_build GeoIPCountryWhois.csv
      mkdir -p /usr/share/xt_geoip/
      cp -r {BE,LE} /usr/share/xt_geoip/


      Here's the basic syntax for using iptables with geoip module in order
      to block traffic originating from or destined to a country. Here, we
      need to use two-letter ISO3166 code in place of country , for eg., US
      for United States, IE for Ireland, IN for India, CN for China and so
      on.



      iptables -m geoip --src-cc country[,country...] --dst-cc country[,country...]






      share|improve this answer




























        0












        0








        0







        You can use the geoip-module for iptables:
        https://linoxide.com/linux-how-to/block-ips-countries-geoip-addons/




        Once our system is upgraded and dependencies are installed, we'll now
        install the xtables-addons in our machine. To do so, we'll download
        the latest tarball from the official xtables-addons project site using
        wget. Once it's downloaded, we'll extract the tarball, then compile
        and install it in our machine.



        wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.13.tar.xz
        tar xf xtables-addons-2.13.tar.xz
        cd xtables-addons-2.13
        ./configure
        make
        make install [...]


        Next, we'll run a module called xt_geoip that comes with the
        xtables-addons extension which downloads the GeoIP database from
        MaxMind and converts it into a binary form recognized by xt_geoip.
        Once it's downloaded, we'll build it and move them to the required
        xt_geoip path ie /usr/share/xt_geoip.



        cd geoip
        ./xt_geoip_dl
        ./xt_geoip_build GeoIPCountryWhois.csv
        mkdir -p /usr/share/xt_geoip/
        cp -r {BE,LE} /usr/share/xt_geoip/


        Here's the basic syntax for using iptables with geoip module in order
        to block traffic originating from or destined to a country. Here, we
        need to use two-letter ISO3166 code in place of country , for eg., US
        for United States, IE for Ireland, IN for India, CN for China and so
        on.



        iptables -m geoip --src-cc country[,country...] --dst-cc country[,country...]






        share|improve this answer















        You can use the geoip-module for iptables:
        https://linoxide.com/linux-how-to/block-ips-countries-geoip-addons/




        Once our system is upgraded and dependencies are installed, we'll now
        install the xtables-addons in our machine. To do so, we'll download
        the latest tarball from the official xtables-addons project site using
        wget. Once it's downloaded, we'll extract the tarball, then compile
        and install it in our machine.



        wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.13.tar.xz
        tar xf xtables-addons-2.13.tar.xz
        cd xtables-addons-2.13
        ./configure
        make
        make install [...]


        Next, we'll run a module called xt_geoip that comes with the
        xtables-addons extension which downloads the GeoIP database from
        MaxMind and converts it into a binary form recognized by xt_geoip.
        Once it's downloaded, we'll build it and move them to the required
        xt_geoip path ie /usr/share/xt_geoip.



        cd geoip
        ./xt_geoip_dl
        ./xt_geoip_build GeoIPCountryWhois.csv
        mkdir -p /usr/share/xt_geoip/
        cp -r {BE,LE} /usr/share/xt_geoip/


        Here's the basic syntax for using iptables with geoip module in order
        to block traffic originating from or destined to a country. Here, we
        need to use two-letter ISO3166 code in place of country , for eg., US
        for United States, IE for Ireland, IN for India, CN for China and so
        on.



        iptables -m geoip --src-cc country[,country...] --dst-cc country[,country...]







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 4 at 2:18









        Olorin

        2,433822




        2,433822










        answered Feb 3 at 16:54









        Markus LengerMarkus Lenger

        101




        101






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Ask Ubuntu!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f868334%2fblock-china-with-iptables%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

            Mangá

            Eduardo VII do Reino Unido