FAHADBIN SHAKIR

Loading essential experience000%

Infrastructure Security

A Practical Linux Web Server Hardening Baseline

A maintainable baseline for identity, patching, network exposure, service isolation, secrets, logging, backups, and recovery on a small production server.

Author: Fahad Bin Shakir · Published: · Updated: · 12 min read

Introduction

Hardening is not a list of commands copied onto a server once. It is a maintained set of controls tied to a threat model, an inventory, an update process, and a recovery plan. A minimal production host should expose only the services it needs, give each component the least privilege it can operate with, and produce enough evidence to investigate failure.

The baseline below is deliberately conservative. Distribution, workload, compliance, and hosting constraints may require different settings, so changes should be tested on a representative host and introduced with a rollback path.

Know what is running and who owns it

Maintain an inventory of the operating system release, kernel, packages, repositories, listening sockets, systemd units, scheduled jobs, users, SSH keys, certificates, domains, data stores, and external dependencies. Remove packages and services that have no operational owner or current purpose.

Assign an owner for patching, certificate renewal, backups, alerts, and incident response. A control without an owner will eventually expire. Record the build procedure so a replacement host can be created without treating the existing machine as the only copy of its configuration.

Reduce identity and privilege risk

Use named administrative accounts, key-based SSH, and sudo for bounded elevation. Disable direct remote root login and password authentication after confirming that the approved key path and recovery console work. Protect private keys with passphrases and remove access promptly when a role changes.

Run the web application, deployment process, database, and monitoring agents under separate service identities where practical. File ownership should allow the application to write only to required runtime paths. The web process should not be able to modify its executable code or read unrelated users' secrets.

Patch predictably and minimize exposure

Use supported repositories and establish a patch window, emergency process, and reboot policy. Subscribe to security notices for the distribution and major runtime components. Test application compatibility, but do not leave critical remotely exploitable updates waiting for an undefined maintenance day.

Default-deny inbound network access and allow only required ports from required sources. Put databases, control panels, and metrics endpoints on private interfaces or an authenticated tunnel. Confirm exposure externally because a local firewall rule can be bypassed by a cloud security group or provider forwarding rule.

Constrain services and protect secrets

Use systemd sandboxing options where compatible, including a private temporary directory, restricted address families, protected system paths, and limited capabilities. Apply one control at a time and test the service because a blanket profile can break legitimate file, network, or process access.

Store secrets outside the repository with strict file permissions or a managed secret store. Rotate them after suspected exposure and avoid printing them in process arguments or logs. Application debug modes, directory listings, source maps, and default server pages should be disabled in production unless there is a documented reason.

Create useful detection signals

Centralize authentication, sudo, web server, application, firewall, and system service logs with protected retention. Synchronize time so events can be correlated. Alert on repeated authentication failures, unexpected new listeners, disabled services, certificate expiry, disk pressure, backup failure, and sudden changes in outbound traffic.

Avoid collecting sensitive request bodies or credentials. Log enough structured context to trace a request, including timestamp, route, status, duration, and request ID. Review alert routing periodically so a valid signal reaches someone who can act.

Back up for recovery, not compliance theatre

Back up application data, configuration, certificates or renewal state, and the information required to rebuild. Keep at least one protected copy outside the server's administrative boundary. Encrypt backups, restrict restore access, and monitor job completion and storage growth.

Perform scheduled restore tests onto an isolated host. Measure recovery time and verify application behavior, not just archive extraction. A tested rebuild procedure is also the safest response when host integrity is uncertain; cleaning an unknown compromise in place is difficult to prove.

Deployment checklist

  • Inventory services, sockets, users, keys, jobs, certificates, and data owners.
  • Use named key-based administration and disable direct remote root login.
  • Separate service identities and minimize writable application paths.
  • Patch supported components on an owned schedule.
  • Default-deny network exposure and verify it externally.
  • Protect secrets and disable production debug surfaces.
  • Centralize actionable logs with synchronized time.
  • Test complete restoration on a separate host.

Primary references

Related Engineering Notes

View all Engineering Notes