Here are some base guidelines I follow when setting up a new VPS manually without configuration management. These steps if anything makes the system more secure overall and provides a good starting point from which you can set up the services/software required for the purpose of the VPS.
All of these steps in this post are from the context of a droplet (VPS) hosted by Digital Ocean using the Debian 8.5 x64 kernel images they use as of the above date.
1 – Setup VPS User Account
Initial root access for this section is assumed. Adding a registered SSH public key to the droplet creation on Digital Ocean gives pass-wordless root access to the VPS.
[alert-announce]
- $ ssh [email protected]
[/alert-announce]
Install the sudo
package manually as this is not included with Digital Ocean’s Debian 8 image.
[alert-announce]
- $ apt-get install sudo
[/alert-announce]
Add your new Linux user to the system. Whenever you see scarlz
here in commands it should be replaced with your own preferred username, and substituted in from throughout.
[alert-announce]
- $ adduser scarlz
[/alert-announce]
Add the newly created user to the sudo
elevation privileges group.
[alert-announce]
- $ adduser scarlz sudo
[/alert-announce]
You can also add the user to the adm
group which grants read access to system log files if you think this would be useful.
[alert-announce]
- $ adduser scarlz adm
[/alert-announce]
Exit the root SSH session.
[alert-announce]
- $ exit
[/alert-announce]
2 – Copy Client Public SSH Key
Install your public key to the new user added in the previous step.
Do this by running the ssh-copy-id
command, supplying it with the the username and IP address of the VPS.
[alert-announce]
- $ ssh-copy-id [email protected]
[/alert-announce]
The public key (after authentication) will be added to the remote user’s ~/.ssh/authorized_keys
file.
As long as the client has the private key tied to the public key just registered, it can be used to log into the VPS.
3 – Update and Install System Packages
SSH back into the VPS as the new user you created previously, which should work without requiring authentication details thanks to the previous step.
[alert-announce]
- $ ssh [email protected]
- $ sudo apt-get update && sudo apt-get upgrade
[/alert-announce]
Run this command to ensure the system’s packages are up to date.
[alert-announce]
- $ sudo apt-get update && sudo apt-get upgrade
[/alert-announce]
4 – Default SSH Port and Root Access
This step removes the assumption any port scanning makes on what port number the SSH service is running on. The default is 22
so these processes will check for that first and foremost. Changing this number to an ephemeral port can help to reduce the number of attempted malicious login attempts that are made. However there are several finer points as to why you might not want to do this, so decide if this seems worthwhile or not before doing it (see the next link).
Note: Should I change the default SSH port on linux servers?
All I would say is don’t get into the habit of doing this for other service’s port numbers. If you choose not to do this then Fail2ban (which we install later) will be enough in its place.
Disabling password authentication for the root user account and relying on the registered SSH key can also put a stop to attempted root logins from unwanted hosts.
Change the VPS’s default SSH port & disable root login via passwords in the system-wide SSH config file.
[alert-announce]
- $ sudo vim /etc/ssh/sshd_config
[/alert-announce]
Change the Port 22
entry to any number between 1025
and 65536
respectively, if you have decided you want to do this.
For example:
[alert-announce]
/etc/ssh/sshd_config
- Port 3267
[/alert-announce]
Change the PermitRootLogin yes
entry to PermitRootLogin without-password
instead,
This as mentioned before means only users with public SSH keys registered in the root authorised keys file can log in as root itself.
[alert-announce]
/etc/ssh/sshd_config
- PermitRootLogin without-password
[/alert-announce]
Restart SSH so the changes take effect.
[alert-announce]
- $ sudo service ssh restart
[/alert-announce]
When accessing the VPS via SSH in the future, you must now append the correct port number to the command e.g.
[alert-announce]
- $ ssh [email protected] -p 3267
[/alert-announce]
5 – Automatic Security Upgrades
Using a package named unattended-upgrades
it’s possible to have updates done by the package manager automatically at set intervals. It is advised to only enable security updating and not the normal package upgrading as this could potentially cause problems with conflicts or unwanted changes.
Install the package to begin with.
[alert-announce]
- $ sudo apt-get install unattended-upgrades
[/alert-announce]
Open/create the 10periodic
configuration file for this package using your preferred text editor.
[alert-announce]
- $ sudo vim /etc/apt/apt.conf.d/10periodic
[/alert-announce]
Add in the lines found in the below code snippet:
[alert-announce]
/etc/apt/apt.conf.d/10periodic
- APT::Periodic::Update-Package-Lists “1”;
- APT::Periodic::Download-Upgradeable-Packages “1”;
- APT::Periodic::AutocleanInterval “7”;
- APT::Periodic::Unattended-Upgrade “1”;
[/alert-announce]
Save your additions and exit the file.
Now open up another configuration file named 50unattended-upgrades
for changes.
[alert-announce]
- $ sudo vim /etc/apt/apt.conf.d/50unattended-upgrades
[/alert-announce]
Enable security updates only by adding the line – "origin=Debian,codename=${distro_codename},label=Debian-Security";
to the correct location, as shown in the next code snippet on line 17:
[alert-announce]
- Unattended-Upgrade::Origins-Pattern {
- // Codename based matching:
- // This will follow the migration of a release through different
- // archives (e.g. from testing to stable and later oldstable).
- // “o=Debian,n=jessie”;
- // “o=Debian,n=jessie-updates”;
- // “o=Debian,n=jessie-proposed-updates”;
- // “o=Debian,n=jessie,l=Debian-Security”;
- // Archive or Suite based matching:
- // Note that this will silently match a different release after
- // migration to the specified archive (e.g. testing becomes the
- // new stable).
- // “o=Debian,a=stable”;
- // “o=Debian,a=stable-updates”;
- // “o=Debian,a=proposed-updates”;
- “origin=Debian,codename=${distro_codename},label=Debian-Security”;
- };
[/alert-announce]
Further down in the file add an email address thatcan receive the update reports and uncomment the line itself:
[alert-announce]
/etc/apt/apt.conf.d/50unattended-upgrades
- // Send email to this address for problems or packages upgrades
- // If empty or unset then no email is sent, make sure that you
- // have a working mail setup on your system. A package that provides
- // ‘mailx’ must be installed. E.g. “[email protected]”
- Unattended-Upgrade::Mail “[email protected]”;
[/alert-announce]
6 – Setup Dotfiles (Optional)
Most administrators or developers will have their own customised dotfiles they use to personalise the server and make tasks easier, or introduce extra functionality to the system. Here is where I would setup my own using Git and GitHub.
It is unlikely that you’ll want to carry out the commands in this step as these instructions are for my own dotfiles, so only really relevant to me.
Replace this step with installing and setting up your own equivalent dotfiles!
Install Git via the system package manager.
[alert-announce]
- $ sudo apt-get install git
[/alert-announce]
Clone your dotfiles repository onto the system.
[alert-announce]
- $ git clone https://github.com/5car1z/dotfiles.git
- $ cd ~/dotfiles
[/alert-announce]
Run the two install scripts that add more packages (all the good stuff) and create the necessary symlinks using GNU Stow.
[alert-announce]
- $ ./install-debian-ubuntu-dotfile-dependencies.sh
- $ ./stow-dotfiles.sh
[/alert-announce]
If there’s any submodule problems update them to their latest remote versions with:
[alert-announce]
- $ update_submodules
[/alert-announce]
7 – Install Software Packages
Any outstanding or super essential packages that haven’t been brought in ny the “dotfiles” step should be considered before moving on. What these are will be known only to you though as everybody’s preferences and needs are different.
Here are several examples, however.
[alert-announce]
- $ sudo apt-get install git vim curl cowsay fortune-mod jq vim tmux ranger
[/alert-announce]
8 – Install and Run UFW
UFW stands for “Uncomplicated Firewall” and is more concise easier to understand alternative to older firewall implementations like iptables.
Install on Debian 8 like any other package simply using:
[alert-announce]
- $ sudo apt-get install ufw
[/alert-announce]
Like with other firewalls of this elk it’s common practice to put in place a blanket set of ingress/egress rules then add the exceptions to services and ports on top afterwards.
Make the default overall action for any incoming traffic to be blocked and denied.
[alert-announce]
- $ sudo ufw default deny incoming
[/alert-announce]
Then make the default overall action for outgoing traffic to be permissible and allowed.
[alert-announce]
- $ sudo ufw default allow outgoing
[/alert-announce]
From here, any services you wish to allow that are received by the VPS can be added as an exception. See a separate post that covers the key areas of UFW in itself for information on how to do this.
To continue here, open the SSH port number you chose earlier on by replacing the number 3267
with your own number, in the following command.
[alert-announce]
- $ sudo ufw allow 3267/tcp
[/alert-announce]
Lastly after all the extra rules you need, enable the firewall so the configuration becomes active.
[alert-announce]
- $ sudo ufw enable
[/alert-announce]
9 – Install and Run Fail2ban
This application permanently stops any excessive failed attempts (brute forcing) at connecting to the VPS – it achieves this by banning the offending source IP. This is configurable over various services on the system and not just SSH.
Install it as done before with the system package manager.
[alert-announce]
- $ sudo apt-get install fail2ban sendmail
[/alert-announce]
Sendmail can also be used by Fail2ban when sending out notification messages for bans that have occurred, so this is useful to install alongside it. Unless you want to configure it to use a different mail service.
[alert-announce]
- $ sudo sed ‘s/^banaction = .*/banaction = ufw/’ /etc/fail2ban/jail.conf > /etc/fail2ban/jail.local
[/alert-announce]
Start the service and ensure it’s running by ussing the command:
[alert-announce]
- $ sudo service fail2ban start
[/alert-announce]
This is a pretty straightforward post, all things considered. Remember that a persons needs for configuring a VPS will be tailored to their own requirements, criteria, and preferences. So these steps are a good general outline but mainly the ones I personally follow – other people’s will be different, according to their needs.