VPS Linux Server Hardening: CIS Practical Guide
The CIS (Center for Internet Security) Benchmark is the industry-standard hardening guideline used by organizations and cloud providers worldwide. This article provides a practical checklist of hardening steps you can implement on any Ubuntu or Debian VPS — from kernel network parameters and user account policies to service auditing and auditd logging. It's ideal for production servers that need stronger security than basic defaults offer.
1. Kernel Network Security (sysctl)
These kernel parameters protect against network-level attacks such as SYN floods, IP spoofing, and ICMP redirects:
sudo nano /etc/sysctl.d/99-hardening.conf
# Prevent IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP redirect (prevent routing manipulation)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Prevent SYN flood attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
# Disable IP source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Hide kernel pointers in dmesg (prevent KASLR bypass)
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
# Restrict ptrace (prevent process snooping)
kernel.yama.ptrace_scope = 1
# Apply immediately
sudo sysctl -p /etc/sysctl.d/99-hardening.conf
2. User Account Security
# Set password policy (requires libpam-pwquality)
sudo apt install libpam-pwquality -y
sudo nano /etc/security/pwquality.conf
# Password requirements
minlen = 12
dcredit = -1 # At least 1 digit
ucredit = -1 # At least 1 uppercase letter
lcredit = -1 # At least 1 lowercase letter
ocredit = -1 # At least 1 special character
maxrepeat = 3 # No more than 3 consecutive identical characters
# Set account lockout after 5 failed login attempts
sudo nano /etc/pam.d/common-auth
# Add this line before other auth rules
auth required pam_faillock.so preauth silent audit deny=5 unlock_time=900
# Lock system accounts without passwords
sudo passwd -l daemon
sudo passwd -l bin
sudo passwd -l sync
# Show users with shell access and UID >= 1000 (real users)
awk -F: '($3 >= 1000) && ($7 != "/usr/sbin/nologin") && ($7 != "/bin/false")' /etc/passwd
3. Disable Unnecessary Services
# List all running services
systemctl list-units --type=service --state=running
# Disable unnecessary services on typical VPS
sudo systemctl disable --now avahi-daemon 2>/dev/null
sudo systemctl disable --now cups 2>/dev/null
sudo systemctl disable --now bluetooth 2>/dev/null
sudo systemctl disable --now isc-dhcp-server 2>/dev/null
sudo systemctl disable --now rpcbind 2>/dev/null
# Check all listening ports
sudo ss -tlnp
4. File System Hardening
# Set noexec, nosuid, nodev flags on /tmp
sudo nano /etc/fstab
# Add options for /tmp
tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev 0 0
# Find unusual SUID/SGID files
find / -xdev \( -perm -4000 -o -perm -2000 \) -type f -print 2>/dev/null | \
grep -v -E "^/(usr|bin|sbin)/"
# Find files with missing owner
find / -xdev \( -nouser -o -nogroup \) -type f -print 2>/dev/null
5. auditd — Audit Logging
auditd logs all important system calls, making it essential for forensics and compliance:
sudo apt install auditd -y
sudo systemctl enable auditd --now
sudo nano /etc/audit/rules.d/hardening.rules
# Log modifications to passwd/sudoers/shadow
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
# Log sudo usage
-w /usr/bin/sudo -p x -k sudo_usage
# Log login/logout events
-w /var/log/lastlog -p wa -k logins
-w /var/run/faillock -p wa -k logins
# Log SSH configuration changes
-w /etc/ssh/sshd_config -p wa -k sshd_config
# Log cron changes
-w /etc/crontab -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
# Load new rules
sudo augenrules --load
sudo systemctl restart auditd
# View recent audit events
sudo ausearch -ts today -i | tail -30
6. Automatic Security Updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
# Configure auto-install of security patches only
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Automatic-Reboot "false"; // Do not reboot automatically
Verify Hardening is Working Correctly
# Verify sysctl parameters are set
sysctl net.ipv4.tcp_syncookies net.ipv4.conf.all.rp_filter kernel.kptr_restrict
# Check that services are disabled
systemctl is-enabled avahi-daemon cups rpcbind 2>/dev/null
# Verify auditd is logging
sudo auditctl -l | head -20
sudo ausearch -k sudoers -ts today 2>/dev/null | head -10
# Run Lynis automated security audit
sudo apt install lynis -y
sudo lynis audit system
Common Issues & Troubleshooting
Error: Cannot login after setting pam_faillock
Your account has been automatically locked. You'll need to unlock it using root or another sudo user:
# Check locked accounts
sudo faillock
# Unlock a specific user
sudo faillock --user username --reset
# If all users are locked and you cannot access the system, boot into single-user mode
# or use the VPS console from your provider's control panel
Error: sysctl parameters not applied after reboot
Configuration files must be placed in /etc/sysctl.d/, not edited directly in /etc/sysctl.conf. On Ubuntu 22.04+, sysctl.conf has lower priority:
# Verify the file is in the correct location
ls /etc/sysctl.d/
# Apply all new configurations
sudo sysctl --system
# Verify the actual running value
sysctl net.ipv4.conf.all.rp_filter
auditd causing I/O bottleneck on busy servers
auditd writes many logs and can impact disk I/O. Adjust rate limiting in /etc/audit/auditd.conf:
# In /etc/audit/auditd.conf
rate_limit = 1000 # Max events/second (default 0 = unlimited)
max_log_file_action = ROTATE
max_log_file = 50 # MB per log file
num_logs = 5 # Keep 5 rotating log files
sudo systemctl restart auditd
Lynis shows low Hardening Index despite following checklist
Lynis checks hundreds of parameters; a low initial score is normal. Focus on red warnings first, then yellow suggestions. Common quick wins on new VPS:
# View all warnings and suggestions from Lynis
sudo lynis audit system 2>&1 | grep "Warning\|Suggestion" | head -30
# Quick improvements:
# - Install fail2ban
# - Set GRUB password
# - Set umask 027 in /etc/profile
# - Disable root SSH login
Frequently Asked Questions
Do I need to follow every CIS Benchmark recommendation?
Not necessarily. CIS Benchmark is divided into Level 1 (essential, non-disruptive) and Level 2 (strict, may break some services). For a typical VPS, implementing all Level 1 recommendations is sufficient. This article covers the complete Level 1 checklist.
Do I need to reboot after hardening?
Most hardening steps don't require a reboot. sysctl and auditd rules apply immediately. However, changes to /etc/fstab (for /tmp options) and GRUB settings require a reboot to take effect. Test hardening in a maintenance window before rebooting production.
Will hardening slow down my server's performance?
Performance impact is minimal. Kernel network parameters only change behavior without adding overhead. auditd may slightly impact I/O if you enable many rules, but the effect is usually unnoticeable under normal load.