Linux Server Hardening: Essential Checklist for UK Web Servers
Is your website running on its own VPS with no sysadmin on staff? This checklist covers the steps we apply to every inherited server, including common pitfalls that can lock you out.
by Cleverson Gouvêa

Linux server hardening is the process of reducing everything an internet-exposed server offers an attacker: open ports, services, users, outdated versions, and excessive permissions. If your company runs a website, e-commerce store, or system on its own VPS and no one on the team is a sysadmin, this checklist shows you what to do, in what order, what not to do, and the ongoing costs of maintenance.
TL;DR
- By 2026, vulnerability exploitation became the leading initial access vector in data breaches: 31% of initial access in the Verizon DBIR 2026, up from 20% the previous year. Outdated servers are the cheapest targets.
- The effective order: inventory and backup → SSH → firewall → updates → PHP and web server → database → logs and monitoring.
- Several popular versions have already reached end-of-life: PHP 8.1 (31/12/2025), MySQL 8.0 (April 2026), Debian 11 (31/08/2026). PHP 8.2 only receives security fixes until 31/12/2026.
- The most costly pitfalls are silent: Docker ignores UFW, fail2ban behind Cloudflare bans Cloudflare itself, and on Ubuntu 24.04, changing the port in sshd_config does nothing.
- Linux server hardening isn't a one-off task: it's a monthly routine. If no one in the company will perform this routine, hire someone who will.
I write as a full-stack developer and founder of Agathas Web, a company that has operated Linux servers since 2008. We support Moodle environments for educational institutions, client websites and systems on managed hosting, and the infrastructure for Voyia, our customer service platform built on the official WhatsApp API. The Linux server hardening checklist below is the same one we apply when inheriting a server.
What is Linux server hardening and why has it become urgent by 2026
A newly created server in any cloud environment comes configured to function, not to resist attacks. It accepts password logins, leaves services listening on all interfaces, and assumes someone will apply updates. Linux server hardening is the process of disabling what's unnecessary and strengthening what remains.
The reason for the urgency lies in the figures. According to the Verizon Data Breach Investigations Report 2026, vulnerability exploitation now accounts for 31% of initial access in breaches, surpassing phishing and stolen credentials. The same report shows that organisations take a median of 43 days to patch a vulnerability already being exploited, and only 26% of them are fully remediated.
Translating this to the reality of a business with a web server: without Linux server hardening and a patching routine, an attacker doesn't need to specifically target you. They scan the internet for a vulnerable version and gain access wherever they find an open door.
The case that best illustrates this is regreSSHion (CVE-2024-6387). In July 2024, Qualys disclosed a flaw in OpenSSH that allowed remote unauthenticated code execution as root on Linux systems with glibc. It affected versions 8.5p1 to 9.7p1, and the company estimated over 14 million potentially vulnerable instances exposed. Those with an update routine patched it within days. Those without remained exposed for months.
This is why Linux server hardening isn't a project with a start, middle, and end. It's a well-executed initial configuration combined with an ongoing routine. In our managed hosting, the contractual goal is to apply critical patches within 72 hours of a CVE's publication — and it's this routine, not the initial day's configuration, that separates a secure server from one that was secure for a day.
Before You Start: Inventory, Backup, and Emergency Access
The most common mistake for those undertaking Linux server hardening for the first time is to start with SSH and lock themselves out. Before touching anything, ensure three things.
1. A Way Back
- Provider's emergency console (KVM, web console, "rescue mode"). Test it beforehand. If you misconfigure the firewall rule, this is how you'll regain access.
- Disk snapshot taken immediately before changes. On a VPS, this costs pennies and can undo an error in minutes.
- A second SSH session open while changing access configuration. Only close it after testing login with a third session.
2. An Honest Inventory
Run ss -tulpn and note down every listening service. On inherited servers, the most common pattern we find is a database listening on 0.0.0.0, a forgotten admin panel, and a test service no one remembers installing. Each item on this list needs an owner and a reason to exist.
3. When NOT to Apply Hardening Now
- Without a tested backup. Hardening a server without guaranteed restoration simply swaps one risk for another.
- On the eve of a launch, enrolment period, or Black Friday. Security changes have a window, just like deployments.
- With a ready-made script from the internet run blindly. Benchmarks like the CIS are excellent references, but applying all items at once will break an application. Apply them in blocks and test between each.
- On an unsupported operating system. If the server runs Ubuntu 20.04 or Debian 11, the correct hardening approach is to migrate to a supported version, not to patch up the old one.
SSH and Users: Who Gets In and How
SSH is the starting point for Linux server hardening because it's the front door. It's also the first thing bots test, minutes after a new IP appears on the internet.
The Bare Minimum
- Key-only login.
PasswordAuthentication noandKbdInteractiveAuthentication noinsshd_config. Use ed25519 keys, one per person, never shared. - No direct root login.
PermitRootLogin no. Each person uses their own user and escalates privileges withsudo, which leaves a trace of who did what. - Only those who need it.
AllowUsersorAllowGroupslimits who can log in, even if another account exists on the system. - fail2ban to block IPs that repeatedly fail. It doesn't replace keys but reduces log noise and thwarts brute-force attacks on other services.
- Disable accounts of leavers. Former suppliers with keys still authorised in
authorized_keysis more common than it seems.
Pitfall: Changing the SSH Port on Ubuntu 24.04
Changing port 22 to another reduces log noise but isn't real protection — a scanner will find the new port in seconds. And there's a detail that catches many people out: since Ubuntu 22.10, SSH uses systemd socket activation. On Ubuntu 24.04, changing Port in sshd_config passes validation but is simply ignored, because the port is listened to by ssh.socket. You need to adjust the socket and run systemctl daemon-reload. If the firewall has already been closed for the old port, this is where you'll lose access.
System Users and Permissions
The rule is least privilege. The web server process (www-data, nginx, or apache) cannot own the application files: if it does, any code flaw allows it to rewrite its own code. Leave the code with a deploy user and grant the web server write access only to folders that require it, such as uploads and cache. In Moodle, for example, moodledata should be kept outside the public folder, with write access only for the PHP process.
Firewall: Close Everything and Open Only What's Necessary
The firewall in Linux server hardening follows a simple policy: deny everything by default and only allow what the business requires. Generally, this means ports 80 and 443 for the world, and SSH only for known IPs or via VPN.
On Ubuntu, UFW works well: ufw default deny incoming, ufw allow 443/tcp, ufw allow from <your-ip> to any port 22. Databases, Redis, and internal panels do not appear on this list. They listen on 127.0.0.1 or a private network.
Pitfall 1: Docker Bypasses UFW
If you run containers, be aware that when publishing a port with -p 8080:80, Docker writes its own iptables rules, which traffic traverses before UFW's rules. Result: a ufw deny 8080 blocks nothing. The official Docker documentation explains this behaviour. The simplest fix is to publish only to localhost (-p 127.0.0.1:8080:80) and let the reverse proxy communicate with the container.
Pitfall 2: fail2ban Behind Cloudflare
With a proxy like Cloudflare in front, the server sees Cloudflare's IP, not the visitor's. A fail2ban reading Nginx logs without configuring the real IP will ban Cloudflare's own addresses — bringing down legitimate clients along with the attacker. Configure the real IP module with Cloudflare's official IP ranges before enabling any log-based blocking rules.
What Cannot Be Closed in the Firewall
Some integrations require a public endpoint. The official WhatsApp API webhook is an example we operate daily at Voyia: Meta needs to reach your server. Here, protection moves from the firewall to the application: validate the X-Hub-Signature-256 signature of each request, apply rate limiting, and reject anything unsigned. With Cloudflare's WAF in front, you can still block bots and traffic spikes before they reach the server.
Updates: Operating System, PHP, and Database
This is the item with the highest return and the most neglected part of Linux server hardening in companies without a sysadmin. The table below shows why the version matters as much as the configuration.
| Component | Situation in September 2026 | What to do |
|---|---|---|
| Ubuntu 20.04 LTS | Standard support ended on 31/05/2025 (ESM paid only) | Migrate to 24.04 LTS |
| Ubuntu 22.04 LTS | Standard support until April 2027 | Plan migration for 2027 |
| Debian 11 | LTS ended on 31/08/2026 | Migrate now |
| Debian 12 | In LTS until 30/06/2028 | Supported, plan for Debian 13 |
| PHP 8.1 | End-of-life on 31/12/2025 | Update the application |
| PHP 8.2 | Security fixes only, until 31/12/2026 | Migrate before year-end |
| MySQL 8.0 | End-of-life in April 2026 | Migrate to 8.4 LTS |
Sources: Ubuntu release cycle, Debian 11 LTS end-of-life announcement, and PHP supported versions.
Automatic Updates: Enable, But Understand the Limits
On Ubuntu, unattended-upgrades comes active and applies only security updates once a day. It's a good baseline. The limit: it doesn't restart the server by default. Kernel and library fixes like glibc and OpenSSL only take effect after a reboot or service restart. Check the /var/run/reboot-required file and schedule reboots within an agreed maintenance window.
When NOT to Update Automatically
In Linux server hardening, a rule applies: major version upgrades — PHP 8.1 to 8.3, MySQL 8.0 to 8.4, Ubuntu 22.04 to 24.04 — should never be automatic. Plugins, extensions, or legacy code will break. The safe approach is to spin up a new server in parallel, validate in staging, and then switch over, as described in our guide for migrating Moodle servers without data loss. This applies to any system, not just Moodle.
PHP and Web Server: What the Application Exposes
A significant portion of PHP website intrusions doesn't come through the operating system: it comes through the code, an outdated plugin, or a poorly validated upload. Linux server hardening doesn't fix bad code, but it limits the damage.
Essential PHP Configurations
expose_php = Offanddisplay_errors = Offin production. Error messages on screen can reveal file paths, versions, and sometimes credentials.allow_url_include = Off. There's no modern reason to include code via URL.- One PHP-FPM pool per application, each with its own user. If one site goes down, its neighbour doesn't go down with it.
- Block PHP execution in the uploads folder. This is how a
.phpfile disguised as an image often gets in. open_basedirrestricting PHP to the application's own folders.
Beware of disable_functions Copied from the Internet
Ready-made lists that disable exec, shell_exec, and proc_open appear in every tutorial. They work for simple institutional websites but break real features: Moodle, for example, calls external binaries for tasks like document conversion and disk usage calculation. Adjust the list to the application, not the other way around. The requirements, costs, and common errors of Moodle hosting show how the stack for this type of system demands specific configuration.
On the Web Server
Remove the version signature (server_tokens off in Nginx), enforce HTTPS with HSTS, disable directory listing, and block access to sensitive files like .env, .git, and .sql backups forgotten in the root. SSL certificates automatically renewed by Let's Encrypt eliminate the shock of a 'not secure' website on a Monday morning.
Database: Off the Internet, Always
There's no reason for a MySQL, MariaDB, or PostgreSQL database for a website or business system to accept connections from the internet. Nevertheless, an exposed database is one of the most frequent findings when we perform Linux server hardening on an inherited environment.
The Database Checklist
- Listen only on 127.0.0.1 or the private network (
bind-addressin MySQL/MariaDB,listen_addressesin PostgreSQL). - One user per application, with permissions only on its own database. The application does not use the database root.
- Strong passwords kept outside versioned code. Credentials in a Git repository are leaked credentials.
- Administrative access via SSH tunnel, never opening port 3306 'just for a day'.
- Remove anonymous users and test databases that some installations create.
- Database backup separate from file backup, with a consistent dump and a copy off-server.
Redis and Similar
Redis without a password listening on a public interface is an invitation. It was designed for a trusted network. Keep it on localhost, enable authentication, and disable dangerous commands that the application doesn't use.
Logs, Monitoring, and Backup: Hardening That Proves It Worked
A hardened server without monitoring is one where you only discover problems via the client. This step closes the Linux server hardening cycle and shows whether the others have worked.
- Centralised and retained logs. Authentication (
/var/log/auth.logorjournalctl), web server, and application. If the server is compromised, local-only logs can be erased. - Alerts that reach someone. External uptime, disk over 85%, stuck CPU, series of 500 errors, SSH login from a new IP. An alert sent to an email no one reads isn't an alert.
- 3-2-1 backup, encrypted and tested. Three copies, two media, one off-site. And the part almost no one does: actually restore, every month, in a test environment. A backup that has never been restored is just a hypothesis.
Summary Checklist and Estimated Effort
| Step | Initial Effort | Routine |
|---|---|---|
| Inventory, snapshot, and emergency access | 1 to 2 hrs | With every major change |
| SSH and users | 1 hr | Quarterly key review |
| Firewall and WAF | 1 to 3 hrs | With every new service |
| Updates and reboots | 1 hr for configuration | Weekly, with a window |
| PHP and web server | 2 to 4 hrs | With every new application |
| Database | 1 to 2 hrs | Quarterly review |
| Logs, alerts, and tested backup | 3 to 6 hrs | Monthly (restore test) |
The hours above are our estimate for Linux server hardening for a typical web server with one or two applications, performed by someone who already knows the process. For those learning, multiply by three. And the real cost isn't the day of configuration: it's the routine that needs to happen every week, for years, without anyone forgetting.
This is where the maths changes for those without a sysadmin. Hiring a full-time senior professional to look after one or two servers rarely pays for itself. Leaving the routine to the application developer usually works until the first busy month. We compare the cost of operating alone versus outsourcing, with figures, in Moodle on AWS vs. Managed Hosting — the reasoning applies to any system.
How Agathas Web Solves This
Everything in this Linux server hardening checklist is part of the standard for our managed hosting. It's not an extra package: it's the starting point for every environment we take on.
What's Included
- Operating system hardening on delivery, with fail2ban, mandatory MFA, and log auditing.
- Cloudflare WAF with customised rules, DDoS mitigation, and bot blocking.
- Updates for system, runtime (PHP, Node, Python), database, and critical plugins, tested in staging and applied within an agreed maintenance window. Critical patches within 72 hours of public CVE, as per contract.
- Daily and incremental backup, off-site and encrypted with AES-256, with monthly tested restores.
- 24/7 monitoring with Grafana, Prometheus, Sentry, and UptimeRobot, and alerts to the technical team's WhatsApp.
- Let's Encrypt SSL automatically renewed for all domains.
- Contractual SLA: 99.9% uptime, response within 15 minutes for critical incidents, and resolution within 2 hours.
How It Works in Practice
We start with a free diagnostic of your current infrastructure: within 3 business days, we identify risks, unsupported versions, and optimised costs. If it makes sense to proceed, we migrate your website, database, emails, and DNS within 7 business days, with staging validation before the switchover and the old environment maintained for 30 days as a rollback plan. The engineer who configured your server will handle your support requests.
Pricing and How to Engage
Institutional sites and blogs typically range between £200 and £400 per month; e-commerce and SaaS, between £500 and £2,000 per month. Initial setup ranges from £700 to £3,000, depending on complexity. The contract is monthly, with no long-term commitment, requiring 30 days' notice for cancellation. If your company also needs someone to decide on IT architecture and priorities, our consultancy, acting as CTO as a Service, complements the operation.
Conclusion: The Checklist Only Works If Someone Runs It Every Month
Linux server hardening starts with a day of configuration and continues with years of discipline. Keys instead of passwords, firewall denying by default, database off the internet, supported versions, tested logs, and backup. None of this is secret. What's missing in most businesses is someone with the time and responsibility to maintain the routine.
If you have the server but not that someone, the next step is simple: request a free diagnostic from Agathas Web's managed hosting. You'll receive a snapshot of your server's current risks and can decide, with the figures in hand, whether to do it yourself or leave it to those who do it every day.
Related posts

Safeguarding Your Web Server: WAF, fail2ban, and Rate Limiting Explained
94% of logins on Cloudflare's network are bots. Discover how WAF, rate limiting, and fail2ban can thwart attacks before they bring down your website.

Cobuccio Tecnologia: The UK Business Case for In-House IT
A data processor worth £1 million in Monte Belo (MG), Brazil, helps explain the most expensive IT decision a UK business might face in 2026.

Microsoft's Other Founder: Paul Allen and the 1975 Story
Paul Allen spotted the Popular Electronics cover, coined 'Micro-soft' and left in 1983. The full story behind the question.