Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

Basic configuration of a Debian server

profile picture
Author
Jonas Braun
Published
2019-03-11
Time to read
7 minutes reading time

Introduction

In this tutorial, we will equip a newly created Debian server (Debian 9 Stretch) with a secure base configuration and install Docker.

We will ...

  • create an unprivileged Sudo user
  • prohibit password login
  • lock the root user
  • change the SSH port
  • set up a firewall
  • install Docker and docker-compose
  • give our Sudo user access to Docker

If Docker is not required on the server, this step can of course be omitted.

I have also created a Cloud-Init configuration that allows all the steps we do in this tutorial to be applied automatically when creating a server.

Step 1 - Create Sudo user

Since one of the next steps will prevent us from logging in as root, we first need a new user with whom we can log in and administer the server.

We create the user holu with the following command:

adduser --disabled-password holu

Since we want to deactivate the login with passwords, we do not need a password for our user and therefore deactivate it with the parameter --disabled-password.

The newly created user 'holu' currently has no special permissions. However, since we want to use the user as a replacement for 'root', we will give holu Sudo permissions, allowing this user to execute commands as root using Sudo.

To assign the permissions to the user, we create the file /etc/sudoers.d/90-holu with the following content:

holu ALL=(ALL) NOPASSWD:ALL

Step 2 - Configure SSH

Step 2.1 - SSH server configuration

For additional security, we adjust the configuration of the SSH server. To do this we open /etc/ssh/sshd_config with a text editor of our choice (which of course should fall on vim), delete the contents of the file and insert the configuration below instead. The most important settings are explained below.

Protocol 2
Port 44933
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
SyslogFacility AUTH
LogLevel INFO
PermitRootLogin no
StrictModes yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
AllowUsers holu

Protocol 2 Ensures that the server only accepts connections via secure protocol version 2.

Port 44933 Changing the port does not increase security, but we can bypass most automated login attempts as they usually only use the default port.

PermitRootLogin no Prohibits login as root via SSH.

PasswordAuthentication no Forbids login with passwords. We set this option because the login with a public key is more secure.

PubkeyAuthentication yes Enables authentication using SSH key pairs.

StrictModes yes Prevents the SSH server from starting if certain files have too loose permissions.

AllowUsers holu This option provides a whitelist for all users who are allowed to log in via SSH. We only allow our 'holu' user.

Important: The server or the SSH service must not be restarted before the next steps are completed, otherwise the new configuration will become active, which will lock us out of the server.

Step 2.2 - Creating an SSH key pair

In the previous step we disabled the login with passwords, so we have to use now the only remaining option, authentication with a SSH key pair.

First, we need to generate a key pair on our local machine. If a key pair already exists, this step can of course be skipped.

Users haunted by Windows can, for example, use the PuTTYgen program to create a key pair.

Under GNU/Linux we can create a key pair with the following command.

ssh-keygen \
  -o \
  -a 100 \
  -t ed25519 \
  -f ~/.ssh/id_ed25519 \
  -C "$(whoami)@$(hostname)"

The key pair (consisting of the files id_ed25519 and id_ed25519.pub) should now be located in the local user's home directory under ~/.ssh. The private key (the file without .pub) should be kept safe, similar to a password, and not passed on.

Step 2.3 - Depositing the public key

To be able to authenticate ourselves with our private key, the corresponding public key must be deposited on the server. Therefore we create the file authorized_keys in the SSH directory of the user 'holu' and insert our public key (the contents of id_ed25519.pub) there. We also adjust the file permissions so that nobody but the user 'holu' can access this file (otherwise StrictMode won't let us start the ssh service).

mkdir -p /home/holu/.ssh
vim /home/holu/.ssh/authorized_keys
chmod 600 /home/holu/.ssh/authorized_keys
chown holu:holu /home/holu/.ssh/authorized_keys

Step 2.4 - Activating the new configuration

Now that our key is stored on the server, we can activate the new configuration of the SSH server by restarting the SSH server.

systemctl restart sshd

We should now be able to connect to the server with the 'holu' user via the new SSH port, and authenticate using our SSH key pair.

ssh -p 44933 holu@<your_host>

From here all steps are performed with the user 'holu'.

Step 3 - Firewall setup

To set up a firewall we will use the program 'ufw' (an abstraction of iptables), because the rules can be managed much easier and more comfortable than with iptables directly.

The 'ufw' package is not included in the default Debian installation and can be installed from the package manager.

sudo apt install ufw

We now create a rule that blocks all incoming connections that were not explicitly allowed.

sudo ufw default deny incoming

Before we activate the firewall, we must of course release our SSH port, otherwise we lock ourselves out of the server.

sudo ufw allow 44933/tcp

We can now activate the firewall with the following command.

sudo ufw enable

With the command ufw status all created rules can be listed. This command must also be executed as root.

Step 4 - Docker Installation (Optional)

Step 4.1 - Adding the repository

Since Debian does not provide a recent version of Docker in the official repositories, the repositories of Docker are required to download via the package manager. The Official Documentation describes how to include them.

Step 4.2 - Installation

If the package sources are included, Docker can be installed normally via the package manager.

sudo apt install \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-compose

Step 4.3 - Access to Docker

By default, Docker can only be used as root. In order use Docker (without sudo) the user 'holu' has to be a member of the 'docker' group.

sudo usermod -aG docker holu

Note: Users in the 'docker' group effectively have root privileges. More information can be found here: Docker security | Docker Documentation.

Step 5 - Cloud Init

Some vendors, including Hetzner Cloud, support Cloud-Init for configuring servers directly after creation. The following Cloud-Init configuration will automatically perform all the steps shown in this article.

Variables (marked with <>) must be replaced before using the configuration.

#cloud-config
users:
  - name: <username>
    ssh-authorized_keys:
    - <your ssh public key here>
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups:
      - sudo
      - docker
    shell: /bin/bash
package_upgrade: true
packages:
  - ufw
  - vim
  - apt-transport-https
  - ca-certificates
  - curl
  - gnupg2
  - software-properties-common
runcmd:
  - curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
  - add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
  - apt-get update -y
  - apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose
  - ufw default deny incoming
  - ufw allow <ssh_port>/tcp
  - echo "y" | ufw enable
write_files:
  - path: /etc/ssh/sshd_config
    content: |
      Protocol 2
      Port <ssh_port>
      HostKey /etc/ssh/ssh_host_rsa_key
      HostKey /etc/ssh/ssh_host_ecdsa_key
      HostKey /etc/ssh/ssh_host_ed25519_key
      UsePrivilegeSeparation yes
      KeyRegenerationInterval 3600
      SyslogFacility AUTH
      LogLevel INFO
      PermitRootLogin no
      StrictModes yes
      IgnoreRhosts yes
      RhostsRSAAuthentication no
      HostbasedAuthentication no
      PubkeyAuthentication yes
      PasswordAuthentication no
      ChallengeResponseAuthentication no
      UsePAM yes
      X11Forwarding no
      PrintMotd no
      AcceptEnv LANG LC_*
      Subsystem	sftp	/usr/lib/openssh/sftp-server
      AllowUsers <username>

Conclusion

Ready! We now have a Debian server with a solid base configuration.

Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue

Discover our

Dedicated Servers

Configure your dream server. Top performance with an excellent connection at an unbeatable price!

Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more