4. Prepare the server

by Double Bastion - Updated April 7, 2023

After you sign up for the VPS, cloud server or dedicated server, you will receive an email with your root password, which you will use to log in to your server via SSH. Some hosting providers, like Linode, let you set your root password in your client account, on their website.

First of all, you should connect to your remote server and change the root password.

If you run Linux on your desktop/laptop (which we recommend), you can connect to the remote server with the terminal, by running:

ssh root@123.123.123.123

Replace 123.123.123.123 with the public IP of your remote server. You will be asked to enter your root password, and then, since this is the first time you connect to the remote server, you will be asked if you accept its host key. You should type yes and then press Enter.

Once connected to your remote server, change the root password with:

passwd

You’ll be asked to enter the new password twice. The new password should be a mixture of about 18 characters: uppercase and lowercase letters, numbers and symbols.

4.1. Add a new regular user to log in with, instead of root

Add a new user tom with /home/tom as home folder (replace tom with your desired name):

adduser tom

Install sudo:

apt-get install sudo

Add user tom to the sudo group:

nano /etc/sudoers

Search for the line:

root ALL=(ALL:ALL) ALL

below it add the following line:

tom ALL=(ALL:ALL) ALL

(replace tom with your chosen username)

4.2. Disable root login

First make a copy of the original /etc/ssh/sshd_config file:

cp /etc/ssh/sshd_config /etc/ssh/sshd_config_orig

Open the /etc/ssh/sshd_config file:

nano /etc/ssh/sshd_config

Change PermitRootLogin to no:

PermitRootLogin no

4.3. Change the default SSH port

While you have the /etc/ssh/sshd_config file open, change the default SSH port, which is 22 to a different port, like 6283, by editing the Port parameter like this:

Port 6283

Change the LogLevel parameter to VERBOSE, since it’s necessary for fail2ban to intercept brute-force attacks. Make it look like this:

LogLevel VERBOSE

If you want sshd to use both IPv4 and IPv6 you don’t have to do anything, because it uses both protocols by default. Yet it’s recommended to configure SSH to use only the IPv4 protocol, to increase security. To do that, edit the AddressFamily parameter as follows:

AddressFamily inet

If you had wanted to configure sshd to use only IPv6 you would have added the directive AddressFamily inet6 instead.

Then, for all the above changes to take effect, reboot:

reboot

After the reboot, log in again, this time by using the new SSH port and the newly added user with SSH access, since you can no longer log in as root.

4.4. Check IP reputation

Although in general, IPs of newly rented servers have good reputation, the first thing you should do after renting a server is to check its IP against the main public blacklists, by using this online tool: https://mxtoolbox.com/blacklists.aspx

You can also check if the IP of your server has been reported for malicious activities, on https://www.abuseipdb.com

If you find that your IP has been included on public blacklists or on abuseipdb.com, you should follow the steps described in the IP reputation chapter to delist your IP.

4.5. Configure the network interface

If your hosting provider offers specific information on how to configure your network interface on their official website, then follow their documentation. Otherwise, follow the steps from below.

First, update the package list and upgrade all the installed packages to their last version:

apt-get update
apt-get dist-upgrade

Then install net-tools:

apt-get install net-tools

Then run ifconfig to get the netmask and the broadcast address:

ifconfig

Sample output:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 123.123.123.123  netmask 255.255.255.0  broadcast 123.123.123.255
        inet6 fe80::5054:ff:fe95:7016  prefixlen 64  scopeid 0x20<link>
        inet6 2a04:9dc0:0:4:5054:ff:fe95:7016  prefixlen 64  scopeid 0x0<global>

Then find the default gateway:

route -n

Sample output:

Kernel IP routing table
Destination      Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0          123.123.123.1   0.0.0.0         UG    0      0        0 eth0
123.123.123.1    0.0.0.0         255.255.255.255 UH    0      0        0 eth0

The IP listed next to 0.0.0.0, namely 123.123.123.1 in this case, is the default gateway. Write down the interface name. Here it’s eth0, but it can be different.

Then make a backup copy of the /etc/network/interfaces file and open it for editing:

cd /etc/network
cp interfaces interfaces_orig
nano interfaces

Change the content of this file to make it look like this:

auto lo
iface lo inet loopback

auto eth0
# IPv4 configuration
iface eth0 inet static
address 123.123.123.123
netmask 255.255.255.0
gateway 123.123.123.1
broadcast 123.123.123.255

# IPv6 configuration
iface eth0 inet6 static
address 2b03:8df0:708::a2b4:ef4d
netmask 64
gateway 2b03:8df0:708::1
up /sbin/ifconfig eth0 inet6 add 2b03:8df0:f401:b5e2::/64
up /sbin/ifconfig eth0 inet6 add 2b03:8df0:f401:b5e2::1/64

Replace eth0 with the name of your network interface, replace 123.123.123.123 with your IPv4 address, replace 255.255.255.0 with your netmask, replace 123.123.123.1 with your default gateway address, replace 123.123.123.255 with your broadcast address, replace 2b03:8df0:708::a2b4:ef4d with your primary IPv6 address and 2b03:8df0:708::1 with your IPv6 gateway. You should be able to find these two IPv6 addresses in your client account, on your hosting provider’s website.

The two lines starting with up /sbin/ifconfig assume that your hosting provider has allocated the 2b03:8df0:f401:b5e2::/64 subnet to your machine. If your client account, on your hosting provider’s website, doesn’t mention the 2b03:8df0:f401:b5e2::/64 subnet, or it mentions a smaller subnet, such as 2b03:8df0:f401:b5e2::1/128, which means only one IPv6 address, you should open a support ticket and ask your provider to allocate a /64 subnet to your machine because you need it to be able to send emails using IPv6. If you don’t have a /64 subnet and you try to send emails using IPv6, your emails can get rejected, since spamhaus.org blacklists an entire /64 subnet when one IP in that range sends spam. So, you need to control an entire /64 range if you don’t want your IPv6 address to be blacklisted for what other neighboring IPs do.If your hosting provider refuses to allocate a /64 subnet, you should disable IPv6 connectivity for your mail server, as explained in the Edit main.cf chapter. Therefore, if you have a /64 subnet from the beginning, or if you obtain one by requesting it in a support ticket, you should add the two lines starting with up /sbin/ifconfig , as presented above. The two lines assign to your server a public IPv6 address (different from the primary IPv6 address), from the /64 range that is at your disposal. Of course, instead of 2b03:8df0:f401:b5e2::1 you can choose 2b03:8df0:f401:b5e2::2 or 2b03:8df0:f401:b5e2::ab12 or whatever address you like, in the allocated /64 range. You can add other IPv6 addresses in the same manner, by appending similar lines.

If you acquired an additional IPv4 address from your hosting provider, you should add the following block below the blocks presented above:

# Additional IP configuration
auto eth0:0
iface eth0:0 inet static
address 130.130.130.130
netmask 255.255.255.0
broadcast 130.130.130.255

Replace 130.130.130.130 with your additional IPv4 address, replace 255.255.255.0 with your netmask, which will be the same as for the primary IPv4 address, replace 130.130.130.255 with your broadcast address, which will have the same structure as that of your primary IPv4 address, and replace eth0 with the name of your network interface. For a third IPv4 address you will add the interface eth0:1 and so on. Multiple IPv4 addresses can be used if you have reasons to serve different websites or applications over different IPs. However, any additional IPv4 address costs and in general you won’t need more than one.

Then open the /etc/resolv.conf file for editing:

nano /etc/resolv.conf

This file lists the default DNS servers used by your server when searching for online resources. If this file contains the IPs of some nameservers offered by your hosting provider, you should leave the file as it is. If, on the other hand, you find here Google’s DNS servers (8.8.8.8, 8.8.4.4, 2001:4860:4860::8888, 2001:4860:4860::8844), you should definitely replace them by adding # in front of each line, then adding the following lines, which mention OpenDNS’ DNS servers:

nameserver 208.67.222.222
nameserver 208.67.220.220
nameserver 2620:119:35::35
nameserver 2620:119:53::53

If you use a Linode server, please note that if you don’t want your network configurations described above to be overwritten on reboot, you will have to disable ‘Network Helper’ and ‘Auto-configure networking’ in your Linode client account, as described here.

4.6. Disable systemd networking

Since new versions of systemd have networking capabilities, it can happen that after a routine systemd upgrade followed by a reboot, you will loose SSH access to your server because of some automatic network configuration changes made by systemd. To avoid this situation, you should disable the networking capabilities of systemd, and use the ‘classic’ Debian networking. To disable systemd networking just run the following commands:

systemctl stop systemd-networkd.socket systemd-networkd systemd-networkd-wait-online
systemctl disable systemd-networkd.socket systemd-networkd systemd-networkd-wait-online
systemctl disable systemd-resolved.service

4.7. Check the sources.list file and install several useful packages

Open the /etc/apt/sources.list file:

nano /etc/apt/sources.list

This file should have the following content:

deb http://deb.debian.org/debian bullseye main
deb-src http://deb.debian.org/debian bullseye main

deb http://deb.debian.org/debian-security/ bullseye-security main
deb-src http://deb.debian.org/debian-security/ bullseye-security main

deb http://deb.debian.org/debian bullseye-updates main
deb-src http://deb.debian.org/debian bullseye-updates main

Some hosting providers may change this default list, replacing the official URLs for Debian packages with those of their mirrors. However, in spite of the claimed speed benefits of using the URLs of some mirrors, it’s recommened to use the official URLs mentioned above, which provide fast enough downloads. If your /etc/apt/sources.list file looks different from what is shown above, you should first make a copy of the original /etc/apt/sources.list file:

cp /etc/apt/sources.list /etc/apt/sources.list_orig

then replace the content of the /etc/apt/sources.list file with the 6 lines from above.

Update the list of available packages:

apt-get update

Next, install the following useful utilities:

apt-get install dialog apt-utils debian-keyring hdparm lshw less bzip2 zip unzip htop curl build-essential bind9-dnsutils

Also install the kernel headers necessary for compiling software packages. First run the following command to see what kernel header is available for your current Linux kernel:

apt-cache search linux-headers-$(uname -r)

Sample output:

linux-headers-4.19.0-14-amd64 - Header files for Linux 4.19.0-14-amd64

Then install the kernel header that you have found:

apt-get install linux-headers-4.19.0-14-amd64

4.8. Domain hosting strategy

You can host as many websites as you want on your server (obviously, you will have to take into consideration your server’s hardware specifications, an estimate of your website traffic, the number of users simultaneously connected to the hosted applications, when deciding how many websites you will host), but let’s say you want to host 5 websites:

www.example.com

www.secondsite.net

www.thirdsite.info

www.fourthsite.org

www.fifthsite.us

It’s recommended to choose one of the 5 websites as your main website, and its domain as your ‘main domain’. Let’s say you choose www.example.com as your main website. Thus, your main domain will be example.com . You can set mail.example.com as hostname for your server. mail.example.com will also be the fully qualified domain name (FQDN) of the server.

You can set up all the subdomains necessary to access the applications described in this guide, as subdomains of the main domain, example.com, like this:

mail.example.com as subdomain for Roundcube

lists.example.com for phpList

mailman.example.com for Mailman

doli.example.com for Dolibarr

cloud.example.com for Nextcloud

office.example.com for Collabora Online

roundpin.example.com for Roundpin

stats.example.com for Matomo

friendica.example.com for Friendica

forum.example.com for MyBB

4.9. Configure the hosts and the hostname

Make a copy of the original /etc/hosts file:

cp /etc/hosts /etc/hosts_orig

Open the /etc/hosts file:

nano /etc/hosts

Make it look like this:

127.0.0.1         localhost
123.123.123.123   mail.example.com

# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

were 123.123.123.123 is the public IPv4 address of your server and example.com is the main domain hosted on your server.

Also make a copy of and then open the /etc/hostname file:

cp /etc/hostname /etc/hostname_orig
nano /etc/hostname

Make it look like this:

mail.example.com

Next, regenerate the server’s default self-signed SSL certificate, so that it matches the new hostname:

apt-get install ssl-cert
make-ssl-cert generate-default-snakeoil --force-overwrite

Restart the server to make the changes take effect:

reboot

4.10. Increase the swap space if needed

If your server has less than 5 GB of RAM, it’s recommended to have a total swap space of around 2 GB. Usually, servers with 1 GB, 2 GB, 3 GB, 4 GB of RAM are preconfigured by the hosting companies with a swap partition of 500 MB. This is not enough for the sudden increase in memory usage that takes place when ClamAV updates the database of virus definitions. When the freshclam utility updates the virus database, clamav-daemon can get killed by the OOM (out of memory) killer if the server has less than 5 GB of RAM and less than 2 GB of swap space, although ClamAV can function properly with just 2 GB of RAM or less. The increased memory demands are only during updating the virus definitions. If clamav-daemon gets killed during updating the virus definitions, you will notice that you will be able to start clamav-daemon manually again and it will function normally until the next update, when it will get killed by the OOM again. To avoid this situation, if you have a server with less then 5 GB of RAM, you should create a swap space of about 2 GB.

Please note that although in general using the swap memory is to be avoided because it’s slower than the RAM memory and in certain situations it can slow down the system, in this situation, where you use a Debian server with less than 5 GB of RAM, having a swap memory of about 2 GB is a must and it won’t have any negative impact on the speed of the system, as our experience proved. This is because SSD storage is much faster than hard disks and Debian has a mechanism by which it stores in swap the data that is needed by various processes but is used infrequently.

You can easily create a swap file of 2 GB, which has the same effect as a swap partition. To do so run:

fallocate -l 2G /swapfile

You can verify that the correct amount of space has been allocated by running:

ls -lh /swapfile

The output will be similar to:

-rw-r--r-- 1 root root 2.0G Oct 18 12:37 /swapfile

Set the right permissions, so that the file will be accessible to root only:

chmod 600 /swapfile

Next, mark the file as swap space by running:

mkswap /swapfile

Enable the swap file:

swapon /swapfile

Now, if you run:

swapon --show

The output will be similar to the following:

NAME      TYPE      SIZE   USED PRIO
/dev/sda2 partition 512M 256.9M   -2
/swapfile file        2G     0B   -3

So, apart from the preconfigured swap partition of 512 MB, there is a swap file of 2 GB.

To make the changes persist after reboot, you have to add the swap file to the /etc/fstab file. First make a backup copy of /etc/fstab:

cp /etc/fstab /etc/fstab_orig

Then open /etc/fstab for editing:

nano /etc/fstab

At the bottom of this file add the following line:

/swapfile swap swap defaults 0 0

Please note that /swapfile none swap defaults 0 0 will also work, because if the filesystem type is swap, the system will ignore the mountpoint field.

If you ever want to remove the swap file in order to create a larger one or for other reasons, you will have to first disable it with:

swapoff /swapfile

Then remove the file with:

rm /swapfile

Then remove the corresponding line (/swapfile swap swap defaults 0 0) from the /etc/fstab file.

4.11. Create the backups directory

You will need a directory to store all the backup archives that you will create before upgrading applications, as well as the periodic backups. Create that directory now by running:

mkdir /var/bm_archives

4.12. Adjust the server clock, if needed

To see if the server has the right time and time zone, run:

date

The right time and time zone are those of the physical location of the server. If you find a different time and time zone, or if you want it to be different, in order to match your physical location, you can change the time and time zone of the server and make the change persistent after reboot, even if you use a VPS and the host physical machine of the VPS may have a different time and time zone than the VPS.

The easiest way to set the time and time zone for a server is to use the tzdata utility. Run:

dpkg-reconfigure tzdata

You will see the following screen:

First choose the continent, by using the up and down arrow keys to select it, then pressing Enter. In the next screen select the city of the time zone (eg: London, Madrid, Paris, Berlin, etc.) and press Enter to set up the time zone. You can check that the server has the right time set up by running again the date command. This configuration will persist after reboot.

Restart the rsyslog service to make the syslog daemon use the new time zone:

systemctl restart rsyslog

4.13. Enable different colors for files and folders on your Debian server

As explained before, you shouldn’t connect to a remote server via SSH as root. Nearly all the brute-force attacks will suppose the user is root. That is why the root login should be disabled. However, after you connect as a regular user, you should switch to the root user (by running su - then entering the root password), so as to have all the rights and be able to do anything you need, without loosing time writing sudo in front of every command. Good quality Linux programs are designed so that even if you install them as root, they will run under special users (like the user postfix for Postfix), and not as root; they will run as root only if that will be really necessary. Therefore, installing good qulity programs, such as those presented in this guide, as root, as the only user running commands on the server, won’t decrease the security of the system.

It is very useful to be able to distinguish between files and folders, and between different types of files, when seeing the content of a folder in command line. Unfortunately, a minimal installation of Debian doesn’t offer distinct colors for different types of files and for folders by default. They are all listed in the same color and you are left to wonder which are files and which are folders. To see the folders and files of your remote Debian server in different colors, while connected to your server via SSH, do the following on the remote server:

First make a copy of the original /root/.bashrc file:

cd /root
cp .bashrc .bashrc_orig

Delete all the content in this file:

cat /dev/null > .bashrc

Open the file:

nano .bashrc

Add the following content inside it:

# ~/.bashrc: executed by bash(1) for non-login shells.

# Note: PS1 and umask are already set in /etc/profile. You should not
# need this unless you want different defaults for root.
# PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ '
# umask 022

# You may uncomment the following lines if you want `ls' to be colorized:
# export LS_OPTIONS='--color=auto'
# eval "`dircolors`"
# alias ls='ls $LS_OPTIONS'
# alias ll='ls $LS_OPTIONS -l'
# alias l='ls $LS_OPTIONS -lA'
#
# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'

export PS1="\[$(tput setaf 1)\]\u\[$(tput setaf 3)\]@\[$(tput setaf 6)\]\h \[$(tput setaf 3)\]\w \[$(tput setaf 5)\]\\$ \[$(tput sgr0)\]"

umask 022

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

# You may uncomment the following lines if you want `ls' to be colorized:
export LS_OPTIONS='--color=auto'
eval `dircolors`
alias ls='ls $LS_OPTIONS'
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -la'
alias ..='cd ..'

# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'

if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

Before restarting the server to apply the changes, you may want to also disable another problematic behavior: while connected via SSH to your remote server using the terminal, if you paste text in the terminal, the pasted text will appear as selected. This will decrease readability and it can be annoying. To disable this behavior, first make a copy of the original /etc/inputrc file:

cp /etc/inputrc /etc/inputrc_orig

Then open /etc/inputrc for editing:

nano /etc/inputrc

Add the following lines at the end of this file:

# Disable highlighted pasted text in the terminal
set enable-bracketed-paste off

Restart the server:

reboot
You can send your questions and comments to: