SSH Brute Force is one of the old way which nicely works, proof is latest attacks on Dyn DNS. The target is to bring DDoS. Frankly, the solutions like anti-DDoS for IaaS, anti-DDoS for PaaS are very costly and without hardware it is difficult to terminate attack. Many a times, the new sysadmin can not understand the odd errors on SSH like pam_unix(sushi:auth): authentication failure, which are indicative of flooding, sometimes Nginx starts to throw PHP-FPM errors when attack is combined with XML-RPC attack. Here is How To Limit SSH Access By Country To Save From SSH Brute Force & Filter With Fail2Ban.
Things To Do Before Reading This Guide on How To Limit SSH Access By Country
The way we are going to describe is one extra layer of security. We suggest the unused readers to read iptables basics chapter 1, iptables basics chapter 2, iptables basics chapter 3. The guides are combined with Fail2Ban. If you are WordPress user, then add Best WordPress Brute Force Plugin too. Basic thing is that, we have to control from all possible layers of OSI model. The danger of following this guide by a newbie is completely locked in situation, specially if the server has no way to access via internal network. Most Cloud Servers has virtual console, which allows to reset the settings and SSH. We tested our method (although we have no discovered it) numerous times, still be careful before hitting exit
from the server you used the method for the first time.
We suggest to have different servers in different countries, like ArubaCloud’s 1GB 1 Euro server, VPSDime’s 6GB $7 server to use their hosting countries as way to test SSH. Apply the rules and test many ways to check and re-check before hitting exit
from the server you are going to use it.
---
We will block at step 1 on this diagram :
Things To Do Before Reading This Guide on How To Limit SSH Access By Country
We are describing for Ubuntu 16.04, method will be same for CentOS. First you need to install these two packages :
1 | apt-get install geoip-bin geoip-database |
If you followed manual method before like that we described for using Nginx Geo-IP module for access log, then running the above commands may tell you that you are using manual method for Geo IP. Such output will not make any difference in the next steps.
cd
to /usr/local/bin/
and create a file named sshfilter.sh
:
1 2 | cd /usr/local/bin/ nano sshfilter.sh |
Copy-paste this script :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/bin/bash # country codes to ACCEPT ALLOW_COUNTRIES="US UK FR" if [ $# -ne 1 ]; then echo "Usage: `basename $0` <ip>" 1>&2 exit 0 # return true in case of config issue fi COUNTRY=`/usr/bin/geoiplookup $1 | awk -F ": " '{ print $2 }' | awk -F "," '{ print $1 }' | head -n 1` [[ $COUNTRY = "IP Address not found" || $ALLOW_COUNTRIES =~ $COUNTRY ]] && RESPONSE="ALLOW" || RESPONSE="DENY" if [ $RESPONSE = "ALLOW" ] then exit 0 else logger "$RESPONSE sshd connection from $1 ($COUNTRY)" exit 1 fi |
I have kept it on GitHub as gist so that you can wget the raw file from server. Where from the script came we do not know! This is used for this purpose. Notice the ALLOW_COUNTRIES="US UK FR"
line. By default this script will allow US, UK and France. You should edit it. We recommend to keep minimum 2 countries. Other countries will be not allowed. Unrecognised countries will be allowed.
chmod the file properly to make it executable :
1 | chmod +x /usr/local/bin/ipfilter.sh |
Now open /etc/hosts.deny
file :
1 | nano /etc/hosts.deny |
Add these lines at the end of that file and save it :
1 2 | sshd: ALL vsftpd: ALL |
If you use vsftpd then you’ll add the second line. For only SSH, first line is enough. So we have blocked all to SSH. Now open /etc/hosts.allow
and these lines at the end of that file and save it :
1 2 | sshd: ALL: aclexec /usr/local/bin/sshfilter.sh %a vsftpd: ALL: aclexec /usr/local/bin/sshfilter.sh %a |
Now restart the SSH service :
1 | service ssh restart |
Now test SSH from various servers from various countries. It is funny to edit the file /usr/local/bin/sshfilter.sh
to disallow US and try from US server. This can happen if you wrongly block yourself! There is nothing more to write as guide.
Now first check various log files :
1 2 3 4 5 | cat /var/log/messages cat /var/log/fail2ban.log cat /var/log/auth.log tailf /var/log/syslog # exit with [control] + [z] |
Empty all of them :
1 2 3 4 | echo " " > /var/log/messages echo " " > /var/log/fail2ban.log echo " " > /var/log/auth.log echo " " > /var/log/syslog |
Normally running websites always have some sort of attacks running. Run cat after few minutes, you’ll see /var/log/auth.log
will show entries like :
1 2 | aclexec returned 1 Nov 20 18:54:00 thecustomizewindows sshd[15644]: refused connect from 125.88.158.219 (125.88.158.219) |
What exactly happening, Fail2Ban is getting a guard with this setup – RAM usage is decreasing when such attack is regular matter. Major disturbing countries are Korea, China, India, Russia etc. When they will try via those allowed countries, Fail2Ban will catch them. So the total security becoming :
1 | iptables - SSH Deny - Fail2Ban |
This method itself not very powerful, but in combination it does great work. Basic disadvantages of this method is locking up own self, allowing unidentified countries, allowing 1-2 countries where from you’ll SSH. Port knocking is good way but many of us dislike it.
Tagged With how to restrict ssh access by country