Skip to content

Ubuntu — Configuration and Hardening Guide

Complete guide to configure, secure and administer an Ubuntu server.

Overview

Ubuntu is one of the most popular Linux distributions for servers. This documentation covers essential configurations to deploy and harden an Ubuntu server for production.

Whether you deploy on a VPS, a dedicated server, or in the cloud, the first hours after provisioning are critical to establish a secure baseline.

Prerequisites

  • Root or sudo access to an Ubuntu server (22.04 LTS or later)
  • Working SSH connection
  • Basic Linux command-line knowledge

System Configuration

Keyboard Layout

bash
# Launch the keyboard configuration wizard
sudo dpkg-reconfigure keyboard-configuration

# Restart the service
sudo service keyboard-setup restart

# Configure system locales
sudo dpkg-reconfigure locales

System Update

bash
# Update available package lists
sudo apt update

# Upgrade all installed packages
sudo apt upgrade -y

# Clean up obsolete packages
sudo apt autoremove -y

For a full upgrade including new kernels:

bash
sudo apt update
sudo apt full-upgrade -y
sudo apt autoremove -y
sudo apt autoclean
sudo reboot

Warning: A reboot can temporarily interrupt services. Plan this during a maintenance window.

Password Management

bash
# Change the current account password
passwd

# Change another user's password (root required)
sudo passwd username

User Management

Principle of Least Privilege

Using root directly is dangerous. Create a user with limited sudo privileges instead.

Create a New User

bash
# Create a user with a home directory
sudo adduser username

# Alternative with full options
sudo useradd -m -s /bin/bash -G sudo username

Grant Sudo Privileges

bash
# Add the user to the sudo group
sudo usermod -aG sudo username

# Verify group membership
groups username

Disable Root SSH Login

Once the sudo user is created and tested:

bash
# Edit SSH configuration
sudo nano /etc/ssh/sshd_config

# Add or modify this line
# PermitRootLogin no

# Restart SSH
sudo systemctl restart ssh

SSH Hardening

SSH is the main access vector to your server. Hardening it is critical to prevent intrusions.

Changing the SSH Port

Benefits:

  • Reduces automated scan noise (bots)
  • Limits attack surface
  • Cleaner logs (fewer intrusion attempts)

Important: Changing the SSH port is not sufficient protection by itself. It's an additional defense layer, not a replacement for strong authentication (SSH keys) and a firewall.

Configuration for Ubuntu 23.04+

Ubuntu 23.04+ uses systemd socket activation for SSH:

bash
# Check if ssh.socket is used
systemctl status ssh.socket

# Open the socket configuration
sudo nano /lib/systemd/system/ssh.socket
ini
# /lib/systemd/system/ssh.socket
[Socket]
ListenStream=49152
Accept=no

Port choice: Ports 49152–65535 are dynamic/private ports rarely used by other services.

bash
# Reload systemd
sudo systemctl daemon-reload
sudo systemctl restart ssh.service
sudo systemctl status ssh.service

# Verify the new listening port
sudo ss -tlnp | grep ssh

Configure the Firewall

Before closing your current session, allow the new port:

bash
sudo ufw allow 49152/tcp
sudo ufw delete allow 22/tcp
sudo ufw enable
sudo ufw status numbered

CRITICAL: Never close your current SSH session before verifying you can connect on the new port in a second session.

Test Connection

bash
# In a NEW terminal
ssh username@server_ip -p 49152

Additional SSH Configuration

bash
# /etc/ssh/sshd_config

# Disable root login
PermitRootLogin no

# Key-based authentication only
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no

# Disable challenge-response authentication
ChallengeResponseAuthentication no

# Restrict allowed users
AllowUsers username other_user

# Connection timeouts
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2

# Disable X11 forwarding
X11Forwarding no

# Enforce SSH protocol version 2
Protocol 2

# Limit authentication attempts
MaxAuthTries 3
MaxSessions 10
bash
# Test configuration before restarting
sudo sshd -t

# If no errors, restart
sudo systemctl restart ssh

Security Best Practices

  • Update regularly: sudo apt update && sudo apt upgrade at least weekly
  • Use a firewall: UFW or iptables to control inbound/outbound traffic
  • Install Fail2Ban: Automatically ban IPs with repeated failed attempts
  • Enable unattended upgrades: For security patches
  • Monitor logs: /var/log/auth.log for login attempts
  • Back up regularly: Automate backups with cron and rsync

Install Fail2Ban

bash
sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
ini
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 49152
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
bash
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Monitoring and Maintenance

Monitor SSH Connections

bash
# Show recent successful logins
last -a

# Show recent failed login attempts
sudo grep "Failed password" /var/log/auth.log | tail -n 20

# Active SSH sessions
who

# Real-time SSH log monitoring
sudo tail -f /var/log/auth.log

Automatic Updates

bash
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure unattended-upgrades

Post-Installation Checklist

  • System updated (apt update && apt upgrade)
  • Keyboard and locales configured
  • Sudo user created and tested
  • Root SSH login disabled
  • SSH port changed and tested
  • SSH key-based authentication configured
  • Password authentication for SSH disabled
  • UFW firewall configured and active
  • Fail2Ban installed and configured
  • Unattended upgrades enabled
  • Backups configured

Resources