Baseline hardening: the first hour of a new server
The first hour on a new Linux server: patch, restrict access, keep visibility.

A freshly installed server is not a secure one; it is a consistent one. Baseline hardening is the short, repeatable set of changes applied in the first hour so that a machine starts from a defensible state: patched, reachable only the way you intend, running only what it needs, and visible when something changes. The word baseline is the honest one — this is a floor, not a guarantee, and nothing here replaces monitoring, patching or review.
Start from a current, known state
Update first. RHEL’s own hardening guidance lists “update your system” as the first post-installation step, and pushing updates before you customise reduces the chance that a later update overwrites work you have just done. Install only what the server’s role requires: a package that is not present cannot be a vulnerability, and anything missing can be added when it is needed.
Identity and privilege
Log in as a named user and reach root through sudo, never shared credentials. On RHEL the privileged group is wheel; on Ubuntu it is sudo. Edit the policy with visudo, which locks the file and refuses to save a syntax error — a plain editor can lock everyone out of privilege escalation. Keep site rules in files under /etc/sudoers.d/ rather than editing the main file, and remember that sudo resets the environment by default. Restrict root itself: the SSH daemon’s default PermitRootLogin prohibit-password allows root only by key, and on a new server root login over SSH is usually something to turn off. Give the account data a look too — /etc/shadow, which holds the password hashes, must not be readable by regular users.
Remote access
Harden SSH before you depend on it. Install your public key, confirm key login works, and only then set PasswordAuthentication no, so password guessing has nothing to guess. Use AllowUsers or AllowGroups to name who may connect, and validate every change with sshd -t before restarting the service. Hold two sessions open while you edit: one to make the change and one to prove you still have access.
Reduce the exposed surface
Two moves dominate. Turn off services the machine does not need — systemctl disable cups on a server with no printers — and review the active set with systemctl list-units; a service that is disabled but still running has not been fixed. Then put a firewall in front of what remains: default-deny inbound and allow only the services this host provides — ufw on Ubuntu, firewalld on RHEL — taking care to allow SSH before enabling a deny policy.
Keep a minimum of visibility
Hardening you cannot observe is not yet hardening. The systemd journal records service output and authentication events; journalctl -u ssh.service (or sshd.service on RHEL) shows a unit’s recent activity, and sending logs off the host is what lets them survive a compromise. Two commands are worth running at the end: firewall-cmd --list-all (or ufw status) to confirm what is actually allowed, and sshd -t to confirm the SSH configuration is still valid. Industry benchmarks such as the CIS Benchmarks for RHEL and Ubuntu give a longer, auditable checklist to measure against.
Limits and the common error
No baseline makes a system secure, and a sheet that claimed otherwise would be wrong. Hardening narrows the exposed surface and removes the easy ways in; it does not stop a vulnerable application, a stolen credential, or a mistake introduced tomorrow. It is also not a one-off — the same care is needed after every installation, and the baseline should be re-applied and re-verified periodically. The most common error is the self-inflicted lockout: disabling password authentication before the key works, enabling a deny-all firewall before allowing SSH, or saving an unvalidated sshd_config. Each is avoided the same way — make one change, keep a second session open, verify, then continue.
Level and prerequisites. L2 — operational. It assumes the L1 basics of users, groups and permissions and the sibling L2 sheets on packages and updates, SSH and the host firewall, whose commands it reuses.
Where to go next
- Server & Virtualization — the area this sheet belongs to.
- Operating systems — the node this sheet sits under.
- Knowledge — the index of every published sheet.
References
- Red Hat Enterprise Linux 9 — Security hardening, Chapter 1 “Securing RHEL during and right after installation”: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/security_hardening/assembly_securing-rhel-during-installation-security-hardening — supports update-first, install-minimum-packages, disabling unneeded services and re-enabling the firewall.
- CIS — Red Hat Enterprise Linux Benchmarks: https://www.cisecurity.org/benchmark/red_hat_linux — the community consensus secure-configuration baseline referenced for RHEL.
- CIS — Ubuntu Linux Benchmarks: https://www.cisecurity.org/benchmark/ubuntu_linux — the corresponding baseline for Ubuntu.
- sudoers(5) — sudoers file format: https://man7.org/linux/man-pages/man5/sudoers.5.html — supports
env_resetbeing on by default and the@includedir /etc/sudoers.dmechanism. - visudo(8) — edit the sudoers file: https://man7.org/linux/man-pages/man8/visudo.8.html — supports the lock and the refusal to save a syntax error.
- shadow(5) — shadowed password file: https://man7.org/linux/man-pages/man5/shadow.5.html — supports that
/etc/shadowmust not be readable by regular users. - systemctl(1) — Linux manual page: https://man7.org/linux/man-pages/man1/systemctl.1.html — supports enabling, disabling and querying service state.
- journalctl(1) — Linux manual page: https://man7.org/linux/man-pages/man1/journalctl.1.html — supports reading the journal, including per unit (
-u). - Ubuntu Server documentation — OpenSSH server: https://ubuntu.com/server/docs/openssh-server — supports key setup,
authorized_keyspermissions andsshd -t. - Ubuntu Server documentation — Firewall: https://ubuntu.com/server/docs/how-to/security/firewalls — supports enabling ufw and its default policy.
- Red Hat Enterprise Linux 9 — Configuring firewalls and packet filters, “Using and configuring firewalld”: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_firewalls_and_packet_filters/using-and-configuring-firewalld_firewall-packet-filters — supports the
firewall-cmd --list-allverification and service-based rules.