This guide lists essential considerations to harden (enhance) a Linux server: reducing the attack surface, limiting the impact of incidents, protecting against human error, and managing users and privileges.


Preparation

  • Plan and maintain logical and physical diagrams that represent the infrastructure and its systems,
  • Create a Software Bill of Materials (SBOM) per server and link it to the associated ports,
  • Graphically document all relationships between applications and services on the network.

Planning

  • Enumerate the layers of communication to apply Defense-in-Depth,
  • Define an entry point for the network and deploy resources in High Availability to prevent single points of failure,
  • The network entry point will typically have:
    • One primary firewall between the internet and the DMZ,
    • Another firewall between the DMZ and the private network.
  • Make firewall rules as restrictive as possible,
  • Use VLANs and ACLs wherever applicable,
  • For physical infrastructures, consider using dedicated data links in the core network,
  • Use port security for transport and access networks where possible,
  • Strategically define where IDS/IPS should be placed and what it will protect (network-based protection),
  • Endpoints must have up-to-date antivirus, anti-malware, and firewall rules (host-based protection),
  • Avoid or eliminate legacy services such as Telnet, FTP, RSH, and HTTP, as they are all unencrypted.
    • If unavoidable, tunnel the traffic over encrypted or dedicated sniff-proof channels.

Hardening Points to Target

  • Hardware
    • Restrict physical access to servers and network devices with locks, alarms, or cameras as needed,
    • Prefer UEFI (uses GPT) over BIOS (uses MBR),
    • Enable TPM 2.0 where possible.
  • BIOS
    • Set a password to access the BIOS/UEFI menus.
  • Operating System
    • Bootloader
      • Restrict access to the bootloader configuration and boot volume (ideally read-only for /boot),
      • Use GRUB passwords for users or groups to limit boot options such as kernel version selection or multi-OS booting.
    • Kernel
      • Customize kernel compilation to load only the drivers required by the hardware in use,
      • Hide processes from other users (only root should be able to see all processes),
      • Isolate process resources using Control Groups and Namespaces,
      • Enable SELinux, AppArmor, and Exec Shield.
    • Always use an LTS version of the chosen distribution and update it regularly (consider unattended upgrades),
    • Remove orphaned (unused) packages and unused features such as X11, FireWire, and IPv6,
    • Consider disabling Ctrl+Alt+Delete if not needed,
    • Reserve disk space for a swap partition,
    • Encrypt volumes that store sensitive data,
    • Disable root login or disable the root account entirely,
    • Granularly define what each user can and cannot execute with sudo, and configure notifications.
  • Services
    • Leverage system and application-level containerization (LXD and Docker, respectively),
    • Periodically audit listening ports,
    • Apply best practices to the SSH service:
      • Do not allow empty passwords (preferably no passwords at all) or root login,
      • Require SSH keys and a secondary factor such as an OTP mobile app [Link] or a USB/NFC hardware key [Link],
      • Restrict access to specific users or groups, or use rules that match a specific pattern,
      • Always use Fail2Ban in combination with most publicly facing services [Link].
  • Administration
    • Centralize logs on a dedicated log server,
    • Configure LogWatch and LogCheck to monitor logs and send periodic reports,
    • Disable and remove unused or unnecessary services,
    • Define which users are allowed to use cron and which are not,
    • Set a reasonable shell timeout,
    • Find and disable files with SUID and SGID permissions,
    • Use PAM (Pluggable Authentication Modules) to enforce strong password policies (length, complexity, reuse limits, etc.) and password aging,
    • Configure Kerberos where possible,
    • Periodically audit UIDs and identify accounts with empty passwords,
    • Establish policies to lock inactive user accounts.
  • Users
    • Assign privileges to groups rather than individual users, even if the user is the sole member of the group,
    • Use a directory service or manage users with automation tools such as Ansible.

Desired State

  • Encryption in transit,
  • Encryption at rest,
  • Restrict read and write access using Least Privilege Access Control:
    • Per file,
    • Per directory,
    • Per volume.