The first hour on a new server: a hardening checklist

Step-by-step guide to securing a fresh Linux server: creating a non-root user, configuring SSH with keys, UFW firewall, system updates, and fail2ban — all in 60 minutes.

6 min Updated 15 Aug 2026

Buying a new server is exciting, but if you don't think about server hardening from the very first moment, you'll likely see failed logins and intrusion attempts in the logs within a few hours. Automated internet scanners are constantly searching for open port 22 and weak passwords. In this article, we've prepared a practical, timed checklist for the first 60 minutes after your server is delivered (for Debian/Ubuntu-based distributions). Goal: to reach a state where your server cannot be compromised with a password, unnecessary ports are closed, and basic intrusion detection tools are active.

Step One: Full System Update (5 minutes)

Before anything else, update the software repositories and upgrade installed packages. A freshly delivered server may be several weeks behind on the latest security updates.

sudo apt update
sudo apt upgrade -y
sudo apt autoremove -y

If a new kernel was installed, reboot the server once after completing the entire checklist. Put regular updates (e.g., weekly) on your calendar; this is the simplest and most cost-effective layer of defense.

Step Two: Create a Non-root User and Enable sudo (10 minutes)

Working with the root account is a huge risk: any typo or malicious script has full system access. Instead, create a regular user and grant it sudo access.

  1. Log in as root and create a new user:
adduser deploy
usermod -aG sudo deploy
  1. Test logging out and back in with the new user:
exit
ssh deploy@your_server_ip
  1. From now on, always log in as deploy and only use sudo for administrative commands.

Common mistake: Forgetting to test logging in with the new user before disabling root access. If you later configure SSH to reject root and the new user doesn't have a correct password, you'll effectively lock yourself out of the server. Always keep a second terminal open before cutting off root access.

Step Three: Configure SSH with Public Key (15 minutes)

Passwords, even strong ones, are vulnerable to brute-force attacks. SSH keys (public/private key pairs) provide much higher security and enable passwordless login.

Generate a Key on Your Local System

Run this command on your laptop or computer (not on the server):

ssh-keygen -t ed25519 -C "deploy@my-server"

The ed25519 key is more secure and faster than RSA. If you have an older operating system that doesn't support ed25519, use ssh-keygen -t rsa -b 4096 instead.

Copy the Key to the Server

ssh-copy-id deploy@your_server_ip

This command adds the public key to the ~/.ssh/authorized_keys file for the deploy user. If you don't have ssh-copy-id, do it manually:

cat ~/.ssh/id_ed25519.pub | ssh deploy@your_server_ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Tighten the sshd_config File

Edit the /etc/ssh/sshd_config file:

sudo nano /etc/ssh/sshd_config

Set these values and then restart the service:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowUsers deploy
sudo systemctl restart sshd

Important note: Before restarting, open a second SSH connection and make sure key-based login works. If an error occurs, don't close the first connection so you can fix the file.

Step Four: Configure UFW Firewall (10 minutes)

Enable the firewall and only leave essential ports open. UFW (Uncomplicated Firewall) is a simple interface on top of iptables and is perfect for this task.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable

If you're installing a web server, also open HTTP and HTTPS ports:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Check the firewall status:

sudo ufw status verbose

The output should look something like this:

Status: active
To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere

Common mistake: Opening extra ports "just in case you'll need them later." Every open port enlarges the attack surface. Only open ports you need right now.

Step Five: Install and Configure fail2ban (15 minutes)

fail2ban monitors system logs and temporarily blocks IPs that fail login multiple times. This tool stops brute-force attacks.

sudo apt install fail2ban -y

Create a local configuration file:

sudo nano /etc/fail2ban/jail.local

Suggested content:

[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log

Enable and restart the service:

sudo systemctl enable fail2ban
sudo systemctl restart fail2ban

To view blocked IPs:

sudo fail2ban-client status sshd

Sample output:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     47
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 3
   |- Total banned:     12
   `- Banned IP list:   185.220.101.34 91.240.118.87 45.155.205.233

You can increase the bantime value to 24h or more. For sensitive servers, maxretry = 3 is more reasonable.

Step Six: Final Review and Testing (5 minutes)

At the end, do a general review to make sure everything works correctly:

  1. From another terminal, test password-based login — it should be rejected.
  2. Test SSH key-based login — it should work without a password.
  3. Scan open ports:
sudo netstat -tulpn | grep LISTEN

Only ports 22, 80, and 443 (plus ports for essential services like MySQL if it's on this server) should be listening.

  1. If the kernel was updated, reboot the server and test key-based login again.

Step Seven: Additional Measures for Better Security

You can add these later, but if you have time, do them now:

  • Enable unattended-upgrades: Automatic installation of security updates:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
  • Change the SSH port: Although it doesn't provide real security, it drastically reduces automated attacks. Change port 22 to, for example, 2222 and apply it in the firewall as well.
  • Install and configure monitoring tools: Such as logwatch for daily email summaries of logs.
  • Disable IPv6 in the firewall: If you don't use IPv6, set IPV6=no in /etc/default/ufw so firewall rules also apply to IPv6.

Conclusion

This 60-minute checklist is the foundation of security for any Linux server. By removing root login, enabling SSH keys, closing unnecessary ports, and installing fail2ban, you dramatically reduce the attack surface. Remember that server hardening is an ongoing process: don't forget regular updates, log reviews, and periodic configuration audits. If you're looking for infrastructure that makes managing these initial settings easier, ServerNet's cloud server services can be a good starting point — but you should follow the principles in this article in any environment.

Finally, an important recommendation: implement these settings on a test server as well to become familiar with the workflow. Mistakes in a test environment cost less than mistakes in production.

Was this page helpful?