{"id":2870,"date":"2022-05-18T02:43:38","date_gmt":"2022-05-18T02:43:38","guid":{"rendered":"https:\/\/dft.wiki\/?p=2870"},"modified":"2026-06-08T21:48:58","modified_gmt":"2026-06-09T01:48:58","slug":"linux-hardening-guide","status":"publish","type":"post","link":"https:\/\/dft.wiki\/?p=2870","title":{"rendered":"Linux Hardening Guide"},"content":{"rendered":"<p>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.<\/p>\n<hr \/>\n<p><strong>Preparation<\/strong><\/p>\n<ul>\n<li>Plan and maintain logical and physical diagrams that represent the infrastructure and its systems,<\/li>\n<li>Create a Software Bill of Materials (SBOM) per server and link it to the associated ports,<\/li>\n<li>Graphically document all relationships between applications and services on the network.<\/li>\n<\/ul>\n<hr \/>\n<p><strong>Planning<\/strong><\/p>\n<ul>\n<li>Enumerate the layers of communication to apply Defense-in-Depth,<\/li>\n<li>Define an entry point for the network and deploy resources in High Availability to prevent single points of failure,<\/li>\n<li>The network entry point will typically have:\n<ul>\n<li>One primary firewall between the internet and the DMZ,<\/li>\n<li>Another firewall between the DMZ and the private network.<\/li>\n<\/ul>\n<\/li>\n<li>Make firewall rules as restrictive as possible,<\/li>\n<li>Use VLANs and ACLs wherever applicable,<\/li>\n<li>For physical infrastructures, consider using dedicated data links in the core network,<\/li>\n<li>Use port security for transport and access networks where possible,<\/li>\n<li>Strategically define where IDS\/IPS should be placed and what it will protect (network-based protection),<\/li>\n<li>Endpoints must have up-to-date antivirus, anti-malware, and firewall rules (host-based protection),<\/li>\n<li>Avoid or eliminate legacy services such as Telnet, FTP, RSH, and HTTP, as they are all unencrypted.\n<ul>\n<li>If unavoidable, tunnel the traffic over encrypted or dedicated sniff-proof channels.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<hr \/>\n<p><strong>Hardening Points to Target<\/strong><\/p>\n<ul>\n<li>Hardware\n<ul>\n<li>Restrict physical access to servers and network devices with locks, alarms, or cameras as needed,<\/li>\n<li>Prefer UEFI (uses GPT) over BIOS (uses MBR),<\/li>\n<li>Enable TPM 2.0 where possible.<\/li>\n<\/ul>\n<\/li>\n<li>BIOS\n<ul>\n<li>Set a password to access the BIOS\/UEFI menus.<\/li>\n<\/ul>\n<\/li>\n<li>Operating System\n<ul>\n<li>Bootloader\n<ul>\n<li>Restrict access to the bootloader configuration and boot volume (ideally read-only for \/boot),<\/li>\n<li>Use GRUB passwords for users or groups to limit boot options such as kernel version selection or multi-OS booting.<\/li>\n<\/ul>\n<\/li>\n<li>Kernel\n<ul>\n<li>Customize kernel compilation to load only the drivers required by the hardware in use,<\/li>\n<li>Hide processes from other users (only root should be able to see all processes),<\/li>\n<li>Isolate process resources using Control Groups and Namespaces,<\/li>\n<li>Enable SELinux, AppArmor, and Exec Shield.<\/li>\n<\/ul>\n<\/li>\n<li>Always use an LTS version of the chosen distribution and update it regularly (consider unattended upgrades),<\/li>\n<li>Remove orphaned (unused) packages and unused features such as X11, FireWire, and IPv6,<\/li>\n<li>Consider disabling Ctrl+Alt+Delete if not needed,<\/li>\n<li>Reserve disk space for a swap partition,<\/li>\n<li>Encrypt volumes that store sensitive data,<\/li>\n<li>Disable root login or disable the <em>root<\/em> account entirely,<\/li>\n<li>Granularly define what each user can and cannot execute with <em>sudo<\/em>, and configure notifications.<\/li>\n<\/ul>\n<\/li>\n<li>Services\n<ul>\n<li>Leverage system and application-level containerization (LXD and Docker, respectively),<\/li>\n<li>Periodically audit listening ports,<\/li>\n<li>Apply best practices to the SSH service:\n<ul>\n<li>Do not allow empty passwords (preferably no passwords at all) or root login,<\/li>\n<li>Require SSH keys and a secondary factor such as an <strong>OTP<\/strong> mobile app [<a href=\"https:\/\/dft.wiki\/?p=2379\">Link<\/a>] or a USB\/NFC <strong>hardware key<\/strong> [<a href=\"https:\/\/dft.wiki\/?p=2494\">Link<\/a>],<\/li>\n<li>Restrict access to specific users or groups, or use rules that match a specific pattern,<\/li>\n<li>Always use <strong>Fail2Ban<\/strong> in combination with most publicly facing services [<a href=\"https:\/\/dft.wiki\/?p=401\">Link<\/a>].<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Administration\n<ul>\n<li>Centralize logs on a dedicated log server,<\/li>\n<li>Configure LogWatch and LogCheck to monitor logs and send periodic reports,<\/li>\n<li>Disable and remove unused or unnecessary services,<\/li>\n<li>Define which users are allowed to use <em>cron<\/em> and which are not,<\/li>\n<li>Set a reasonable shell timeout,<\/li>\n<li>Find and disable files with SUID and SGID permissions,<\/li>\n<li>Use PAM (Pluggable Authentication Modules) to enforce strong password policies (length, complexity, reuse limits, etc.) and password aging,<\/li>\n<li>Configure Kerberos where possible,<\/li>\n<li>Periodically audit UIDs and identify accounts with empty passwords,<\/li>\n<li>Establish policies to lock inactive user accounts.<\/li>\n<\/ul>\n<\/li>\n<li>Users\n<ul>\n<li>Assign privileges to groups rather than individual users, even if the user is the sole member of the group,<\/li>\n<li>Use a directory service or manage users with automation tools such as Ansible.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<hr \/>\n<p><strong>Desired State<\/strong><\/p>\n<ul>\n<li>Encryption in transit,<\/li>\n<li>Encryption at rest,<\/li>\n<li>Restrict read and write access using Least Privilege Access Control:\n<ul>\n<li>Per file,<\/li>\n<li>Per directory,<\/li>\n<li>Per volume.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This guide lists essential considerations to harden (enhance) a Linux server: reducing the attack surface, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-2870","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/2870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2870"}],"version-history":[{"count":7,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/2870\/revisions"}],"predecessor-version":[{"id":5679,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/2870\/revisions\/5679"}],"wp:attachment":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}