Deploying a self-hosted environment on a fresh Linux instance requires establishing a secure baseline before you start spinning up web services or databases. A naked Ubuntu server exposed to the public internet is vulnerable to automated scanning and brute-force attacks within minutes of deployment.
Read, Understand, and Apply Selectively
Please read this entire guide carefully before executing commands. Take the time to understand what each phase does, and only apply the configurations required for your specific architecture. Some steps (like strict cloud-provider rules or swap memory) may not be necessary for every environment. If a step doesn't fit your use case, skip it.
This guide establishes a chronological, production-ready DevSecOps baseline from the moment you first SSH into your new virtual machine.
Phase 1: Initial System Provisioning
Before configuring any services, you must ensure the base operating system is up-to-date and accurately tracking time. A fresh instance will likely have pending security patches.
1.1 System Update and Upgrade
Run a full system update and upgrade:
sudo apt update && sudo apt upgrade -y
Kernel Updates
Depending on the kernel updates, you may be prompted to restart certain services. It is generally safe to select the default options and press Enter.
1.2 Set System Timezone
Accurate system time is critical for security tools (like Fail2ban) to read log timestamps properly. Set your server to your local timezone (e.g., UTC or Asia/Kolkata):
sudo timedatectl set-timezone UTC
Phase 2: Core Security & Firewall Setup
Relying on raw iptables directly is dangerous—flushing them can result in an immediate SSH lockout. UFW (Uncomplicated Firewall) provides a safe abstraction layer, while Fail2ban prevents brute-force attacks.
2.1 Install & Automate Security Packages
First, install UFW, Fail2ban, and the automatic upgrade utility:
sudo apt install ufw fail2ban unattended-upgrades -y
Next, configure the system to actually execute those upgrades automatically in the background. Open the configuration file:
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
Paste the following two lines into the file, then save and exit (Ctrl+O, Enter, Ctrl+X):
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
2.2 UFW and Port Management
Warning
SSH Lockout
You MUST explicitly allow OpenSSH before enabling UFW, or your active session will be immediately severed.
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Infrastructure Allowances
sudo ufw allow OpenSSH
# Add other necessary ports here later, e.g., sudo ufw allow 80,443/tcp for web servers
sudo ufw enable
[!info] Optional: Strict Cloud Providers
Some cloud providers (like Oracle Cloud) enforce underlying iptables rules that can block web traffic even if UFW allows it. If you plan to host web applications and encounter blockages, run this to explicitly force ports 80 and 443 open:
sudo iptables -I INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
2.3 Fail2ban Integration
Force Fail2ban to utilize UFW instead of raw iptables to prevent firewall rule conflicts. Open a new local configuration file:
sudo nano /etc/fail2ban/jail.local
Paste the following configuration into the file, then save and exit:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
banaction = ufw
banaction_allports = ufw
[sshd]
enabled = true
backend = systemd
Enable and start the service:
sudo systemctl enable --now fail2ban
2.4 Disable SSH Password Authentication
Once you have verified that you can log into the server securely using your SSH key, you must disable password authentication. This renders brute-force dictionary attacks mathematically impossible.
Open the main SSH configuration file:
sudo nano /etc/ssh/sshd_config
Scroll through the file and look for these two settings. You may need to remove the # symbol at the start of the line to uncomment them, and ensure both are set to no:
PasswordAuthentication no
PermitRootLogin no
Save and exit the file. Then, restart the SSH service to apply the new rules:
sudo systemctl restart ssh
Phase 3: System Stability (Swap Memory)
Running memory-intensive applications can cause Out-Of-Memory (OOM) crashes on servers with limited RAM. Creating a dedicated swap file prevents catastrophic failures when your system memory maxes out by utilizing disk space as a safety net.
Create and mount an 8GB swap file (adjust the size based on your storage capacity):
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Top comments (0)