Security9 min read

Securing a VPS and hosting: the checklist we use ourselves

Checklist for securing a VPS and hosting, with an illustration of an administrator at a server rack

You secure a VPS in layers: filter traffic before it reaches your server, shield management access, open only the ports you need, update automatically, detect and block attacks, limit the damage if something does go wrong, and keep backups that survive a hack. Below are the 12 measures VirtuoLab applies to every server, with how important each one is.

Why does a VPS need extra security?

A VPS (virtual private server) is your own server at a hosting provider, and with most VPS plans you are responsible for its security yourself. The provider keeps the machine running; what runs on it, which ports are open and whether updates are installed is up to you. With shared hosting the host handles much of that for you, but you also have less control. That difference matters, because attackers scan the internet continuously and automatically for servers with a known weak spot. According to Verizon's 2025 Data Breach Investigations Report, 20% of the breaches studied started with a vulnerability, and 22% with stolen or misused credentials. A new server with an open SSH port usually gets its first login attempts within minutes. Security is therefore not something to add later, but something to set up before the server goes live.

Which 12 measures make a server secure?

This table is the checklist VirtuoLab uses. Every server gets the essential measures; which others are needed depends on what runs on the server and how sensitive the data is.

Measure
What it does
Priority
Cloudflare WAF and DDoS protection
Filters attacks, malicious bots and suspicious traffic before it reaches the server
Essential
Tailscale and SSH keys
Management over a private network: SSH is not publicly reachable and password login is off
Essential
Firewall (UFW or nftables)
Closes every network port except the ones needed, such as 443 for HTTPS
Essential
Automatic security updates
Installs operating system security patches as soon as they are released
Essential
Encrypted offsite backups
Protects data against a hack, ransomware or loss of the server
Essential
Docker hardening
Isolates applications, limits privileges and keeps internal services out of reach
Essential with Docker
CrowdSec
Recognises attack patterns in log files and blocks suspicious IP addresses
High
AppArmor and process isolation
Limits what a compromised process can read, write and execute
High
Lynis audit
Checks the server for weak or incorrect security settings
High
auditd and AIDE
Records important system actions and flags changed system files
High
Monitoring and alerts, day and night
Warns about suspicious activity, outages and system problems
High
Wazuh (EDR and SIEM)
Collects security events centrally and flags suspicious behaviour
Advanced

How do you set up secure server management?

You secure server management by allowing SSH with keys only and by not exposing the SSH port to the public internet. Step 1: create an SSH key pair and set PasswordAuthentication no and PermitRootLogin no in the SSH configuration, so guessing passwords becomes pointless. Step 2: log in as a regular user and use sudo for administrative tasks, so every action can be traced to a person. Step 3: put management behind a private network such as Tailscale, which runs on WireGuard. The SSH port is then open only to devices in that network, and the rest of the internet does not even see it. Step 4: give every administrator their own key, so you can revoke access per person when someone leaves. According to Verizon, a third party was involved in 30% of breaches in 2025. Knowing who has access to your server, and keeping that access small, is therefore one of the first steps.

Which firewall rules does a web server need?

A typical web server only needs port 443 (HTTPS) open to the outside, plus port 80 just to redirect visitors to HTTPS and to renew certificates. Everything else is closed: the database, admin panels and internal services are reachable only from the server itself or through the private network. On Ubuntu and Debian you do this with UFW, a simple layer on top of nftables. Watch out for one well-known pitfall: when you publish a port, Docker inserts its own firewall rules, and those bypass the UFW rules. A database container started with -p 5432:5432 is then reachable from outside, even though port 5432 is closed in UFW. The fix is to publish containers only on 127.0.0.1, or not to publish them at all and let them talk over an internal Docker network. After every change, check from the outside which ports are really open, for example with a port scan from another machine.

How do you keep a server up to date automatically?

You keep a server up to date by installing security updates automatically and scheduling the rest. On Ubuntu and Debian the unattended-upgrades package does this: it installs operating system security patches as soon as they are released. Larger updates, such as a new version of PHP, Node.js or the database, you do deliberately and on a test environment first, because they can break your application. Also turn on an alert when the server needs a reboot after a kernel update, because the old kernel keeps running until then. October 2026 showed how fast this needs to happen. Two critical PHP vulnerabilities became public before a fix existed, and Dutch services including DigiD and MijnOverheid went offline as a precaution. Servers that update automatically are protected within hours of the release instead of weeks.

How do you detect and block attacks?

You detect and block attacks in two places: in front of the server and on the server. In front of the server sits a web application firewall (WAF) with DDoS protection, such as Cloudflare's. It filters known attack patterns, malicious bots and overload attacks before they reach your server, and the server only accepts traffic coming from Cloudflare. On the server, CrowdSec reads the log files of SSH, the web server and other services, recognises patterns such as repeated login attempts or probing for known vulnerable paths, and blocks those IP addresses. CrowdSec also shares these signals with other users, so an address that attacked elsewhere is blocked for you too. Together these two layers catch most of the automated traffic every server receives. They do not replace updates: a targeted attack on an unpatched flaw can still get through a filter.

How do you limit the damage if something goes wrong?

You limit the damage by giving every component as few privileges as possible, so an intruder in one application does not get the whole server. AppArmor defines per program which files it may read and write and what it may execute; a compromised web server then cannot reach the SSH keys, for example. Each application runs under its own user without admin rights. If you use Docker, this also means: do not run containers as root, grant only the Linux capabilities that are needed (cap_drop: ALL, then add what is really required), make the file system read-only where possible, and never mount the Docker socket into a container. Passwords and API keys belong in protected environment variables or a secrets vault, not in the code. That way a flaw in one component really stays limited to that component.

How do you check whether a server is properly secured?

You check whether a server is properly secured with an audit up front and continuous oversight afterwards. Lynis is an open-source audit tool that checks hundreds of settings on the server and returns a list of improvements and a hardening score; VirtuoLab runs it after setting up a server and periodically after that. Continuous oversight comes from auditd, which records important system actions such as who did what with admin rights, and from AIDE, which stores a fingerprint of system files and reports when a file changes unexpectedly. For larger environments, or when you must comply with rules such as the Dutch Cyberbeveiligingswet (the national NIS2 law, in force since 15 August 2026), Wazuh collects the alerts from all servers centrally. Wazuh is an EDR and SIEM platform: it correlates events and flags suspicious behaviour. For a single small server Wazuh is usually too heavy; Lynis, auditd and AIDE are enough there.

How do you set up backups that survive a hack?

Backups that survive a hack are encrypted, stored at another location and cannot be deleted from the server itself. That last point matters: if ransomware or an intruder gains admin rights on your server and the backups are reachable from it, they are often the first thing to be wiped. According to Verizon, ransomware played a role in 44% of breaches in 2025. A good setup follows the 3-2-1 rule: three copies, on two types of storage, one of them at another location. Encrypt backups before they leave the server, with a key that is not stored on the server. That encryption is far from universal: according to the 2025 Cybersecurity Monitor of Statistics Netherlands (CBS), only 33% of companies with 2 to 10 employees encrypt their data, against 91% of companies with 250 or more. Finally, test a restore at least every quarter, because a backup you have never restored is an assumption, not a backup.

What should you monitor, and who responds?

You monitor three things: availability (is the site reachable and fast), server health (disk space, memory, expiring certificates) and security events (blocked attacks, changed files, unexpected logins). SSL certificates from Let's Encrypt are valid for 90 days and renew automatically, but an alert when renewal fails prevents a site with a browser warning. Just as important is who responds. An alert that nobody looks at protects nothing. To be honest about how this works at VirtuoLab: monitoring runs day and night and sends alerts immediately, and follow-up by a person happens on working days from 09:00 to 18:00. VirtuoLab is a one-person business and has no operations centre staffed around the clock. If you need one, a specialised SOC is the better choice, and VirtuoLab can connect your server to it.

The checklist in short

1Put Cloudflare (or a comparable WAF) in front of your site and only allow that traffic.
2Log in with SSH keys only, disable root login and passwords, and put management behind Tailscale.
3Open only port 443 (and 80 for redirects); check Docker ports separately.
4Turn on automatic security updates and schedule larger updates.
5Make encrypted offsite backups that the server cannot delete, and test restores.
6Run containers without root and with as few privileges as possible.
7Install CrowdSec to detect and block attackers in the log files.
8Use AppArmor and a separate user per application.
9Run Lynis after setup and periodically after that.
10Turn on auditd and AIDE for a trail of system actions and changed files.
11Monitor availability, server health and security events, and agree who responds.
12Consider Wazuh for multiple servers or legal obligations.

Need help securing your server?

Would you like someone to review, set up or manage your VPS or hosting? Book a free intro call with VirtuoLab. You talk directly to the developer, Mustafa Kose: call +31 6 43913632 or email info@virtuolab.dev. After the call you get a fixed price for the work, and an honest view of what you can do yourself and what is not needed.

Further reading

Sources