After creating a VPS instance (e.g. DigitalOcean droplet or Linode linode), you will be provided an IP address as well as login password. Use the credentials to log into the server.
Tips regarding authentication (explained further in SSH Lockdown below)
SSH login via root should be disabled
Only use ssh key authentication
Use a non-common port for ssh
Managing Users
By default, only one user exists: root - a superuser
Creating a new user
Create a new user to avoid using root and it's elevated privileges. While creating a new user, several questions will be asked. You can add additional information about the user but note that only the password is essential.( Press ENTER to skip the rest)
Confirm that you can login as this new user before proceeding.
SSH Lockdown
Disabling root login
Before disabling root login, ensure that you've created a user that can SSH to the server (as explained in User Management above).
The user can use the su command to become root (will need root password), or if the user has sudo they can just sudo su - to access root.
Edit /etc/ssh/sshd_config and turn PermitRootLogin to no. Use a different editor if new to vi (ZZ to exit).
Before doing this, ensure that you can login with another (non-root) user account (see User Management above).
Restart ssh service for this change to effect.
SSH Key-Based Authentication
You can now setup public key authentication (recommended). This will enable you to securely login to the server without having to enter your password.
Public Key authentication enables you to login to a server using ssh public key. This is my recommended method of authentication.
SSH Keys come in a pair; a private and public key.
Generate Key Pair
OpenSSH client is required, this is most likely already installed. You can install it with sudo apt-get -y install openssh-client
Use the following commands to have the key pair generated; accept the defaults by just pressing Enter. You can leave the password empty (optional). You should use existing keys if you already have them.
The public and private keys will be generate in the default directory ~/.ssh as ~/.ssh/id_rsa.pub and ~/.ssh/id_rsa respectively. The public key (id_rsa.pub) can safely be shared, however, NEVER share your private key (id_rsa).
In order to login with the generate ssh keys, append the contents of the public key to the following file in the VPS ~/.ssh/authorized_keys.
From your computer, you can run either of the following commands. They will require inputting your password once.
You can now simply login without entering a password with ssh USERNAME@SERVER_IP.
Edit /etc/ssh/sshd_config and change the Port number to a non-common SSH port (just pick an unused number more that 1025, note: don't use 2222, it's also common)
Update Server
Update server software:
Set desired server hostname: As superuser, edit the files /etc/hostname and /etc/hosts. To update without a restart restart, run this: systemctl restart systemd-logind.service
Update the timezone, to your desired timezone. Use dpkg-reconfigure tzdata
Add Swap
Check if swap is already enabled on the server, if enabled, the swap partition will be listed.
If swap is not enabled, check the amount disk space you have available.
Create swapfile (usu 2x or 1x your RAM)
Verify space has been allocated
Enable Swap
Enable Swap on Reboot/ Start: Edit fstab (/etc/fstab), and add the swap filesystem.
If you are working on a RAM intensive app, e.g Java, consider reducing swappiness and inode cache rate.
Read how to do that
Tweak Swappiness
Check the current swappiness (0-100)
Change swappiness to your desired value.
Enable on restarts
Inode Cache Rate
Configuring a Firewall
UFW(uncomplicated firewall) is a tool that simplifies configuring of iptables to secure your server. It is an easy to use firewall.
Install ufw (most likely already installed)
Enable IPv6: Edit /etc/default/ufw and set IPv6=yes
Check ufw status and rules (will be inactive if not yet enabled).
Setup default firewall policies
Allow common connections only allow what you use
Allowing SSH connection (default ssh port 22)
If you are using different port for SSH (see SSH Lockdown: custom port above), then allow that instead of port 22
Allow HTTP and HTTPS
Allow SMTP - if sending out mail directly using SMTP
Check all added exceptions (allowed connections)
Enable UFW: Also useful when reloading to update configuration
Reset UFW
In case of errors during configuration, you can reset ufw with the following command
UFW and docker: Docker usually manipulates iptables rules meaning that the ufw restrictions will not apply.
Read how to fix that
Here are a few workarounds I've found useful. You can either:
Only bind docker containers to loopback interfaces e.g. docker run -p "127.0.0.1:8080:80"..
Not use port forwarding (-p or -P) esp. if you don't need it.
Add --iptables=false to the docker daemon: Uncomment the following line in /etc/default/docker
Restart the docker service for the change to effect sudo service restart docker
Use the host's network docker run --net host..
Intrusion Prevention with Fail2ban
Fail2ban is an open source intrusion prevention software that scans log files and bans IPs with malicious behaviour such as too many invalid login attempts or automated attacks.
It primarily focusses on SSH attacks but can be configured to work with other services (e.g Apache, SMTP, FTP) based on their logs.
Install fail2ban
Configuring Fail2ban
Fail2ban configuration files are located at the /etc/fail2ban/ directory.
The fail2ban configuration profile /etc/fail2ban/fail2ban.conf: this contains settings for fail2ban itself (eg logging level, pid and socket locations).
Fail2ban defail jail configuration: /etc/fail2ban/jail.conf: contains declarations for jails (filters and actions), this is usually what you want to customize.
In order to customize fail2ban configs, create .local files at /etc/fail2ban containing your desired configuration settings. Settings in .local will override settings in .conf files.
Therefore:
copy fail2ban.conf to fail2ban.local (optional)
copy jail.conf to jail.local (usu what you'll want to customize)
Fail2ban jails are a combination of filters and actions for the various services it will protect.
Pre-defined filters and templates of how to declare jails are defined in jail.conf, which you copied to jail.local.
To customize your jails, edit the file jail.local
The following options are declared when defining jails:
filter
name of pattern to be used to detect matches, each match increments a counter
logpath
path to log file to be used by filter (default: /var/log/messages)
maxretry
number of filter matches (counter) that trigger ban action (default: 3)
findtime
reset counter if no filter matches in this time (seconds) (default: 600)
bantime
duration (seconds) to ban, negative number for permanent ban (default: 600)
Sections
The jail.local file is divided into sections.
Jails are defined in their own sections some sections have special uses for example [DEFAULT] includes global configurations that apply to all jails and can be overwritten in each individual jail.
Commonly customized settings in the [DEFAULT] section:
ignoreip is used to specify IPs that will not be banned. You can append you IP if you have a dedicate IP you use often (203.0.113.11 below is an example)
bantime, findtime and maxretry are for changing jail option default values
If you wish to enable email, update the values for destemail,sendername and mta
Example:
Individual Jail Sections
To enable the jail, set the enabled value to true
filter is the filter the jail will use should exist in /etc/fail2ban/filter.d
logpath defines a logfile to the specific service jail
Example: (enable ssh jail for port 22 (default ssh port))
Restart fail2ban service to make use of your customized configuration
While Fail2ban helps reduce rate of invalid logins, it does not eliminate the risk of weak password authentication. I'd recommend using public key authentication (described in SSH Lockdown above).