Recently I examined my Raspberry Pi's logfiles because of all the cyber warfare going on and as I went trough the auth.log (/var/log/auth.log) looking for failed login attempts I saw a list of about 100 attempts from IPs trying to login as root or bin user.
$ cat /var/log/auth.log | grep 'sshd.*Failed'
This got my attention and my awareness, of having an unprotected SSH server running open to the worldwide net. I decided to pay a little bit more attention to the security of my Raspberry Pi and here I'll show you a few easy steps to make your Pi more secure:
Changing the pi standard user
First you have to kill all processes running under your current user. Therefore it would be best for you to log in via SSH as root and then you have to find out the id of your pi user:$ sudo su
$ killall -u pi
$ id pi
uid=1000(pi) gid=1000(pi) groups=1000(pi), ...
next you have to change the login user, group and the home directory to the new user called newuser and copy the contents of the pi user's home to the home of the newuser, then delete the old directory
$ usermod -l newuser pi
$ groupmod -n newuser pi
$ usermod -d /home/newuser -m newuser
$ usermod -c REALNAME newuser
$ cp -r /home/pi /home/newuser
$ rm -r /home/pi
Now you should be able to log in as 'newuser', but to still be able to use sudo, you need to change the user in /etc/sudoers from pi to newuser. This is only possible with the tool "visudo":
$ visudo
newuser ALL=(ALL) NOPASSWD: ALL
Set a hard password
Most important and most easiest thing to do, is to choose a strong password. You can change your current password by typing$ passwd
and then set your new, strong password. Strong passwords usually contain
- upper and lower case characters
- numbers
- special characters
- more then 8 characters in length
- and so on and so forth
$ </dev/urandom tr -dc '12345!@#$%qwertQWERTasdfgASDFGzxcvbZXCVB' | head -c12; echo ""
Changing the SSH port
One important action to avoid crawler which randomly test for open ports, is to change the standard SSH port from 22 to something else. This can easily be done either- directly via your routers port forwarding rule or
- by changing the SSH daemon's listening port
Directly via the router
Depending on your routers configuration you have to change the port forwarding from port 22 on your router to a random port (say 1337), which is not used by another service. By using this alternative, you don't need to change your sshd config on the Pi, you just have to change add the port-number when ssh-ing to the pi. Your router redirects port 1337 to port 22 on your Pi, and everything works as usual$ ssh pi@my.duckdns.org -p 1337
Here a short overview over various services and their standard ports.
Changing the daemon
If you want to change the listening-port of the daemon directly, you have to alter the sshd config.$ sudo vi /etc/ssh/sshd_config
replace Port 22 with Port 1337
Keep in mind that you also need to change the port-forwarding on your router to the port you selected.
If you want to open a connection you have to specify the port:
$ ssh pi@my.duckdns.org -p 1337
For your convenience you can create a $HOME/.ssh/config file and add the following:
Host rpi
HostName my.duckdns.org
User newuser
Port 1337
This enables you to connect easily from this computer:
$ ssh rpi
Adapt the SSH config
There are a few more things you can do with the sshd_config to improve the security of your Raspberry. As we are curious, we want to increase the logging level of our SSH daemon by changing following parameter from$ sudo vim /etc/ssh/sshd_config
[...]
LogLevel INFO
to
LogLevel VERBOSE
After this change, ALL details of the login attempts will be saved to the auth.log file.
Allow and deny specific users
One great feature is to only allow specific users to login via SSH. Therefore you just have to add or change following lines in the config:$ sudo vim /etc/ssh/sshd_config
[...]
AllowUsers Peter Jango
This line tells the server to allow only Peter and Jango to sign in via SSH. The next line does exactly the opposite:
$ sudo vim /etc/ssh/sshd_config
[...]
DenyUsers Peter Jango
Peter and Jango are not allowed to sign in via SSH, everyone else is allowed.
If you want to personalize your SSH login, then you can take a look at this tutorial, showing you how to customize the SSH login.
Restrict root access
Another important option, is to disable root access via SSH. It is still possible to login as normal user and switch to root or to work with sudo only. Just change the option "PermitRootLogin" to no$ sudo vim /etc/ssh/sshd_config
[...]
PermitRootLogin no
$ sudo /etc/init.d/ssh reload
Limit number of connections
If an IP address tries to open more than X connections in XX seconds, we can tell the server to drop this connections. This can be handled by the MaxStartups option and can significantly alleviate DDOS attacks.MaxStartups 10:30:60 (start:rate:full)
10 is the number of unauthenticated connections before we start dropping connections by a chance of rate/100 (30 %). Once there are 60 unauthenticated connections, we drop every connection. Because the Pi is on the lower end of the performance scale and isn't used as server for many users, I suggest to insert smaller values for start and full.
$ sudo vim /etc/ssh/sshd_config
[...]
MaxStartups 2:50:10
It also makes sense to reduce the LoginGraceTime, this is the time the server keeps the connection alive while waiting for authorization.
$ sudo vim /etc/ssh/sshd_config
[...]
LoginGraceTime 20
Disable password authentification - SSH keys only
A weak password is the biggest problem on SSH servers, so best thing would be to use SSH keys instead of passwords, because this keys are complex enough to withstand an average attack and together with the other configuration described above should provide a certain amount of protection. But the use of SSH-keys also comes with disadvantages: You can not log in from a device without pre-approving. Keep that in mind! To disable password authentication set$ sudo vim /etc/ssh/sshd_config
[...]
PasswordAuthentication no
You can find a short tutorial about ssh-key authentication here.
Fail2ban
Fail2ban is a python based intrusion prevention tool, which scans logfiles like the auth.log and bans IPs that cause too many login errors by updating firewall rules (iptables) or TCP Wrappers (/etc/hosts.deny). It is very flexible, easy to use and has a lot of filters for various services like SSH, lighttpd, apache, vsftpd and so on.You can download fail2ban on the fail2ban download page or simply install it on your raspbian by typing:
$ sudo apt-get install fail2ban
After installation is finished, we have to configure fail2ban, therefore go to the directory containing the config files (usually /etc/fail2ban/) and make a copy of the jail.conf with the name jail.local. Only change the parameters in the jail.local file, because changing the .conf file directly can cause errors on program updates and the parameters in the jail.conf get overwritten by the ones in the .local file. Here I will just talk about the basic options for SSH.
Look for the options regarding the SSH service and see if the filters are enabled and the logpath is set to the right place, usually /var/log/auth.log. I would recommend to set the maxretry parameter to 3 and the increase the time the IP is banned to e.g. 1800 (30 min). If you want to ban the IP forever you have to set a negative value for the bantime e.g. -1
$ sudo vi /etc/fail2ban/jail.local
[...]
bantime = 1800
[...]
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
You can find the filter rules in /etc/fail2ban/filter.d/ and you can create new ones for every service you like.
Find more information on www.fail2ban.org/wiki
I hope you found this useful and it will help you to stay secure!