After working with various PaaS solutions for years, I decided to set up a VPS with Contabo for hosting a few personal projects. While nothing particularly sensitive will be hosted there, I still wanted to implement proper security practices from the start.
Even simple hobby projects can become targets for automated attacks or get compromised for cryptocurrency mining. Here's my systematic approach to hardening a fresh Ubuntu VPS, covering the essential security fundamentals.
The Starting Point
Fresh VPS with Ubuntu, an admin
user with sudo privileges, and SSH key authentication already configured during setup. Time to implement proper security measures.
Step 1: SSH Hardening
The default SSH configuration needed immediate attention. Running SSH on the default port 22 makes your server a target for automated scanning tools that constantly probe this port.
sudo nano /etc/ssh/sshd_config
Key changes made:
Port 2222 # Move away from the default port PermitRootLogin no # Disable direct root access PasswordAuthentication no # Enforce key-based authentication PubkeyAuthentication yes # Enable SSH keys MaxAuthTries 3 # Limit failed attempts AllowUsers admin # Restrict user access
Then restart SSHD:
sudo systemctl restart sshd
Important: Always test your SSH configuration in a separate terminal session before closing your current connection. This prevents accidental lockouts. Also, ideally, don't close your connection before Step 2
.
Step 2: Firewall Configuration
Linux's UFW provides straightforward firewall management. The approach is to deny all incoming connections by default, then explicitly allow only necessary services.
# Set restrictive defaults sudo ufw default deny incoming sudo ufw default allow outgoing # Allow essential services sudo ufw allow 2222/tcp # SSH on custom port sudo ufw allow 80/tcp # HTTP sudo ufw allow 443/tcp # HTTPS # Enable firewall sudo ufw enable
Critical note: It's recommended to perform Steps 1 & 2 during one SSH session to avoid locking yourself out of access.
Step 3: Automated Intrusion Prevention with Fail2Ban
Fail2Ban monitors log files and automatically bans IP addresses showing suspicious behavior, such as repeated failed login attempts.
sudo apt install fail2ban
Modern Ubuntu systems use systemd journaling instead of traditional log files, which requires specific configuration:
sudo nano /etc/fail2ban/jail.local
[DEFAULT] bantime = 3600 # Ban duration in seconds findtime = 600 # Time window for counting failures maxretry = 3 # Maximum attempts before ban [sshd] enabled = true port = ssh filter = sshd backend = systemd # Use systemd journal journalmatch = _SYSTEMD_UNIT=ssh.service
After that, restart the service for it to use the updated configuration:
sudo systemctl restart fail2ban
Step 4: Docker Security Configuration
I am a big fan of Docker. I decided to go full docker. It will bring little few more steps but we'll get better security as all services accessible from internet will run in an isolated docker containers.
It also keeps our host machine clean of unecessary installed packages.
Installation is pretty simple and a lot of VPS providers offers fresh install with docker pre-istalled.
When docker is installed create /etc/docker/daemon.json
with following content:
{ "live-restore": true, "userland-proxy": false, "no-new-privileges": true, "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }
The no-new-privileges
setting is particularly important as it prevents containers from escalating their privileges during runtime, blocking a common attack vector.
As before, don't forget to restart the service:
sudo systemctl restart docker
Current Security Status
The VPS now has:
- SSH access secured with custom port and key-only authentication
- Firewall blocking unauthorized connections
- Automated intrusion detection and response
- Hardened Docker daemon configuration
This setup effectively blocks automated attacks and provides a solid security foundation for hosting web applications.
Coming Up in Part 2
The next article will cover:
- Setting up a reverse proxy with Nginx in Docker
- SSL certificate management with Let's Encrypt
- Container security best practices
- System monitoring and maintenance
These foundational security measures provide essential protection while maintaining accessibility for legitimate use.
Top comments (1)
"Since applications run in Docker containers" - well, that's a big and unproven assumption :-) ... but for the rest, yeah nice, some useful tips/guidelines :)