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 computered25519
provides the encryption algorithm used to generate keysmycomputer
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 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
1
sudo apt-get install vim
-
Install
fish
as default shell, andomf
to configurefish
1 2 3
apt-get install fish chsh -s /usr/bin/fish curl -L https://get.oh-my.fish | fish
-
1
sudo apt-get install caddy
-
Install Node (v12.x)
1 2
curl -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 2
sudo apt install mysql-server sudo mysql_secure_installation
That’s all folks - enjoy your brand new VPS!