What a practical baseline looks like—and who owns it
A hardening baseline is a small, testable set of controls that every production Linux host must meet before it handles real traffic. It focuses on access, updates, services, logging, and verification—not every possible knob. The baseline should be OS‑agnostic where possible, parameterized for environments (prod, staging), and automated. Make it boring: the same controls, the same tests, the same exceptions process, every time.
Ownership matters more than tooling. Security defines the controls, platform engineering automates them, and application teams attest to compliance during delivery. Create a one‑page policy that names the control owner and evidence source for each item. Tie it to your CI/CD so noncompliant images never ship. For edge cases, use a documented risk acceptance with expiry dates, so exceptions don’t quietly become the new standard.
Build a hardened OS image you can reproduce
Start from a minimal distribution image and add only required packages. Remove compilers and legacy services from production images to reduce exploit surface. Enforce secure kernel parameters (e.g., disable IP forwarding unless needed, restrict dmesg, hardened mmap) via sysctl, applied at boot. Prefer immutable configuration baked into the image over scripts that mutate hosts post‑provisioning, so every server starts compliant and drifts less over time.
Treat the image like code. Store the Packer/Kickstart/Ansible definitions in version control, tag releases, and sign the image. Include a non‑interactive CIS‑style scan stage and break the build on medium‑or‑higher findings you care about. Document supported instance types and filesystems. Trade‑off: images that are too generic grow config sprawl, while overly specialized ones multiply maintenance; aim for 2–4 base images aligned to workload classes.
Access control and identity: SSH, sudo, keys
Disable password SSH logins; use key‑based auth with short‑lived certificates (e.g., via SSH CA) or centrally rotated keys. Restrict SSH to specific subnets or bastions and enforce protocol 2, strong KEX/MACs, and idle session timeouts. Mandate multi‑factor auth on the jump host. For sudo, require explicit groups, no NOPASSWD for admin shells, and narrow command whitelists for automation users. Log every elevation with reason codes in the ticket.
Expect operational impacts: locked‑down SSH can slow break‑glass recovery if you haven’t pre‑positioned access. Keep an emergency local admin with a vaulted, rotated password and console access only. For service accounts, prefer short‑lived tokens (OIDC, cloud instance roles) over long‑lived secrets. Rotate host keys during image updates. Verification: an unauthorized user should receive publickey failure, not password prompts; sudo logs must show user, command, and ticket ID on every elevation.
Network, services, and patching: reduce attack surface
Default‑deny inbound with host firewall (nftables or iptables) and only open documented ports. Bind services to loopback or specific interfaces; disable wildcard listeners. Turn off unused daemons (avahi, rpcbind, cups). Enforce TLS with modern ciphers; store private keys with least privilege. Consider SELinux/AppArmor enforcing modes for critical services; profile noisy denials in staging first to avoid accidental outages.
Patching is not optional. Enable unattended security updates with controlled maintenance windows, and use kernel live‑patching where uptime is a must. Maintain a rapid channel for high‑severity fixes with rollback plans. Common failure modes: breaking ABI‑dependent agents, reboot loops after kernel changes, and firewall rules that vanish on restart. Verification: nmap from a control host should show only expected ports, and package inventory should reflect latest security advisories for your distro.
Logging, monitoring, and verification you can act on
Centralize system logs (journald, syslog) and security events (auditd) into a SIEM with immutable storage and retention that meets your regulatory needs. Enable file integrity monitoring for critical paths (/etc, binaries), and alert on changes outside approved windows. Forward authentication, sudo, and kernel messages with host metadata (AMI ID, image version) so you can pivot incidents to affected images, not just instances.
Write detection rules that match your baseline: alert on SSH from non‑bastion sources, sudo without ticket tags, new listening ports, and auditd rule tampering. Add lightweight health checks: verify time sync, disk encryption where required, and that SELinux/AppArmor stays enforcing. Run periodic compliance jobs that fail the node into quarantine if controls drift. Verification: a golden host should pass a scripted checklist in under two minutes with zero manual steps.
A step‑by‑step hardening workflow for SMEs
Catalog your workloads and group them by exposure (internet‑facing, internal, batch) and data sensitivity. Define the baseline controls per group and write them as code in your image build. Next, enforce network policy: security groups or ACLs first, then host firewalls. Integrate secrets management and identity early, so applications never need static secrets on disk.
Automate deployment via CI/CD: build image, run compliance scans, push to registry, and only allow autoscaling or provisioning from signed, approved images. During rollout, start with non‑critical tiers, observe metrics, then advance to critical systems. Document rollback per service. Finish by enabling central logging and detections, and schedule monthly drift reports and quarterly tabletop exercises to rehearse break‑glass access and patch surge events.
Checklist you can copy, plus common mistakes to avoid
Checklist: minimal signed image; sysctl hardening; SELinux/AppArmor enforcing for key services; password SSH disabled; MFA on bastion; sudo scoped with logging; default‑deny firewall; unused daemons removed; TLS modernized; unattended security updates and live‑patch where applicable; centralized logs and auditd; file integrity monitoring; immutable infrastructure where possible; scripted verification, nmap and auth tests; documented break‑glass and rollback.
Common mistakes: treating cloud network controls as a substitute for host hardening; enabling SELinux/AppArmor without staging; unmanaged exceptions that never expire; long‑lived SSH keys; skipping verification in CI; and letting configuration drift. Next steps: codify your baseline, pilot on one service, and iterate with measurable SLOs. If you need help aligning hardening with your stack, Auranik’s Cloud Solutions & IT Services (/poland/technology/cloud) can assist without disrupting delivery.
Community content reflects individual experiences and should not be treated as legal, immigration, financial or government advice.
Know someone who may find this guide useful?