Setting up a new Linux server requires careful attention to configuration and security from the very beginning. This guide walks you through the essential steps, providing concrete code examples and expected outputs to harden your server against common threats.
1. System Update
The first and most fundamental step is ensuring your system has the latest security patches and updates .
Example (Ubuntu/Debian):
sudo apt update && sudo apt upgrade -y
Output:
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
Get:3 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
...
Fetched 15.2 MB in 3s (5,080 kB/s)
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
libcurl4 curl
2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 450 kB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 libcurl4 amd64 7.81.0-1ubuntu1.10 [234 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 curl amd64 7.81.0-1ubuntu1.10 [216 kB]
Fetched 450 kB in 0s (1,125 kB/s)
(Reading database ... 65432 files and directories currently installed.)
Preparing to unpack .../libcurl4_7.81.0-1ubuntu1.10_amd64.deb ...
Unpacking libcurl4:amd64 (7.81.0-1ubuntu1.10) over (7.81.0-1ubuntu1.9) ...
Preparing to unpack .../curl_7.81.0-1ubuntu1.10_amd64.deb ...
Unpacking curl (7.81.0-1ubuntu1.10) over (7.81.0-1ubuntu1.9) ...
Setting up libcurl4:amd64 (7.81.0-1ubuntu1.10) ...
Setting up curl (7.81.0-1ubuntu1.10) ...
Processing triggers for man-db (2.10.2-1) ...
2. Create a Non-Root User with Sudo Privileges
Logging in as the root user directly poses significant security risks. Always create a dedicated user account with sudo
capabilities .
Example:
# Create a new user (replace 'myuser' with your desired username)
sudo adduser myuser
# Add the user to the sudo group
sudo usermod -aG sudo myuser
Output for adduser
:
Adding user `myuser' ...
Adding new group `myuser' (1001) ...
Adding new user `myuser' (1001) with group `myuser' ...
Creating home directory `/home/myuser' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for myuser
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] Y
3. Secure SSH Access
SSH is often the primary target for attackers. Hardening SSH is critical .
a. Generate SSH Key Pair (on your local machine)
# On your local computer
ssh-keygen -t ed25519 -C "your_email@example.com"
Output:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX your_email@example.com
The key's randomart image is:
+--[ED25519 256]--+
| ... |
| . . . |
| . . . |
| . . o |
| . + .S. |
| . = o.o . |
| + * =.o |
| . o.B.+E |
| .o=+*o. |
+----[SHA256]-----+
b. Copy Public Key to Server
# From your local machine, copy the public key to the server
ssh-copy-id myuser@your_server_ip
c. Configure SSH Server
Edit the SSH daemon configuration file.
sudo nano /etc/ssh/sshd_config
Modify or add the following lines:
Port 2222 # Change default SSH port
PermitRootLogin no # Disable root login
PasswordAuthentication no # Disable password login, use keys
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
MaxSessions 2
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers myuser # Restrict SSH access to specific users
Save the file and exit the editor.
d. Restart SSH Service
sudo systemctl restart sshd
Output (checking status):
sudo systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2024-05-18 10:30:00 UTC; 1min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1234 (sshd)
Tasks: 1 (limit: 9487)
Memory: 1.2M
CGroup: /system.slice/ssh.service
└─1234 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
e. Test SSH Connection (from your local machine)
# Connect using the new user and port
ssh -p 2222 myuser@your_server_ip
4. Configure Firewall (UFW)
Implementing a firewall is a key step in securing your server . UFW (Uncomplicated Firewall) provides a user-friendly interface for managing iptables .
a. Install UFW (if not already installed)
sudo apt install ufw -y
b. Set Default Policies
# Deny all incoming connections by default
sudo ufw default deny incoming
# Allow all outgoing connections
sudo ufw default allow outgoing
Output:
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
Default outgoing policy changed to 'allow'
c. Allow Essential Services
# Allow SSH on the new port
sudo ufw allow 2222/tcp
# Example: Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Example: Allow specific IP to access a port (e.g., PostgreSQL from a specific IP)
# sudo ufw allow from 192.168.1.100 to any port 5432
Output for allowing SSH:
Rule added
Rule added (v6)
d. Enable UFW
sudo ufw enable
Output:
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
e. Check Firewall Status
sudo ufw status verbose
Output:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
Rules:
ufw deny in on any
ufw allow out on any
ufw allow 2222/tcp
ufw allow 80/tcp
ufw allow 443/tcp
5. Additional Hardening Steps
a. Remove Unnecessary Software
Reduce the attack surface by removing packages you don’t need .
# List installed packages
dpkg -l
# Remove a package (example)
sudo apt remove --purge package_name
sudo apt autoremove
b. Keep Automatic Updates Enabled (Optional but Recommended)
Configure automatic security updates.
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
c. Monitor System Logs
Regularly check logs for suspicious activity.
# View recent authentication logs
sudo tail -f /var/log/auth.log
# View recent system logs
sudo journalctl -f