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
Th
en 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