🔐
1. SSH Configuration
Primary attack surface on any exposed Linux server
| Checkpoint | Priority | ✓ |
|---|---|---|
Disable root SSH login PermitRootLogin noIn /etc/ssh/sshd_config — prevents brute force attacks on root |
Critical | |
Key-only authentication PasswordAuthentication noDisable SSH passwords, use RSA/Ed25519 keys only |
Critical | |
Change default SSH port Port 2222Reduces automated scans on port 22 |
High | |
Restrict allowed SSH users AllowUsers deployer adminOnly listed users can connect via SSH |
High | |
Inactive session timeout ClientAliveInterval 300 / ClientAliveCountMax 2Disconnects inactive sessions after 10 minutes |
Medium | |
Use Ed25519 keys (not RSA 1024/2048) ssh-keygen -t ed25519 -C "deployer@server"Ed25519 is more secure and faster than RSA |
Medium | |
Disable X11 forwarding X11Forwarding noReduces attack surface |
Info |
🔥
2. Firewall and Network
Restriction of inbound and outbound network access
| Checkpoint | Priority | ✓ |
|---|---|---|
Active firewall (UFW / firewalld / iptables) ufw enable && ufw default deny incomingDefault policy: block everything, allow explicitly |
Critical | |
Open only necessary ports ufw allow 443/tcp && ufw allow 2222/tcp80 (redirect → 443), 443 (HTTPS), SSH port only |
Critical | |
Block direct database access PostgreSQL/MySQL must never be accessible from outside (ports 5432/3306 closed) |
Critical | |
Enable fail2ban apt install fail2ban && systemctl enable fail2banAutomatically blocks IPs after X failed attempts |
High | |
Disable IPv6 if unused net.ipv6.conf.all.disable_ipv6 = 1In /etc/sysctl.conf — reduces attack surface |
Medium | |
Enable UFW connection logging ufw logging onTraceability of connection attempts |
Info |
👤
3. User and Permission Management
Principle of least privilege
| Checkpoint | Priority | ✓ |
|---|---|---|
Disable root account (Linux) passwd -l rootUse sudo instead of direct root |
Critical | |
Create a dedicated deploy user adduser deployer && usermod -aG sudo deployerNever deploy with a personal or root user |
High | |
Passwordless sudo only for required commands deployer ALL=(ALL) NOPASSWD: /bin/systemctl reload nginxLimit NOPASSWD to specific necessary commands only |
High | |
Check for users with UID 0 awk -F: '$3 == 0 {print}' /etc/passwdOnly root should have UID 0 |
High | |
Sensitive file permissions chmod 600 /etc/ssh/sshd_config && chmod 640 /var/log/auth.logConfig files not readable by ordinary users |
Medium | |
Strong password policy apt install libpam-pwqualityMinimum 12 characters, complexity requirements, expiration |
Medium |
🔄
4. Updates and Patches
Most intrusions exploit known unpatched vulnerabilities
| Checkpoint | Priority | ✓ |
|---|---|---|
System up to date at deployment time apt update && apt upgrade -y && apt autoremove -yAlways deploy on a patched OS |
Critical | |
Enable automatic security updates dpkg-reconfigure -plow unattended-upgradesSecurity patches applied automatically |
High | |
Remove unnecessary packages apt-get remove --purge telnet ftp rsh-serverEach installed package is a potential attack surface |
Medium | |
Audit application dependencies (composer audit, npm audit) composer audit && npm auditCVEs in application libraries |
Medium |
🌐
5. Application and Web Security
Nginx, HTTPS, security headers
| Checkpoint | Priority | ✓ |
|---|---|---|
HTTPS mandatory with TLS 1.2+ only ssl_protocols TLSv1.2 TLSv1.3;Disable SSLv3, TLS 1.0 and TLS 1.1 in Nginx/Apache |
Critical | |
HTTP security headers add_header X-Frame-Options "SAMEORIGIN";X-Frame-Options, X-XSS-Protection, X-Content-Type-Options, HSTS, CSP |
Critical | |
Hide web server version server_tokens off;Don't expose Nginx/Apache version to attackers |
High | |
Environment variables — never in code API keys, DB passwords, JWT secrets must be in .env (gitignored) or system environment variables |
Critical | |
.env absent from Git repository echo ".env" >> .gitignore && git rm --cached .envVerify Git history: no secret should have been committed |
Critical | |
Rate limiting on authentication endpoints limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;Brute force prevention on /login, /api/auth |
High | |
APP_DEBUG=false in production Never display stack traces and system information to users |
High |
📊
6. Logs, Audit and Monitoring
Incident detection and traceability
| Checkpoint | Priority | ✓ |
|---|---|---|
Centralized logs (journald, syslog, ELK...) journalctl -u nginx --since "1 hour ago"Application, system and security logs centralized and retained ≥ 90 days |
High | |
Monitor failed SSH connections grep "Failed password" /var/log/auth.log | tail -20Alerts on ≥ 10 attempts from the same IP |
High | |
Uptime and resource consumption alerts CPU > 90%, memory > 85%, disk > 80% → email/Slack notification |
Medium | |
Immutable application audit trail Every sensitive action (create/update/delete data) must be logged with user, timestamp and IP |
Medium | |
Documented incident response plan Who to contact, what actions to take in case of intrusion detection |
Info |
💾
7. Backups and Disaster Recovery
An untested backup is not a backup
| Checkpoint | Priority | ✓ |
|---|---|---|
Automated daily database backups pg_dump dbname | gzip > backup_$(date +%Y%m%d).sql.gzStored outside the production server (S3, another VPS, NAS) |
Critical | |
Backup retention ≥ 30 days Ability to restore a previous version in case of ransomware attack or corruption |
High | |
Monthly restore test Verify that the restore actually works on a test environment |
High | |
Encrypted backups gpg --symmetric --cipher-algo AES256 backup.sql.gzBackups contain sensitive data — encrypt them at rest |
Medium |
