As a staking service, we acknowledge that securing our servers is vital to operating nodes on a blockchain. In this blog post, we explain how a few relatively simple steps can make a huge difference for your server’s security.
After performing the actions in this tutorial, an attacker will need to know or have:
- the IP address
your.ip.add.ress
of your server - the only username (
nonrootuser
in our example) that is allowed SSH access - the private key of your SSH identity key pair
- your passphrase with which the private SSH key was encrypted
- the only custom port number through which your server can be accessed (
your-ssh-port
in our example) - your time-based 2FA Google Authenticator code
Because we will also install Fail2Ban, the attacker’s IP address will be blocked after 3 consecutive failed login attempts. Sounds pretty secure, right?
For this guide, we will assume that you want access to your Ubuntu 18.04 server from a Windows computer, using MobaXterm as an SSH client.
Username root
, SSH port 22
Rent any server, and you will find that the server is accessible with username root
and an initial password on the default port for SSH, which is port 22. Apart from the password, trying username root
at port 22 is a pretty decent starting point for anyone who wants to get illegitimate access to your server. The only thing left for their algorithms to guess will be the password. For running blockchain nodes, this can hardly be called secure.
Setting up a non-root user
To continue with the following steps, start a local terminal and log on to your server with your login credentials. The first low-hanging fruit is to create a non-root user with a less obvious name than root
. Suppose you want to create superuser nonrootuser
, with bash
as the default shell and /home/nonrootuser
as $HOME
directory. Once logged in, you could do it like this:
useradd -s /bin/bash -d /home/nonrootuser -m -G sudo nonrootuser
User nonrootuser
will need a password and we can set it with:
passwd nonrootuser
You could use a password that you can remember, but best practice is to create a strong password that no one would be able to guess, and to store it somewhere safe, i.e. offline. Even though the next step will show that you won’t need your password to login to your server, your password will be necessary to be able to run commands as root
with sudo
.
Generate SSH keys
Better than using any password for SSH access to your server is to use an identity key pair. The trick is to generate both a private key and a public key on your Windows computer, and to install the public key — which almost serves as a lock to your private key — as an authorized key on your remote server. The associated private key will then grant you access your server. This may sound complicated, but it’s done with a few simple commands.
In MobaXterm, go to Settings and select your Persistent Home Directory. Then click on “Start local terminal” (or choose Session > Shell). You will get a prompt starting in /home/mobaxterm
. This is where we create an Ed25519 SSH key pair. Ed25519 is the most recommended SSH key algorithm available today: it’s safe and it’s fast!
mkdir -p $HOME/.ssh
ssh-keygen -t ed25519 -C "My SSH key"
You will be prompted to “Enter a file in which to save the key”. Press Enter to accept the default location (/home/mobaxterm/.ssh/id_ed25519
) — we will assume this for now — but you can also choose a different location. You will be prompted to add an optional passphrase, which is recommended for extra security, because then your private SSH key will be useless to anyone else.
Your public SSH key will be here on your local system:
/home/mobaxterm/.ssh/id_ed25519.pub
Your private SSH key will be here on your local system:
/home/mobaxterm/.ssh/id_ed25519
Now add your newly generated Ed25519 key to SSH agent:
eval `ssh-agent -s`
ssh-add $HOME/.ssh/id_ed25519
Next, we copy the public SSH key to your server:
ssh-copy-id [email protected]
Your public SSH key will be here in yournonrootuser
account on your server:
$HOME/.ssh/authorized_keys
Try to log on to your server as nonrootuser
:
ssh '[email protected]'
IMPORTANT: only if this is successful, you can proceed. Otherwise, go back and verify that you’ve followed all the steps correctly.
Disallow root access and set a custom SSH port
The next part is performed on your remote server and is hazardous. You might lock yourself out, so make sure you get the port number right every time! Check if you have the possibility to connect to your server with VNC, using a VNC client such as UltraVNC Viewer.
We don’t want to connect through the default SSH port 22 anymore, but we will set the SSH port number to your-ssh-port
, which is any number between 49152-65535.
sudo nano /etc/ssh/sshd_config
(use sudo apt install nano
if you have to)
In this file:
- Change
#Port 22
to:Port your-ssh-port
- Change
PermitRootLogin yes
to:PermitRootLogin no
(Note: there could be more than one entry forPermitRootLogin
) - Below this line, add a new line:
AllowUsers nonrootuser
- Change
#PasswordAuthentication yes
to:PasswordAuthentication no
- Change
ChallengeResponseAuthentication no
to:ChallengeResponseAuthentication yes
(Note: this is for adding 2FA with Google Authenticator later on)
Now save the file. In our example, you only want access to your server using port your-ssh-port
. Let’s set up your firewall with a clean slate. We’re only opening the customized port your-ssh-port
that we will be using for SSH:
sudo ufw reset
(use sudo apt install ufw
if you have to)sudo ufw allow your-ssh-port
sudo ufw enable
(After this step, there is a small chance that you will need to login to your server again with nonrootuser
through customized SSH port your-ssh-port
, with the password you set for nonrootuser
when you created this user.)
Now we need to restart the SSH server/daemon in order for the changes to take effect:
sudo service ssh restart
Important tip: try to maintain your current SSH session for as long as possible and open a new local terminal to proceed with the next steps. Keeping the current SSH session open will allow you to easily undo your changes if it turns out that you made a mistake somewhere!
Access your newly configured server with SSH
Now we open a new terminal (in MobaXTerm you would use a new tab) and we log on to your server with our new configuration. Your server has already become much more secure. It’s become impossible to connect as user root
, you now need to specify nonrootuser
as the username, and you can’t use a password anymore to login but you’ll need the private SSH key with the associated passphrase. You will also need to specify the SSH port, which is not port 22 anymore but your-ssh-port
(the port number you chose in the 49152-65535 range). You can login from the command line with:
ssh -p your-ssh-port -i $HOME/.ssh/id_ed25519 [email protected]
In MobaXTerm, you could also start (and save) a session like this:
Session interface in MobaXTerm. Your private key will be in the “Persistent Home Directory”\.ssh folder.
For mobile access using the Termius app, you should save the private key file locally on your mobile phone. In the Termius menu, choose Keychain to add your private key file to the collection. For each host, you can specify the key file. Also, don’t forget to specify the username (nonrootuser
) and the port (your-ssh-port
).
Add 2FA with Google Authenticator
After you have confirmed that the steps above have been successful, you can proceed with adding 2FA (two-factor authorization). This extra layer of security will eliminate the slightest chance left of someone compromising your server. We will use the Google Authenticator app available for Android (in the Play Store) and iOS (in iTunes) to generate authentication codes. If you want the best security within reasonable bounds, this is it!
First, we will install the Google Authenticator PAM (Pluggable Authentication Module):
sudo apt install libpam-google-authenticator
Now we configure the 2FA authorization by running this command:
google-authenticator
After you run the command, you’ll be asked a few questions:
- Do you want authentication tokens to be time-based?:
y
After answering this question, a lot of output will scroll past, including a large QR code. At this point, use your authenticator app on your phone to scan the QR code or manually type in the secret key. If the QR code is too big to scan, you can use the URL above the QR code to get a smaller version. Once it’s added, you’ll see a six digit code that changes every 30 seconds in your app.
- Do you want me to update your “/home/nonrootuser/.google_authenticator” file?:
y
- Disallow multiple uses of the same authentication token?:
y
- Permit for a time skew of up to 4 minutes between client and server?
n
- Enable rate-limiting?
y
To make SSH use the Google Authenticator PAM module, we need to edit the /etc/pam.d/sshd
file:
sudo nano /etc/pam.d/sshd
In this file:
- Find the line
@include common-auth
and comment it out by adding a#
character as the first character on the line. This tells PAM not to prompt for a password. - To make SSH use the Google Authenticator PAM module, add the following line at the bottom of the
/etc/pam.d/sshd
file:auth required pam_google_authenticator.so
Now save the file. Next, we’ll configure SSH to support this kind of authentication. Re-open the SSH configuration file for editing.
sudo nano /etc/ssh/sshd_config
Add the following line at the bottom of the file. This tells SSH which authentication methods are required. This line tells SSH we need both an SSH key and a Google Authenticator verification code:
AuthenticationMethods publickey,keyboard-interactive
(Check one more time that this file includes the line ChallengeResponseAuthentication yes
, because this is important.)
Finally, we need to restart the SSH server/daemon in order for the changes to take effect:
sudo service ssh restart
Important tip: try to maintain your current SSH session for as long as possible and open a new local terminal to proceed with the next steps. Keeping the current SSH session open will allow you to easily undo your changes if it turns out that you made a mistake somewhere!
Now try to login in a new terminal tab from the command line with:
ssh -p your-ssh-port -i $HOME/.ssh/id_ed25519 [email protected]
You could also use your previously saved MobaXTerm session. If all is well, you will be prompted for the passphrase of your private SSH key first, after which you will be prompted for a “Verification code”, which is your 6-digit Google Authenticator code.
Block suspicious IP addresses with Fail2Ban
If you want to go the extra mile, consider using Fail2Ban to block IP addresses with several failed login attempts.
You can install it with:
sudo apt-get install fail2ban
Configure a Fail2Ban jail:
sudo nano /etc/fail2ban/jail.local
In this new file, paste the following contents:
[sshd]
enabled = true
port = your-ssh-port
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
Finally, start the Fail2Ban daemon and enable it on reboot:
sudo systemctl start fail2ban && sudo systemctl enable fail2ban
Disable VNC access
If you have VNC access enabled and you are sure that you can login using SSH, you can now disable VNC access.
. . .
Welcome to a new level of security!
That’s all it takes to add a few much-needed layers of extra security to your Linux machine.
Congratulations! You have just secured your server like a boss.
. . .
References
https://hostadvice.com/how-to/how-to-change-your-ssh-port-from-the-default-for-security/
https://www.cyberciti.biz/faq/ubuntu-18-04-setup-ssh-public-key-authentication/
https://www.cyberciti.biz/faq/how-to-disable-ssh-password-login-on-linux/
https://ubuntu.com/tutorials/configure-ssh-2fa#5-getting-help
https://www.techrepublic.com/article/how-to-install-fail2ban-on-ubuntu-server-18-04/
This web site certainly has all of the info I wanted about this subject and didn’t know who to ask.
Somebody essentially assist to make severely posts I would state. That is the very first time I frequented your website page and thus far? I amazed with the analysis you made to make this actual post incredible. Great process!