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 -
- Get a cheapo VPS on Digital Ocean, Vultr (get $100 credit), Hetzner, OVH, and friends - I end up choosing Ubuntu as the OS
- Secure your server
- Setup app server, database server and tools
- 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 -
- Already created the server using the browser console provided by your favourite service provider
- You have chosen Ubuntu LTS (v20.4 at this time, though it should quite happily work the same for v18.4)
- 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.
|
|
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.
|
|
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.
|
|
Enter password for new user. Next allow the new user to sudo.
|
|
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.
|
|
Once the update is complete, reboot server.
|
|
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.
|
|
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.
|
|
Copy/paste the following lines -
|
|
3. Change SSH Port and Default User Access
We will do two things here -
- Change SSH port & protocol
- 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 -
|
|
Open the config file and change the default 22 port used by SSH.
|
|
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.
|
|
Enable non-root SSH user
Open another command prompt. Try logging in to your server with the user id that was created earlier.
|
|
Once you are in, try to run a sudo command.
|
|
If things worked well so far, it is time to disable root login using SSH.
Open the SSH config on server.
|
|
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.
|
|
Open yet another command prompt and try logging in as root.
|
|
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.
|
|
securepassphrase- can be anything that you can remember but at the same time secures access to SSH server from your computered25519provides the encryption algorithm used to generate keysmycomputeris 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 keyid_ed25519.pub- public key
Next, we update the generated public key on the server.
|
|
Create .ssh directory (if it doesn’t exist) and create a new file within in.
|
|
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 -
|
|
Open a command prompt on client, and login with key.
|
|
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 -
|
|
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.
|
|
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 -
|
|
Check status by using -
|
|
Configure ufw to allow SSH sessions on our SSH port. This is important since ufw closes all ports by default. Enable firewall.
|
|
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 -
|
|
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.
|
|
Copy the default config file to jail.local and restart service.
|
|
6. Get on with your apps
With your server setup you can start installing your applications. A few of those are super useful -
-
Vim Editor
1sudo apt-get install vim -
Install
fishas default shell, andomfto configurefish1 2 3apt-get install fish chsh -s /usr/bin/fish curl -L https://get.oh-my.fish | fish -
1sudo apt-get install caddy -
Install Node (v12.x)
1 2curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - sudo apt-get install -y nodejs -
Install MySQL database and configure MySQL. You will also need to open port in
ufw.1 2sudo apt install mysql-server sudo mysql_secure_installation
That’s all folks - enjoy your brand new VPS!