First 10 Minutes on an Ubuntu Server

First 10 Minutes on an Ubuntu Server

When you first boot up an Ubuntu server, you have to first secure it before launching your apps. In this tutorial I go through the basics of securing / hardening an Ubuntu instance. I would love to hear your thoughts on this in the comments and any actions you do that I didn’t mention or anything you think is superfluous etc. 

Let’s Dive!

Enable Auto Updates

We’ll start by enabling automatic security updates.

							
							
					sudo apt-get install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
				
			

Create a New Sudo User

Next we need to create a new user and grant them sudo privileges. This is because running as root all of the time is just not a good idea, more on this here: https://serverfault.com/questions/57962/whats-wrong-with-always-being-root. We will create our new user via: 

							
							
					adduser <username>				
			

You will be prompted to input a password, confirm the password, and add any details needed regarding the user. Once you have created the new user we will assign the user to the sudo users group via: 

							
							
					usermod -aG sudo <username>				
			

Next we will move onto ssh hardening.

SSH Hardening

In this section we will cover ssh hardening. Including enabling ssh keys, disabling password based logins via ssh, disabling root access via ssh, other ssh hardening measures, as well as optionally setting up time based 2FA. 

Enable SSH Keys

SSH keys are a more secure alternative to password based logins to an ssh server, for more info on that see: https://news.ycombinator.com/item?id=35854969. It is highly recommended that you enable ssh key authentication and disable password based authentication on your SSH server. 

The first step is to generate an SSH key pair. We do this on our local machine by entering the following command: 

							
							
					ssh-keygen -t rsa -b 4096  -C  "youremail@example.com"				
			

Once you generate the key it will prompt you for where to save the key to, the standard is ~/.ssh/id_rsa, however if you have multiple keys or will have multiple keys you may want to name them for your own reference. Enter the path to save the key and hit enter. 

Note:  This creates two keys a private key and a public key. The private key should be kept absolutely secure and private, whereas the public key is not so sensitive.

You will also be prompted to enter a passkey for accessing the ssh private key.

Once the key is saved, the terminal will output the key’s fingerprint and the key’s random art image.

Now that you have an ssh key pair, we will copy the ssh public key to the remote server. If your local machine does not have ssh-copy-id installed you can manually copy the public key to the remote server see this post here: {LINK COMING SOON}

							
							
					ssh-copy-id username@hostname_ip				
			

If you saved your private key under a different name or path than the default, you will have to specify the exact path to the public key, be sure to copy the PUBLIC key not the private key to the remote server, for instance the modified command may look like: 

							
							
					ssh-copy-id -i ~/.ssh/mysshkey_id_rsa.pub username@hostname_ip				
			

To verify the keys work, open a new terminal and try logging into the server, you should be prompted for your passkey, and log in, if not, then the configuration isn’t correct.

Disable Password Logins

Once you have copied the public key over to the remote server and VERIFIED the keys are working (you should not have to enter your ssh password to login into the remote server), it is time to disable remote ssh access to the server via password authentication. BE CAREFUL, IF YOUR KEYS ARE NOT WORKING YOU WILL BE LOCKED OUT OF YOUR SERVER FOREVER.

Begin by logging into the server via ssh, it should automatically log you in via your ssh keys (if it doesn’t, you shouldn’t be about to disable password authenticcation), now we are going to edit the ssh config file, it should be located at /etc/ssh/sshd_config, once you open the file in an editor, find the line that says PasswordAuthentication, it will be set to “yes”, you want to set it to “no”.  

Note: Be sure the setting “PubKeyAuthentication” is set to “yes”, it should be by default, but just be sure, otherwise you will not be able to login to the ssh server using SSH Key authentication.

Disable Root User Logins & Other Secuirty Hardening Measures

While still in the sshd_config file find the setting “PermitRootLogin” and set it to “no”, this will disable root logins into the ssh server. Some other settings we will configure include: “MaxAuthTries” set it according to company policies (this sets the number of login attempts per IP over a certain period of time), “PermitEmptyPasswords” set to “no” (should be already), and “ChallengeResponseAuthentication” set to “no” (if you setup 2FA on the server in the next couple steps you can leave this setting to “yes”).  At this point we will exit the editor (Ctrl X and enter “Y” to save.) and restart the ssh server via the following command and ensure the new configuration is working properly. For instance try logging in with password based authentication, if it fails you know the configuration has updated successfully.

							
							
					sudo systemctl restart ssh				
			

In the next section we will change the default ssh port to a non-default port so as to prevent unwanted traffic.

Changing the Default SSH Port on the Remote Server

SSH uses port 22 by default, this is industry standard and there are good reasons for it, however as it is universally known malicious actors also know what port your ssh server is likely running on. In this section we will cover how to change the default ssh server to a less common port of your choice, preventing hackers from attempting to brute force their way into your server.

Navigate back to the ssh config file at /etc/ssh/sshd_config and find the “Port” setting you will see that it is set to “22” switch to whatever you want (you may want to avoid using well-known ports see: https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers) Be sure your firewalls are configured to allow incoming traffic to the new port. Restart the ssh server as before and ensure you are able to login to the server with the new port. 

In the next section we go through setting up 2FA on our ssh server. 

Installing Time Based 2FA for our SSH Server

In this section we will install Google Authenticator to provide time-based 2FA as a second layer of protection on our server. I will mention that if you are using SSH keys that you are most likely fine to treat this as optional. In fact I have a whole post on how to recover your server in case you get locked out of it due to 2FA issues. I guess I am saying you might not want to do this. 🙂

We will install the Google Authenticator PAM module via: 

							
							
					sudo apt install libpam-google-authenticator
				
			

Next we need to add the following line to the PAM ssh config file located at /etc/pam.d/sshd 

							
							
					auth required pam_google_authenticator.so nullok   
#nullok ensures that if problems arise due to a misconfiguration that you are still able to login 
#be sure to delete nullok for production				
			

And in the same file we need to comment out the line: @include common-auth, it should look like: #@include common-auth

Now we will restart the ssh server via: 

							
							
					sudo systemctl restart ssh				
			

Next we need to adjust the following settings in the /etc/ssh/sshd_config file:

  • “KbdInteractiveAuthentication” set to “yes”
  • “ChallengeResponseAuthentication” set to “yes”
  • “AuthenticationMethods” set to “publickey,keyboard-interactive”
  • “UsePAM” set to “yes”
  • “PasswordAuthentication” set to “no”

Once we have finished configuring the settings in the sshd_config file, exit the editor and we will configure the Google Authenticator settings. Run: 

							
							
					google-authenticator				
			

Then it will prompt with various settings and options, adjust the configuration as needed, I have provided a sample configuration below. Be sure to copy the emergency scratch codes somewhere safe.

							
							
					Do you want authentication tokens to be time-based (y/n) y

#You will see a GIANT QR code here

Your new secret key is: XXXXXXXXXXXXXXXXXXX
Enter code from app (-1 to skip): XXXXXXXX
Code confirmed
Your emergency scratch codes are:
  XXXXXX
  XXXXXX
  XXXXXX
  XXXXXX
  XXXXXX
Do you want me to update your "/home/<username>/.google_authenticator" file? (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) y

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y
				
			

Once you have finished the Google Authenticator configuration restart the ssh server via:

							
							
					sudo systemctl restart ssh				
			

Test logging into the server in a new terminal before logging out of the current session to ensure things are working properly.

Install Fail2Ban & UFW

In this section we install and configure Fail2Ban and UFW. Fail2Ban bans IPs after a specified number of failed logins over a specified period of time. It provides brute force protection for numerous apps on your server. 

Installing Fail2Ban & UFW

We will install Fail2Ban and UFW via: 

							
							
					sudo apt-get install fail2ban ufw				
			

Configuring Fail2Ban

Next we will configure fail2ban to monitor login attempts to the SSH Server. We need to edit the jail.local file located at: /etc/fail2ban/jail.local. Enter the following configuration or modify it as you prefer:

							
							
					[sshd]
enabled = true 
port = <your_custom_port>
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 600
findtime = 600
				
			

Now run: 

							
							
					sudo systemctl enable fail2ban
sudo systemctl start fail2ban				
			

To view active jails and jail details run: 

							
							
					sudo fail2ban-client status
sudo fail2ban-client status sshd     #ssh jail specific details including number of ips banned etc.				
			

Configuring UFW

Next we will configure UFW to allow HTTP, HTTPS, and SSH traffic. 

We will enable traffic over ports 80/tcp incoming and outgoing, 443/tcp incoming and outgoing, and <your_custom_ssh_port>/tcp incoming and outgoing. We will also set the default rules to block incoming and allow outgoing traffic.

							
							
					sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow <your_custom_ssh_port>
sudo ufw default deny incoming
sudo ufw default allow outgoing				
			

I have included some helpful ufw commands below: 

							
							
					sudo ufw allow <port_number>   #allows traffic to and from a specified port
sudo ufw deny <port_number>   #denys traffic to and from a specified port
sudo ufw status   #displays status of ufw including active rules
sudo ufw status numbered   #displays status of ufw including active rules along with the rule ID
sudo ufw status verbose   #displays status of ufw including active rules as well as default rules 
sudo ufw app list   #displays a list of application profiles 
sudo ufw delete <rule_id>   #deletes a firewall rule by rule ID				
			

Installing and Configuring Other Software

From here we can proceed with installing any other software we need to run on the server as well as other security and monitoring solutions, such as LogWatch. For this tutorial though we will keep with just the bare essentials and leave it at this.

That’s a wrap! Thanks for reading!

Walter Miely is a tech entrepreneur and CEO of Phoenix Ignited Tech You can find him on Linkedin. This material is licensed under the CC BY 4.0 License LEGAL DISCLAIMER: The content provided here is provided AS IS, and part of, or the entirety of this content may be incorrect. Please read the entireLegal Disclaimer here.