Having your own server in 2021 is a must for anybody, whatever you want it for a personal portfolio or WordPress website or any applications you made because it gives you full access to your server so you can change and edit whatever you want.
In this article we gonna talk about how correctly configure your server and some security concerns that make your server more secure, then some best practice on dealing with Linux servers in general, hope you enjoy it.
For today I will use a virtual server from Azure Cloud, so we can demonstrate how to do things on a real-world server rather than a VirtualBox machine, which not gives you the real scenario in production.
First login to your server via SSH, if you use Linux or Mac, open your Terminal, and if you use Windows download putty, Buts if you have Windows 10 Pro, the SSH client comes preinstalled so you don't need to download any third-party software, just open Command Prompt (known as CMD).
When you create your virtual server in your cloud provider you will get an IP for your server to connect to it via SSH, you can use a floating IP this a best practice if you want to deploy a Linux server for a production App, we will talk about the benefits of using a floating IP later rather than the default one, but we stick with that one given by the cloud provider.
I create a Server just for testing, maybe it will be deleted after few days after this article published, we will log in with SSH by typing the username given by the cloud provider and the password you created in the dashboard, in my case was:
ssh Nassim@20.199.88.158
Yeah yeah, I know it's not good to make the first letter capital. I do it for a reason so I can create a new user, and give add it to the sudo group so we can run some commands that required root privileges. Considering that some cloud provider gives you the root login at this form:
ssh root@your_ip
Of course, this is not a good practice and not securing at all the work and login with the root, so we can add a new user and add it to sudo group.
If your cloud provider, don't make login as root by default, you can skip this section and go to the next section by clicking HERE.
Let's create a new user, type: (change nassim
with whatever the name you want )
sudo adduser nassim
When you hit Enter you will be prompted to write a password create a one and confirmed it (if you don't familiar with Linux the password is hiding when you type the password so just continue.), when you confirm the password you will ask for further information, if you want to write it, do it, for me I don't so, I just Hit Enter multiple times.
Now, after creating a user let's add it to the sudo group, so we can run a root command, type:
sudo adduser nassim sudo
Or:
sudo usermod -aG sudo nassim
The user will be added as the picture below:
Now, we will log out from the server and log in as his user we created, as I said before it' not a good practice to log in as root, type logout. then connect as the user:
exit
Then go back and login as the user:
ssh nassim@20.199.88.158
Now it's the time to talk about why I make the first latter capital the first time, so can I add a new user and at the same time demonstrate to the beginners that nassim
and Nassim
are not the same names for ssh, that's how Linux works if your username is nassim
and tying the connect to SSH with Nassim
, it wouldn't work.
Then when you connect with your username you will asked for the password you created, type it and click Enter.
Now, we should do an important thing, which updates the packages and install some security updates in the Server, this is the first thing you should do when you log in to your server just type:
sudo apt update && sudo apt upgrade -y
This will take a couple seconds or minutes just wait for it until it finished, and after that, you should restart your server by typing:
sudo reboot
This will cut the connection with your server, don't worry just wait a couple of seconds until the server turns on again and login with ssh as usual.
After we install important updates, we will set up SSH key-based authentication, so we can log in to our server without a password, maybe you get confused now, just hold on everything will be clear shortly.
When we login with a password that makes anyone trying to get access to our server by using a Brute-force attack, So they can try a lot of passwords until they get the right one, but if we set up an ssh based key authentication, just the one who has the public key can be login even without a password (If you don't know much about Cryptography, I will make an article about it and how it works).
Make sure you are in the home directory of your user, you can check that by typing :
pwd
Then create a new directory called .ssh
:
mkdir .ssh
If you are in Windows, open the new Command Prompt (cmd), and type:
cd %USERPROFILE%\.ssh
If you are in Linux or Mac, type:
cd ~/.ssh/
Then type this command:
ssh-keygen -b 4096
This will generate a public/private RSA key pair, for the -b option specifies the key size, a larger key size improves security.
Increasing key size slows down the initial connection but has no effect on the speed of encryption or decryption of the data stream after a successful connection has been made.
You can learn more about different options by visiting this Website.
After you hit Enter, you will be prompted by the location where the public/private keys will save, by default it will save in your user folder under the name .ssh
, if you want to choose a specific name it, do it, otherwise just click Enter the keep the same name, which by default: id_rsa
,in my case I will call it test_server
, as I have already a key named id_rsa
, that will override that key, if you already generate a key with the default name, for best practice, choose a name that describes your server purpose, in my case, it is just a test server. Enter the name and hit Enter.
After you will be asked the write passphrase for extra security, In my case I will let it blank then hir Enter.
Now if you go to your .ssh folder you will see 2 files, one called test_server
and other test_server.pub
.
Now we have the public key which ends with .pub
and the private key is just test_server without extension, we need to move our public key to the server, so we can perform a secure ssh connection.
We will go back to our CMD or Terminal on our Local machine, and use a tool called: SCP which stands for Secure Copy, so we can send our public key to the server.
On Windows type:
scp %USERPROFILE%\.ssh\test_server.pub nassim@20.199.88.158:~/.ssh/authorized_keys
On Linux or Mac:
scp ~/.ssh/test_server.pub nassim@20.199.88.158:~/.ssh/authorized_keys
After hit Enter, you will asked for the password of your server, type it, then hit Enter, and it will send to the server, as shown in the picture below:
If we don't understand the command above, we are sending the public key called test_server.pub
from our local machine, which located in the %USERPROFILE%\.ssh\
and sends it the nassim@20.199.88.158
which is our server, and after :
we put the location we want the public key to go that why we specify that we want our public key to be saved on the server in the .ssh directory and put it inside a file called authorized_keys
.
Now, if you go to the server and type:
ls .ssh
You will see that the file has been created and the public key now inside the authorized_keys file.
The next step is the set some permission to the .ssh
directory, so the owner of the directory has read, write, execute permissions on the directory, and the owner of the files on that directory will have the read and write permissions on the files, so to do that, I'm gonna do :
sudo chmod 700 ~/.ssh/
If you asked to write a sudo password write it, ad hit Enter.
I'm also going to set the permission of all the files in that ssh directory:
sudo chmod 600 ~/.ssh/*
If you are confused about where those numbers come in the place, that's another topic about users and permission, I will write an article about it if I have time.
We will make some modification in the sshd_config so we can finish the whole process, got the server, and type:
sudo nano /etc/ssh/sshd_config
We will disable password so hackers can not brute force the password, so only you who have the private key can access your server, look for PasswordAuthentication
and change the value to no, it will look similar to the picture below:
Now we disabled a password authentication so we can only use the ssh key to connect to our server, next step is the disable the root login, because we already have a user with sudo privileges so we don't need to allow login as a root. In the same file look for PermitRootLogin
and change it to no, as in the image below:
After making these modifications, press CTRL + X
then Y
then Enter and you are good to go.
The last step is the restart the ssh server, just type :
sudo systemctl restart sshd
If you try to log in to your server, this message will appear:
Don't worry, just specify the private key you have and then you can log in without a password.
On Windows type:
ssh -i %USERPROFILE%\.ssh\test_server nassim@20.199.88.158
On Linux or Mac:
ssh -i ~/.ssh/test_server nassim@20.199.88.158
In that command, we specify the private key so that the SSH knows that this is the private key of that public key that we sent in previous steps to the server.
As you can see in the image below, we don't need any password to log in.
After done with all related stuff to the SSH, now we will play a little bit with the Firewall for extra security. Most cloud providers already have a firewall in place in the dashboard, for example for Azure you need to open specific ports from the dashboard if you want to use them.
For an extra layer of security we will add our own Firewall, In this example we will stick with UFW Firewall, this is the easiest firewall you can deal with compared to iptables or any other one, even that clear from its name, UFW stands for Uncomplicated Firewall.
In your Terminal, type:
sudo apt install ufw
After the UFW installed, most of the servers you got from the cloud providers already come preinstalled, then write this snippet to allow all outgoing traffic from our server.
sudo ufw default allow outgoing
Then deny all incoming traffic to our server, by typing:
sudo ufw default deny incoming
Don't worry we will just allow the ports we are using, because it's not recommended to open all of your ports if you want to use a few of them.
Now first we need to do is allow ssh port, because if your let all things like that you will not be able to connect via ssh because we block all incoming traffic, so let's allow ssh in the firewall:
sudo ufw allow ssh
Or you can just type:
sudo ufw allow OpenSSH
Since that a test server we need just an ssh port to be open, But if you have a specific port you want to open, in this case, we want to open port 80:
sudo ufw allow 80
If you want to know all the services and corresponding port number, you can type :
cat /etc/services
This will list all the services with their port number.
Now after setting up everything we will activate the firewall.
BE CAREFULL!, make sure that you are adding the ssh to the firewall, or you will completely lose the connection to your server.
After you add your services to be opened, activate the firewall:
sudo ufw enable
After that, you will be prompted with a warning just type y
then Enter, and now the firewall is enabled.
If you want to check all the services and port you allowed you can type:
sudo ufw status
Then all the list of them will be listed as shown below:
Another thing to do is activating the logging, so you can check the log of the UFW under /var/log/ufw.log
just type:
sudo ufw logging on
Log levels can be set by running:
sudo ufw logging low
sudo ufw logging medium
sudo ufw logging high
The default setting is low.
You can learn more about UFW by typing:
man ufw
NOTE:
with all these measures of security we implemented and best practices we are just reducing the risks of been hacked because there is nothing in this field that makes you protected 100%.