So now that I have a working webserver running on my Raspberry Pi, it’s time to secure it. This has to be done before I expose my new server to the internet. These are just a few simple things that can really make a big impact. I once again want to clarify that I am not an IT professional and that these are the only the steps that I am aware of. Proceed at your own risk.
Making a New User
So I’ve got the default ubuntu user on this server, but it has a similar security issue to that of root. It’s an admin account that is pretty common. Really this is a pretty minimal risk but I like to get rid of it anyway. So I ssh into the server using the ubuntu account. Using the adduser command I create an account that I would like to keep.
sudo adduser yoda
I after entering a new password for this account I was asked for a full name, room number, work phone, home phone, and other information. I left all this blank, I don’t need it. Now to give my padawan account the power it needs to manage this server.
sudo usermod -aG sudo yoda
Now that my new account has sudo privileges, I can sign out the server. The next part happens on my local PC.
Making an SSH Key
To make the SSH connection more secure, I created an SSH key pair. I did this by simply running the ssh-keygen command. I added the -t flag to specify that I wanted an ed25519 type of key. It’s a strong encryption with a shorter keystring and is typically faster to use. I know nothing about encryption, but I have read part of an article from someone that does and they say it’s a strong encryption type, so that’s what I used.
ssh-keygen -t ed25519
I was asked to enter a file in which to save the key and I hit enter to accept the default. Then I was prompted to enter a passphrase. I put in a strong and complicated password for the extra security that this gives. I’ll have to enter this passphrase when I connect to the server, which will be a small nuisance, but it makes the SSH key useless to anyone who doesn’t also have the password. The keygen tool then showed me some randomart image. I suppose this is to show me how fancy encryption keys can be? But my keys are generated and to put them to use I copy the public key to webserver with the ssh-copy-id command.
ssh-copy-id -i ~/.ssh/id_ed25519.pub yoda@ipaddress
The password that it asked for at this point was that of my new account on the server. After the key copied over to the webserver, I took it for a test run.
ssh yoda@ipaddress
This time it asked for the passphrase of the SSH key. I entered the passphrase and the connection worked perfectly!
Disable SSH Passwords
Now that the SSH keys have been shown to be working I wanted to disable ssh passwords. To do this I needed to edit /etc/ssh/sshd_config
sudo vim /etc/ssh/sshd_config
PasswordAuthentication yes
sudo systemctl restart sshd.service
I tested the new settings by trying to ssh into the ubuntu user on the server using a new terminal window.
ssh ubuntu@ipaddress
Hurray, permission denied! No password option given at all.
Enabling the Firewall
At this point my SSH has been secured to my satisfaction. Now I wanted to secure the rest of the server and the best way to accomplish this is to enable the firewall. I needed to set the firewall rules before enabling it or I could lock myself out. This particular Rasperry Pi is damaged and the usb ports don’t work. If I got locked out now I would need to start all over again. So run this command.
sudo ufw allow from MYIPADDRESS to any port 22
With this I am allowing an ssh connection to the server, but only from my ip address. This is, in a sense, tripling the security to my server ssh. To SSH to the server(once the firewall is enabled) the key, the passphrase and my IP, are all required to gain access. I was feeling like living dangerously so I enabled the firewall.
sudo ufw enable
The warning that popped up after this command was a little nerve-racking, “Command may disrupt existing ssh connections. Proceed with operation (y|n)?”. I swallowed hard and typed y. The firewall is active message that proceded let me know that my connection was still good. I double checked by opening another terminal and started another SSH session. It still works! But what good is a web server where users can’t connect to it? Time to open the web ports.
sudo ufw allow "Apache Full"
The webserver now has 3 ports open on the firewall. Port 80 and 443 for the webservice and port 22 to my ip address for SSH connections. This is as secure as I can think of. The web server is also behind my home firewall which also blocks everything but port 80 and 443. With this I considered myself done securing the server.
Removing the Ubuntu User
So I was happy enough with the security of server but I don’t have a need for the ubuntu user on it. I never plan on using it again and by removing that user I will effectively be reducing the attack surface of the server, sort of. This user can’t be accessed remotely anyway.
sudo userdel -r ubuntu
I added the -r flag to remove the home directory of the ubuntu user. This left me feeling satisfied that there was only one user on the server.
Complete
So my server has been secured to the best of my ability. The only thing left is to build a site and get an SSL certificate. So that’s what I’m going to do next.