Initial Server Setup Guide — Linux Hardening Basics
A freshly installed Linux server is like a house with the front door unlocked. This guide walks through the essential hardening steps every Linux server needs before going into production — SSH key authentication, firewall configuration, fail2ban, and non-root user management.
What You’ll Learn
By the end of this tutorial, you’ll be able to provision a new Linux server, create a non-root sudo user, configure SSH key-based authentication, set up UFW firewall rules, install and configure fail2ban for brute-force protection, and apply basic security hardening.
Why Server Hardening Matters
Unsecured servers are scanned by bots within minutes of going online. According to industry data, an unprotected SSH server on the public internet receives thousands of login attempts per day. A single compromised server can lead to data breaches, ransomware, or becoming part of a botnet. At DodaTech, Durga Antivirus Pro uses hardened Linux servers to process threat intelligence — a compromised server would expose sensitive security data.
Server Setup Learning Path
flowchart LR
A[Linux Basics] --> B[Server Setup]
B --> C[Essential Commands]
C --> D[System Administration]
D --> E[Package Management]
B --> F{You Are Here}
style F fill:#f90,color:#fff
Step 1: Connect to Your Server
When you first provision a server from a cloud provider (AWS, Linode, DigitalOcean), you’ll receive an IP address and a root password or initial SSH key.
# Connect as root using password
ssh root@203.0.113.10If using an SSH key already configured by your provider:
# Connect using the private key file
ssh -i ~/.ssh/id_rsa root@203.0.113.10Step 2: Create a Non-Root User
Running commands as root is dangerous. Create a regular user with sudo privileges:
# Create a new user
adduser alice
# Add the user to the sudo group (Ubuntu/Debian)
usermod -aG sudo alice
# On RHEL/Fedora/CentOS, use wheel instead
# usermod -aG wheel aliceExpected output:
Adding user `alice' ...
Adding new group `alice' (1001) ...
Adding new user `alice' (1001) with group `alice' ...
Creating home directory `/home/alice' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfullyNow disconnect and test the new user:
# Exit root session, then reconnect as new user
ssh alice@203.0.113.10Step 3: Configure SSH Key Authentication
Password-based SSH is vulnerable to brute-force attacks. SSH keys are cryptographically secure and more convenient.
# On your LOCAL machine, generate an SSH key pair (if you don't have one)
ssh-keygen -t ed25519 -C "alice@laptop"Expected output:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/you/.ssh/id_ed25519
Your public key has been saved in /home/you/.ssh/id_ed25519.pubCopy the public key to the server:
# Using ssh-copy-id (simplest method)
ssh-copy-id alice@203.0.113.10
# Alternative: manual copy
# cat ~/.ssh/id_ed25519.pub | ssh alice@203.0.113.10 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"Test that key authentication works:
ssh alice@203.0.113.10If it connects without asking for a password, key authentication is working.
Step 4: Disable Password Authentication and Root Login
Edit the SSH daemon configuration:
sudo nano /etc/ssh/sshd_configFind and change these lines:
# Disable root login
PermitRootLogin no
# Disable password authentication
PasswordAuthentication no
# Only allow key authentication
PubkeyAuthentication yes
# Optional: change SSH port (security through obscurity)
Port 2222Apply the changes:
sudo systemctl restart sshdWarning: Keep your current SSH session open while testing a new connection. If you make a mistake (like disabling keys before testing them), you’ll lock yourself out. Always verify access in a second terminal before closing the first.
Step 5: Configure the Firewall (UFW)
UFW (Uncomplicated Firewall) provides a simple interface to iptables.
# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (change port if you modified sshd_config)
sudo ufw allow 22/tcp
# If you changed SSH to port 2222:
# sudo ufw allow 2222/tcp
# Allow web traffic if running a web server
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable the firewall
sudo ufw enableExpected output:
Firewall is active and enabled on system startupCheck the status:
sudo ufw status verboseExpected output:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)Step 6: Install and Configure fail2ban
fail2ban scans log files for repeated failed login attempts and temporarily bans the offending IP.
sudo apt update && sudo apt install fail2ban -yCreate a local configuration file:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.localAdd or modify these settings:
[DEFAULT]
# Ban IP after 5 failed attempts
maxretry = 5
# Ban for 10 minutes
bantime = 10m
# Find failures within 10 minute window
findtime = 10m
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
# Ban for 1 hour for SSH specifically
bantime = 1hStart and enable fail2ban:
sudo systemctl enable --now fail2banCheck its status:
sudo fail2ban-client status sshdExpected output:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:Step 7: Automatic Security Updates
Enable automatic security updates to receive critical patches without manual intervention:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgradesSelect “Yes” when prompted. This configures the system to install security updates automatically.
Common Server Setup Mistakes
1. Locking Yourself Out Before Testing
Always keep your original SSH session active while testing a new connection. If the new connection fails, you can fix the configuration without needing physical console access.
2. Using Weak SSH Keys
RSA keys shorter than 2048 bits are vulnerable. Use Ed25519 keys (ssh-keygen -t ed25519) — they’re more secure, faster, and produce shorter key strings than RSA.
3. Opening Too Many Firewall Ports
Only expose the ports your application needs. Every open port is an attack surface. If you’re not running a web server, don’t open port 80 or 443.
4. Skipping fail2ban Configuration
Many admins install fail2ban but use default settings. The default bantime is often too short (10 minutes). For SSH, consider a 1-hour or permanent ban after repeated failures.
5. Not Configuring Automatic Updates
Manual patching is unreliable. Systems running unpatched software are the #1 target for automated exploits. Use unattended-upgrades or equivalent.
6. Using Port Knocking Instead of Proper Security
Port knocking (hiding SSH behind a sequence of connection attempts) adds complexity without real security. Focus on key auth, firewall rules, and fail2ban instead.
7. Forgetting to Secure the Root User Even After Disabling Root Login
Even with PermitRootLogin no, the root account exists. Ensure root has a strong password and that /etc/ssh/sshd_config has AllowUsers alice to restrict SSH access to specific users.
Practice Questions
1. Why should you disable root SSH login?
Root has unlimited privileges. If an attacker compromises the root account, they have full control. By logging in as a regular user and using sudo, you add an audit trail and limit the damage from a compromised credential.
2. What does the command ssh-keygen -t ed25519 do?
It generates a new SSH key pair using the Ed25519 algorithm. Ed25519 offers strong security, excellent performance, and compact key sizes compared to RSA.
3. What is the difference between ufw allow 22/tcp and ufw enable?
ufw allow 22/tcp creates a rule allowing SSH traffic on port 22. ufw enable activates the firewall and applies all rules. Rules can be defined before or after enabling the firewall.
4. How does fail2ban protect your server?
fail2ban monitors log files (like /var/log/auth.log) for repeated failed authentication attempts. When a threshold is exceeded, it adds a temporary iptables rule to block the attacker’s IP address.
5. Challenge: Write a script that checks whether fail2ban is running and, if not, starts it and sends a notification.
Answer: systemctl is-active --quiet fail2ban || sudo systemctl start fail2ban && echo "fail2ban started" | mail -s "Alert" admin@example.com
Mini Project: Server Hardening Audit Script
Create a script that checks the hardening status of your server:
#!/bin/bash
# hardening_audit.sh — Check server security posture
echo "=== Server Hardening Audit ==="
# Check SSH root login
if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config 2>/dev/null; then
echo "[PASS] Root SSH login is disabled"
else
echo "[FAIL] Root SSH login is enabled or not explicitly denied"
fi
# Check password authentication
if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config 2>/dev/null; then
echo "[PASS] Password authentication is disabled"
else
echo "[FAIL] Password authentication is enabled"
fi
# Check UFW status
if ufw status | grep -q "Status: active"; then
echo "[PASS] UFW firewall is active"
else
echo "[FAIL] UFW firewall is not active"
fi
# Check fail2ban
if systemctl is-active --quiet fail2ban; then
echo "[PASS] fail2ban is running"
else
echo "[FAIL] fail2ban is not running"
fi
# Check unattended-upgrades
if dpkg -l unattended-upgrades 2>/dev/null | grep -q "^ii"; then
echo "[PASS] unattended-upgrades is installed"
else
echo "[FAIL] unattended-upgrades is not installed"
fi
echo "=== Audit Complete ==="Save as hardening_audit.sh, make it executable (chmod +x hardening_audit.sh), and run it with sudo ./hardening_audit.sh.
Expected output:
=== Server Hardening Audit ===
[PASS] Root SSH login is disabled
[PASS] Password authentication is disabled
[PASS] UFW firewall is active
[PASS] fail2ban is running
[PASS] unattended-upgrades is installed
=== Audit Complete ===FAQ
What’s Next
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro