This page looks best with JavaScript enabled

Setup Ubuntu VPS - First Few Steps

 ·   ·  ☕ 8 min read

I create virtual private servers at least 8-12 times an year for client and personal projects. The steps to go live remain the same -

  1. Get a cheapo VPS on Digital Ocean, Vultr (get $100 credit), Hetzner, OVH, and friends - I end up choosing Ubuntu as the OS
  2. Secure your server
  3. Setup app server, database server and tools
  4. Stitch together various components through configuration files

I have thought about switching to Docker (or Caprover) for months, but keep putting off any kind of automation. The adhoc sharing of DB servers, file systems, report/analytics servers make it a tricky exercise. I don’t quite spend more than 4 hours on a crazy day - so it’s not quite a big deal.

Not being a sys admin myself I follow a few “best practice” steps recommended by smarter people on the Internet. Here’s an easy-to-follow list for setting up a secure VPS.

1. Get Access and Logon

I assume that you have -

  1. Already created the server using the browser console provided by your favourite service provider
  2. You have chosen Ubuntu LTS (v20.4 at this time, though it should quite happily work the same for v18.4)
  3. I use a Windows computer to connect to VPS. A few steps for configuring client will differ if you are using Linux or Mac

Login to your server.

1
ssh root@<password_in_email>@<server_ip>

You will get a message like this -

The authenticity of host '11.11.111.111 (11.11.111.111)' can't be established.
ECDSA key fingerprint is SHA256:XXBLAH.
Are you sure you want to continue connecting (yes/no)? yes

Enter yes to continue.

You can make this step more secure when creating servers with some providers like Hetzner. You can enter the SSH public key at the time of server creation and get seamless access to the server once it is created. We will get to the public key part soon.

Change root password.

1
passwd

Enter new password for root. It is a good idea to store this in LastPass or some other password management tool.

Add a new admin user. This id will be the default to login to your server.

1
adduser aweadmin

Enter password for new user. Next allow the new user to sudo.

1
usermod -aG sudo aweadmin

The goal is to get farther from defaults to make it more safe. This by itself will not completely secure the server, but reduce the risk of your server being of any interest to hackers.

2. Enable Automatic Security Updates

First, let us update the OS.

1
2
apt update
apt dist-upgrade

Once the update is complete, reboot server.

1
reboot

Your SSH session will disconnect and server will reboot. Re-login using SSH to your server.

Recent versions of Ubuntu have unattended updates by default. You can verify or change those updates -

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

If you are using an older version, you may need to install and configure automatic updates.

1
2
apt install unattended-upgrades
nano /etc/apt/apt.conf.d/50unattended-upgrades

Comment out everything other than the security updates.

Unattended-Upgrade::Allowed-Origins {
//      "${distro_id}:${distro_codename}";
        "${distro_id}:${distro_codename}-security";
        // Extended Security Maintenance; doesn't necessarily exist for
        // every release and this system may not have it installed, but if
        // available, the policy for updates is such that unattended-upgrades
        // should also install from here by default.
        "${distro_id}ESM:${distro_codename}";
//      "${distro_id}:${distro_codename}-updates";
//      "${distro_id}:${distro_codename}-proposed";
//      "${distro_id}:${distro_codename}-backports";
};

Save file with Ctrl+O > Enter. Exit the editor with Ctrl+X.

So far you have configured automatic updates. Next, enable the automatic updates.

1
nano /etc/apt/apt.conf.d/20auto-upgrades

Copy/paste the following lines -

1
2
3
4
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

3. Change SSH Port and Default User Access

We will do two things here -

  1. Change SSH port & protocol
  2. Enable additional SSH user and disable root access

Change Port and Use Protocol 2

SSH uses port 22 by default. But, you can choose any free port between 1023 and 65535. You can find out whether a port is free with the following command -

1
ss -tulpn | grep LISTEN

Open the config file and change the default 22 port used by SSH.

1
nano /etc/ssh/sshd_config

Find the line which begins with Port and change it -

Port 65432

While we are at it, let us also add a line to force SSH to always use Protocol 2. Just add the below line anywhere in the file.

Protocol 2

Ctrl+o > Enter + Ctrl+x to save and exit out of the editor.

Restart SSH.

1
sudo systemctl restart ssh

Enable non-root SSH user

Open another command prompt. Try logging in to your server with the user id that was created earlier.

1
ssh -p 65432 aweadmin@11.11.111.111

Once you are in, try to run a sudo command.

1
sudo ls /root

If things worked well so far, it is time to disable root login using SSH.

Open the SSH config on server.

1
sudo nano /etc/ssh/sshd_config

Change the below parameter to no and insert a new line to enable access for the new admin user.

PermitRootLogin no
AllowUsers aweadmin

Ctrl+o > Enter + Ctrl+x to save and exit out of the editor.

Restart SSH.

1
sudo systemctl restart ssh

Open yet another command prompt and try logging in as root.

1
ssh -p 65432 root@11.11.111.111

This should not work but aweadmin will login without problems.

4. Disable SSH login with password

If you ever check the security logs on your server, you will find a series of attempts to access your server with default user ids, ports and common passwords. In this section, we will disable SSH access using password altogether and enable only clients with trusted keys to login.

Let us first set up the client (which is our computer = not server).

Run following command to generate a public/private key on your computer.

1
ssh-keygen -N "securepassphrase" -t ed25519 -C "mycomputer"
  • securepassphrase - can be anything that you can remember but at the same time secures access to SSH server from your computer
  • ed25519 provides the encryption algorithm used to generate keys
  • mycomputer is just a random name which is a description for the key. You may want to provide different descriptions on other computers

Accept the default file names for public and private keys (or change them). You should have two files in c:\user\<user_name>\.ssh\ folder.

  • id_ed25519 - file with private key
  • id_ed25519.pub - public key

Next, we update the generated public key on the server.

1
ssh -p 65432 aweadmin@11.11.111.111

Create .ssh directory (if it doesn’t exist) and create a new file within in.

1
2
mkdir /home/aweadmin/.ssh
nano /home/aweadmin/.ssh/authorized_keys

Copy / paste the public key from id_ed25519.pub.

Ctrl+o > Enter + Ctrl+x to save and exit out of the editor.

Change the default permission for the newly created file -

1
chmod 0600 /home/aweadmin/.ssh/authorized_keys

Open a command prompt on client, and login with key.

1
ssh aweadmin@11.11.11.1111

You will get a different prompt that asks for the key passphrase. Enter the passphrase to gain access to the server - you are not required to type the aweadmin's password again.

Next, we will disable password logins in the SSH config file -

1
sudo nano /etc/ssh/sshd_config

Change following parameter -

PasswordAuthentication no

Ctrl+o > Enter + Ctrl+x to save and exit out of the editor.

You are required to enter passphrase when logging in each time. We can work around that.

Go to Start > Services to list Windows services (or Start > Run > Enter services.msc). You should find a service called OpenSSH Authentication Agent service that will be in disabled state by default. Enable the service to start automatically with Windows and start the service.

Go to Start > Run > type notepad c:\<user>\.ssh\config. Enter following lines -

Host 11.11.111.111
  User aweadmin
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  Port 65432

Save file. Ensure that the file is saved without the default txt extension.

You should now be able to login to the server without entering user id, password or key passphrase.

1
ssh 11.11.111.111

If you use multiple computers, or want to provide access to other users, just repeat the steps to generate distinct private keys and update public key on the server.

5. Secure Your Server

Let us install and enable software to secure the server.

Firewall

I typically use UFW because it is quite simple to setup and understand.

You can install / update ufw with -

1
sudo apt install ufw

Check status by using -

1
sudo ufw status

Configure ufw to allow SSH sessions on our SSH port. This is important since ufw closes all ports by default. Enable firewall.

1
2
sudo ufw allow 65432/tcp
sudo ufw enable

Open another command prompt and try accessing the server with default port - you should be able to login.

You can check the rules with the command -

1
sudo ufw show added

Intrusion Detection

We will install Fail2Ban to work alongside the firewall and secure our server. fail2ban is an intrusion detection and prevention framework that can automatically ban IPs temporarily (or otherwise) based on invalid login attempts.

1
2
3
sudo add-apt-repository universe
sudo apt-update
sudo apt install fail2ban

Copy the default config file to jail.local and restart service.

1
2
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
service fail2ban restart

6. Get on with your apps

With your server setup you can start installing your applications. A few of those are super useful -

  1. Vim Editor

    1
    
    sudo apt-get install vim
    
  2. Install fish as default shell, and omf to configure fish

    1
    2
    3
    
    apt-get install fish
    chsh -s /usr/bin/fish
    curl -L https://get.oh-my.fish | fish
    
  3. Caddy Web server

    1
    
    sudo apt-get install caddy
    
  4. Install Node (v12.x)

    1
    2
    
    curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
    sudo apt-get install -y nodejs
    
  5. Install MySQL database and configure MySQL. You will also need to open port in ufw.

    1
    2
    
    sudo apt install mysql-server
    sudo mysql_secure_installation
    

That’s all folks - enjoy your brand new VPS!

Stay in touch!
Share on

Prashanth Krishnamurthy
WRITTEN BY
Prashanth Krishnamurthy
Technologist | Creator of Things