It's very common for all servers (virtual/cloud and physical) connected to the internet to be scanned and logins attempted. There are a few steps you can take to secure your SSH installation. It's important to note that it's impossible to be 100% guaranteed secure, but there are lots of steps you can take to make it almost there...
The following are in order of difficulty for you when then trying to access them. All are described in terms of an Ubuntu 16.04 instance, but should work on most other distributions too.
This piece of software is great - it simply monitors the SSH authentication log files for failed attempts and bans connecting IP addresses that have 3 failed attempts for 10 minutes (by default). As these requests often are just sent in huge batches, it stops them after three attempts for a while, making them more likely to give up rather than wait infinite years for their attempts to succeed. There's lots of information online about
fail2ban but a simple installation is just:
sudo apt update sudo apt install fail2ban
And that's it! If you want to tweak settings you can have a look at the files in
The simplest thing you can do is to simply configure
sshd to not listen on port 22. You do this by editing
/etc/ssh/sshd_config and changing the line:
to be a new choice of port (some people use 2222, but because this is so common it's now often attempted along with the default one anyway):
After doing this you need to restart your SSH daemon with
service ssh restart.
Now when you SSH from the command line you can either specify the port with:
ssh -p 2234 email@example.com
Or you can edit a file on your local machine called
~/.ssh/config and put a section like:
Host your.ip.address.here Port 2234
When hackers try to brute force entry to your SSH daemon, they often try the OS's default users (
debian, etc) or
root. So if you have a non-
root user with sudo permissions that you use to connect with, you can disable the
root login via SSH completely. To do this edit the
/etc/ssh/sshd_config file on the instance again and change the line:
And again restart your ssh with
service ssh restart. NOTE: If you only have a root user on the server, you'll lose access to your instance by doing this - forcing a rebuild and 100% data loss on the instance.
You can use either a custom Civo firewall from your dashboard or your distributions built-in firewalling to only allow TCP connections to your SSH daemon to a specific IP address (your office's fixed IP address). This is really secure, but it doesn't help if you're on vacation and an instance has a problem. Read more about firewalling instances.
This is going to be the most hasslesome method, but is really clever. What you do is completely firewall SSH off from being accessed and setup a daemon that listens on a number of ports and when it receives a connection of them in the right order, it then opens up the firewall to SSH for the IP address that made the sequence of port connections. Let's install it and work through an example:
The first step is to setup some default rules using
# Accept all local traffic (from the same machine) sudo iptables -A INPUT -i lo -j ACCEPT # Allow any already established connections sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # If you have any other rules add them now, e.g. HTTPS: # sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT # Finally drop anything that we haven't specified sudo iptables -A INPUT -j DROP
That's locked your box down, but because of the
ESTABLISHED,RELATED item your current SSH connection won't drop (DON'T exit the connection yet now though).
Now we should make these rules exist between reboots with:
sudo apt update sudo apt install iptables-persistent sudo service iptables-persistent start
Now we're ready to install Knockd, which is a really nice piece of software to listen on configured ports and run commands when it receives connections in the right order:
sudo apt install knockd
Now we can configure the daemon by editing
[options] UseSyslog [openSSH] sequence = 6001,6003,6007 seq_timeout = 5 command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 6007,6003,6001 seq_timeout = 5 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn
This is configured now so that if you knock on ports 6001, then 6003 and then 6007 in that order it will open
iptables to allow your current IP's connection. If you knock in reverse order it will close it again. We'd recommend that you not use the ports above though, pick three (or whatever) ports of your own choosing, above 1024 and less than or equal to65535. Now you've got to enable the daemon and start it. Edit the file
/etc/default/knockd and change the line:
And start the service with:
sudo service knockd start
Now you're ready to try it (hopefully you're doing this for the first time on a test instance):
Open a new terminal (tab) and install the
knock client (or you can use
netcat or something similar) using
apt install knock or
brew install knock (for Linux and Mac OS X respectively, a Windows client is also available).
knock your.ip.address.here 6001 6003 6007 ssh your.ip.address.here
And then you should be connected to your server. When you've finished with it, you can exit your SSH connection and knock in revers order to close it again:
knock your.ip.address.here 6007 6003 6001