Essential security configurations for your VPS.
Edit /etc/ssh/sshd_config:
# Disable root login
PermitRootLogin no
# Disable password authentication (use SSH keys only)
PasswordAuthentication no
# Limit SSH to specific users
AllowUsers deploy
# Change default port (optional)
Port 2222Restart SSH:
sudo systemctl restart sshd# Install UFW
sudo apt install ufw
# Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (use your port if changed)
sudo ufw allow 22/tcp
# Allow HTTP/HTTPS for Traefik
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable firewall
sudo ufw enable
# Check status
sudo ufw status verbose# Install
sudo apt install fail2ban
# Create local config
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.localEdit /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600# Restart and enable
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
# Check banned IPs
sudo fail2ban-client status sshd# Install unattended-upgrades
sudo apt install unattended-upgrades
# Enable automatic updates
sudo dpkg-reconfigure -plow unattended-upgradesAlways set memory limits in docker-compose:
services:
app:
mem_limit: 512m
mem_reservation: 128mIn Dockerfile:
RUN adduser --disabled-password --gecos '' appuser
USER appuserservices:
app:
read_only: true
tmpfs:
- /tmpservices:
app:
security_opt:
- no-new-privileges:true- SSL/TLS: Full (strict) if using valid origin cert
- Always Use HTTPS: ON
- Automatic HTTPS Rewrites: ON
- Minimum TLS Version: 1.2
- Opportunistic Encryption: ON
Block direct IP access (only allow Cloudflare IPs):
For admin panels or monitoring dashboards:
# Generate password hash
docker run --rm httpd:alpine htpasswd -nb username 'password' | sed 's/\$/\$\$/g'Add to Traefik labels:
labels:
- "traefik.http.routers.app.middlewares=app-auth"
- "traefik.http.middlewares.app-auth.basicauth.users=username:$$apr1$$hash$$here"- Never commit
.envfiles to git - Use
.env.examplewith placeholder values - Set restrictive permissions:
chmod 600 .env
# Update system packages
sudo apt update && sudo apt upgrade -y
# Update Docker images
docker compose pull
docker compose up -d
# Clean unused Docker resources
docker system prune -af
# Check for security updates
sudo apt list --upgradable- SSH key authentication only
- Firewall configured (UFW)
- Fail2Ban installed
- Automatic updates enabled
- Docker resource limits set
- Cloudflare SSL configured
- Sensitive services protected with Basic Auth
- Environment files not in git
- Regular update schedule