How to Secure Your Linux Server Against Common Attacks
This is a practical, copy-ready hardening checklist for Ubuntu/Debian servers. Apply it from Day 0, verify with simple commands, and wire alerts so you’re never blind.
0) Pre-flight
- Snapshot/backup before changes.
- Ensure out-of-band access (provider console) in case of lockout.
1) System Updates
sudo apt update && sudo apt -y upgrade
sudo apt -y install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
2) Users & SSH
# Create non-root user and add to sudo
sudo adduser deploy && sudo usermod -aG sudo deploy
# SSH keys (local machine)
ssh-keygen -t ed25519 -C "deploy@host"
# Copy pubkey
ssh-copy-id deploy@SERVER
# SSH daemon hardening
sudo nano /etc/ssh/sshd_config
# Port 22 (optionally change)
# PermitRootLogin no
# PasswordAuthentication no
# PubkeyAuthentication yes
# MaxAuthTries 3
sudo systemctl reload ssh
Tip: Keep a second SSH session open when changing auth—test before closing.
3) Firewall (UFW)
sudo apt -y install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enable
sudo ufw status verbose
4) Fail2ban
sudo apt -y install fail2ban
sudo systemctl enable --now fail2ban
# Override jail
sudo tee /etc/fail2ban/jail.local &>/dev/null <<'EOF'
[sshd]
enabled = true
port = ssh
filter = sshd
maxretry = 4
bantime = 1h
findtime = 15m
EOF
sudo systemctl restart fail2ban
5) TLS & Web Security (if serving HTTP)
sudo apt -y install nginx certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# Add security headers in nginx server block:
# add_header X-Frame-Options "DENY" always;
# add_header X-Content-Type-Options "nosniff" always;
# add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# add_header Content-Security-Policy "default-src 'self';" always;
6) Sysctl Hardening (basic)
sudo tee /etc/sysctl.d/99-security.conf &>/dev/null <<'EOF'
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv6.conf.all.accept_redirects = 0
kernel.kptr_restrict = 2
kernel.yama.ptrace_scope = 1
EOF
sudo sysctl --system
7) Services & Packages
# See open listeners
ss -tulpn
# Remove what you don't need
sudo apt -y purge telnet rsh-server rlogin nis
8) Audit & Logging
sudo apt -y install auditd
sudo systemctl enable --now auditd
# Basic checks
sudo journalctl -u ssh -S -24h
sudo fail2ban-client status sshd
9) Backups & Recovery
- Automate encrypted offsite backups (restic/borg).
- Test restores monthly; backups you never try aren’t backups.
10) Monitoring & Alerts
- Uptime + resource: Netdata/Prometheus + node_exporter.
- Security: logwatch, fail2ban email, file integrity (aide).
- Alert to Telegram/Slack via webhook on key events.
11) Containers & Apps
- Rootless Docker/Podman when possible.
- Read-only root FS, drop capabilities, run as non-root user.
- Rotate app secrets and use env files or a vault.
12) Incident Basics
- Isolate host/network segment; preserve volatile data.
- Rotate keys, revoke tokens; rebuild from known-good images.
- Post-mortem: document timeline, patch, automate regression checks.
“Security is a rhythm: harden → observe → patch → repeat.” — redesign.ir
Warning: Changing SSH port alone isn’t security. Treat it as noise reduction, not a control.
Comments
Join the discussion. We keep comments private to your device until moderation tooling ships.