Debian Server Essentials: Setup, Configure, and Hardening Your System

This Guide empowers users to secure and set up Debian servers efficiently, catering to various skill levels.

Debian Server Essentials: Setup, Configure, and Hardening Your System penguin in a server room covered in ice and snow, whole picture made out of green matrix style lines of code, cinematic


Today, we're delving deep into my standard Debian setup. Debian has become my go-to choice for various server projects. I rely on Debian across the board, whether it's running on my Raspberry Pi, inside my LXC containers, or powering my virtual machines (VMs). In fact, even the hypervisor I use, Proxmox, is built on the Debian foundation.

As I'm not a Proxmox expert by any means, I'll steer clear of the hypervisor setup, but that is quite straight forward anyways. I will walk you through my step-by-step process for configuring a fresh Debian server. This methodology applies universally, be it a VM, Raspberry Pi, or LXC container.

I want to make it clear that I'm not a Linux expert or administrator; everything I've learned has been self-taught. The same applies to security practices.

If you happen to identify any issues or have valuable tips and advice, I welcome your input. I'm continually seeking ways to improve, and I'll maintain a change log at the bottom of this article to track any updates and enhancements.

Why Debian Wins my Heart and Server

I had been using Ubuntu as my primary operating system until the beginning of 2023. However, at that point, I encountered some performance issues within my setup that proved quite challenging to debug and identify the culprit. Faced with this predicament, I made the decision to overhaul my system and take the opportunity to explore Debian. I had heard numerous positive remarks about Debian and had come across articles suggesting that it could potentially provide a slight boost in performance, which piqued my interest.

I've always had a penchant for exploring new horizons and technologies. Considering that I'm not a Linux expert, I viewed this transition to Debian as a significant change that offered the perfect chance to learn something new. The allure of mastering a different Linux distribution and broadening my skill set was too enticing to pass up.

Since the complete rebuild of my homelab on Debian and parting ways with Ubuntu, I have experienced no issues and, perhaps subjectively, perceived a bump in performance. However, it's important to be entirely honest here—I lack concrete data to substantiate this perception. After all, running a homelab for several years, constantly tinkering and experimenting, may have introduced some issues. It's entirely plausible that a fresh start on Ubuntu might have yielded similar results. But the allure of Debian's reputation and the joy of embarking on a new learning journey were more than enough to justify the switch.

Embark on Your Debian Journey: A Step-by-Step Installation Guide

To kick off your Debian journey, start by obtaining the official Debian installer. You can either create an installation USB stick for your physical server or load the image directly into Proxmox for your virtualization environment.

Debian Installer

Installing Debian via the Internet

Debian Installer (RPi)

Tested images
This guide is centered around a Proxmox VM setup. Please note that there may be differences or additional steps required when setting up on a Raspberry Pi or LXC container.

Debian Installation

For those who may be unsure about the Debian installation process, I've documented my personal approach with screenshots and compiled it into a helpful video guide. Feel free to adapt the steps to your own needs and preferences. As a personal practice, I start with a straightforward, easily memorable password during the installation, which I then replace with a long, randomly generated password once the system is up and running. This adds an extra layer of security to the setup while keeping the initial installation process user-friendly.

Note as well that the root password is left empty on purpose. This will install sudo and grant our personal user sudo privileges.


Now that we've completed the initial setup, we'll transition to using SSH for all subsequent steps. To begin, you'll need to determine your server's IP address. If you have a DNS (Domain Name System) like I do, you can create a DNS record that points to the server's IP address. This not only simplifies access but also provides a more user-friendly and reliable way to connect to your Debian server.

If you're using a Windows PC and have set up WSL 2 (Windows Subsystem for Linux 2) with a Debian environment, you're in luck. This environment can serve as a powerful tool for managing and connecting to your Debian servers. You can seamlessly use your WSL Debian environment to SSH into your servers, simplifying the process and enhancing your workflow. With this setup, you'll have the best of both worlds, harnessing the flexibility and power of Linux without leaving your Windows environment behind.

First Steps to Server Bliss: Connecting and Initial Configuration

Let's proceed to the next steps to configure the basics of our new server and bolster its security.

Connecting via SSH

As our initial action, we're going to create an SSH key for secure and efficient remote access. This cryptographic key pair enhances both convenience and security. If you've already generated a private key, you can skip this step and proceed to the next stage of our server configuration.

If you need backward compatibility (pre OpenSSH 6.5), then use an RSA key. Otherwise, go for an Ed25519 key, which offers the same (if not better) security and is more efficient.

ssh-keygen -t ed25519 -a 100

-a 100 provides a more secure key with longer key generation time.

ssh-keygen -t rsa -b 4096

When creating your SSH key, you'll notice that most fields are optional, and you can leave them blank to use the standard values. However, it's crucial to note that by doing so, your private key won't be secured with a password. While skipping the password might seem more convenient, it's also less secure. If you choose this option, it's imperative to ensure the physical and digital safety of your private key file. In the event that the key is ever lost or compromised, you should promptly revoke all access granted to that specific key to maintain the integrity of your server's security.

Now it is time to copy the public key onto the server. I made a DNS entry for my server under 'nerdyarticles'. You can use your server name or IP address instead.

ssh-copy-id <YOUR USER>@nerdyarticles

Now we can connect using our private key.

ssh <YOUR USER>@nerdyarticles

Disable root

Our next priority is to enhance server security by prohibiting direct root login. This added layer of protection ensures that the root user won't have the ability to log in directly, which is a recommended practice to bolster your server's defenses.

This step is straightforward and effective. To prevent root login, we'll modify the shell that root uses upon login to point to a non-existent file. A commonly recommended practice is to set the shell to '/bin/nologin'.

sudo nano /etc/passwd

Change Passwords

To elevate our server's security, it's time to change the initial, easy-to-remember password we used for convenience during setup. I personally rely on a password manager to generate and securely store long, randomly generated passwords. This practice not only enhances security but also simplifies password management.


Secure SSH

Now, it's time to reinforce the security of our SSH connection. We'll implement a set of configurations that I've gathered through online research, intended to enhance the security of your SSH setup.

sudo nano /etc/ssh/sshd_config

Let's delve into the configuration file and make the necessary changes or additions to the parameters. I've arranged them in the order they should appear for your convenience

Protocol 2
PermitRootLogin no  
MaxAuthTries 3  
PubkeyAuthentication yes 
PasswordAuthentication no   
PermitEmptyPasswords no  
X11Forwarding no  
ClientAliveInterval 180  
ClientAliveCountMax 3  

Restart the service

sudo systemctl restart sshd

Let us try the connection.

ssh <YOUR USER>@nerdyarticles -p XXXX

Disable IPv6

While there are clear advantages to having IPv6 enabled, I've chosen to disable it for my setup. In the future, I may explore this topic more deeply. It's worth noting that there are differing opinions on whether to leave it enabled, so I encourage you to research and decide based on your unique use case.

sudo nano /etc/sysctl.conf

Add the following to the bottom of the config file.

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.tun0.disable_ipv6 = 1

To put these changes into action and have them take full effect, a reboot is in order.

sudo reboot now

Setting up a Firewall

Our next step involves setting up the Uncomplicated Firewall (UFW) to establish fine-grained control over the ports and services that can be accessed on our server. This configuration ensures that only the ports and services we've explicitly configured are accessible, adding a significant layer of security to our system.

sudo apt install ufw

Since we've disabled IPv6, it makes sense to extend the optimization to UFW by disabling IPv6 rules. This not only streamlines our configuration but also eliminates any duplicated rules.

sudo nano /etc/default/ufw

Change the IPv6 value to false.

Before enabling the firewall, it's crucial to grant access to the SSH service. Neglecting this step could lead to unintentionally locking ourselves out of the server. Therefore, let's ensure SSH access is allowed before we activate the firewall.

sudo ufw allow <PORT YOU CHOSE> comment "SSH service"

Get ready, it's firewall time!

sudo ufw enable

Enhanced Security: Safeguarding with Fail2ban

Continuing our journey, we'll bolster security and vigilance by setting up additional measures and implementing log monitoring. One such tool is 'fail2ban,' which scans server logs for repetitive failed login attempts and subsequently blocks IP addresses engaging in suspicious behavior. This extra layer of defense enhances your server's resistance to potential threats.

sudo apt install fail2ban

Adding Qemu Guest Agent

As I run my VM on Proxmox, I want to make sure the QEMU Guest Agent is installed. This tool plays a critical role in enhancing the interaction between the host and guest systems. It enables various features like graceful shutdowns, improved file system consistency, and provides better insights into the guest's operational state. Ensuring the QEMU Guest Agent's presence contributes to a more efficient and manageable virtualized environment.

Be sure to activate the QEMU Guest Agent option in your Proxmox VM's settings and reboot. The QEMU Guest Agent might already be active. If not, you can install it as follows:

sudo apt install qemu-guest-agent

A reboot might be necessary!

Closing Remarks

To reiterate, I'm a self-taught Linux user and also not a security expert. While I consider this setup quite safe, I strongly advise conducting your own research and taking responsibility for any intrusions or issues.

I sincerely hope that this guide has proven helpful in establishing a secure and reproducible server setup. While I could have embarked on the journey of learning Ansible to streamline this process into one (or more) playbooks, I've found that the commands outlined in this article offer a swift and efficient means of bringing a new server to life, fully configured and ready to roll.

Change Log

  • 20.10.2023: Updated install procedure (no root passwd), removed need to install sudo and change root passwd, added ssh key Ed25519 details, redone IPv6 paragraph
  • 19.10.2023: Initial article based on Debian Proxmox VM