How do you know if your VPS is actually hardened? Most server owners install a firewall, change the SSH port, and call it done. But real security posture comes from verifying that every layer — from kernel parameters to user permissions to service configuration — is actually doing what you think it is. This guide provides 10 commands you can run right now to audit your Linux VPS hardening status, with explanations of what each result means and what to do if it fails. Before you start, check our VPS comparison table to see which providers include security features like DDoS protection and automated patching.
1. Check for Unauthorized User Accounts
cat /etc/passwd | awk -F: '($3 >= 1000) {print $1, $3}'
This lists all users with UID >= 1000, which is the conventional range for human users. Expect only the accounts you created. If you see unexpected entries (especially with UID 0), investigate immediately. A UID 0 user has root privileges regardless of the username. Run awk -F: '($3 == 0) {print}' /etc/passwd to check for multiple root accounts — there should be exactly one: root.
2. Verify SSH Key-Only Authentication
sudo grep -E "^(PasswordAuthentication|PubkeyAuthentication|PermitRootLogin)" /etc/ssh/sshd_config
Your output should show PasswordAuthentication no and PubkeyAuthentication yes. If password authentication is still enabled, attackers can brute-force your SSH login. For PermitRootLogin, the most secure setting is prohibit-password (root login via key only) or no (disable root SSH entirely and use sudo). After any changes, restart sshd and verify you can still connect in a second terminal before closing the first.
3. Audit Open Ports
sudo ss -tlnp | column -t
This shows all listening TCP ports and the processes that own them. Every open port is a potential attack surface. On a standard web server, you should see only 22 (SSH), 80 (HTTP), and 443 (HTTPS). Anything else — 3306 (MySQL), 6379 (Redis), 8080 (unproxied app) — should be bound to localhost or firewalled. If you see unexpected services, investigate and close them. Use sudo ss -ulnp for UDP ports as well.
4. Check the Firewall Rules
sudo nft list ruleset
# or if using ufw:
sudo ufw status verbose
A proper firewall has a default-deny policy on the input chain. Look for a rule that drops or rejects input traffic that does not match any accept rule. If you are using nftables, the default policy should be drop on the input chain. If you are using iptables, check with sudo iptables -L -n. A common mistake is having a firewall that only restricts SSH but leaves all other ports open.
5. Check for Unnecessary Services
systemctl list-units --type=service --state=running | head -40
Every running service consumes resources and adds attack surface. Review the list and disable anything you do not need: avahi-daemon, cups, rpcbind, and postfix (if not used for mail) are common candidates for removal on a single-purpose VPS. Use sudo systemctl disable --now <service> to stop and disable each one.
6. Verify Automatic Security Updates
sudo systemctl status unattended-upgrades
# Check config:
cat /etc/apt/apt.conf.d/20auto-upgrades
On Debian/Ubuntu, unattended-upgrades should be active and configured to apply security updates automatically. The config file should show APT::Periodic::Update-Package-Lists "1" and APT::Periodic::Unattended-Upgrade "1". On RHEL-family systems, check for dnf-automatic or yum-cron. If automatic updates are not configured, you are relying on manual patching — which means you are probably not patching as often as you should.
7. Check for World-Writable Files in Critical Directories
sudo find /etc -perm -o+w -type f 2>/dev/null
World-writable files in /etc are a privilege escalation risk. Any user on the system can modify them. If this command returns any files, investigate why they are writable and lock them down with chmod o-w. Extend the check to /usr and /var if you want to be thorough.
8. Audit SUID and SGID Binaries
sudo find / -perm -4000 -type f 2>/dev/null
SUID binaries run with the privileges of their owner (usually root), regardless of who executes them. They are necessary for some system functions (like ping and sudo), but every unexpected SUID binary is a potential escalation vector. Cross-reference the output against your distribution’s SUID baseline. On Ubuntu, the typical list includes /usr/bin/sudo, /usr/bin/passwd, /usr/bin/su, and a few others. If you see anything unusual, investigate with dpkg -S <path> to check which package installed it.
9. Test Your Backup Integrity
# For restic:
restic check
# For rsync-based backups:
ls -la /backup/latest/
This is not a command you run — it is a procedure. Log into your backup destination, verify the latest backup file exists and is not corrupted, and if possible, restore a test file to a temporary directory. A backup that has never been tested is a wish, not a backup. Document the restore procedure and practice it at least quarterly.
10. Review System Logs for Suspicious Activity
sudo journalctl -u sshd --since "7 days ago" | grep "Failed password" | wc -l
sudo journalctl -u sshd --since "7 days ago" | grep "Accepted" | awk '{print $11}' | sort | uniq -c
The first command counts failed SSH login attempts in the last 7 days. Any number above zero means someone is probing your server; if you have key-only auth enabled this is harmless noise but worth monitoring. The second command shows which IPs have successfully logged in — verify they are all expected. If you see successful logins from unknown IPs, investigate immediately.
Building a Habit, Not a Checklist
Running these 10 commands once gives you a snapshot. Running them weekly gives you a trend. Consider automating the checks with a simple script that emails you the results, or integrate them into a monitoring tool like Nagios or Prometheus with node_exporter’s textfile collector. The goal is not to pass an audit — it is to catch configuration drift before it becomes a breach. Compare security features across providers at our features comparison page to see what your host should be handling at the infrastructure level.



Leave a Reply
You must be logged in to post a comment.