Unix and Linux security: a practical hardening guide

Updated November 2026

This guide shows system administrators how to make a Unix or Linux server harder to break into, and how to recover when something goes wrong. Work through it once for every new system, then keep the security checklist for regular reviews.

About this guide

The original version of this page, written in the early 2000s, used HP-UX as its example and was linked from thousands of sites. HP-UX reached the end of standard support at the end of 2025, so the guide now uses current Linux distributions for its examples, with notes for the BSDs, AIX and Solaris. The principles have not changed much; the tools have.

No guide can promise a secure system. Security is a process: reduce what can be attacked, keep it patched, watch what happens, and be able to restore. The sections below follow that order.

1. Physical and console security

Internal security is often overlooked. Anyone who can touch a machine, its console or its management port can usually take it over, whether that is a cleaner, a visitor or a former employee who still has a badge.

To set a GRUB password on Debian or Ubuntu, create a password hash and add it to a custom file:

grub-mkpasswd-pbkdf2
# copy the grub.pbkdf2.sha512... string it prints, then:
sudo tee -a /etc/grub.d/40_custom <<'EOF'
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.PASTE-HASH-HERE
EOF
sudo update-grub
The server will then wait for the password at every boot

On Debian and Ubuntu this protects every menu entry, so the machine stops at boot and asks for the password, and a remote server will not come back unattended. To let it boot normally but still block editing, add --unrestricted to the CLASS= line in /etc/grub.d/10_linux, run sudo update-grub, and check the line again after GRUB package updates.

On RHEL and Fedora use sudo grub2-setpassword, which does the same in one step and still lets the default entries boot without the password.

2. Keep the system patched

Most break-ins use known holes that already have a fix. Patching is the single most effective thing you can do.

# Debian and Ubuntu: install security updates automatically
sudo apt install unattended-upgrades needrestart
sudo dpkg-reconfigure -plow unattended-upgrades

# RHEL, AlmaLinux, Rocky (Fedora 41+ uses dnf5-plugin-automatic and dnf5-automatic.timer)
sudo dnf install dnf-automatic
sudo sed -i 's/^apply_updates = no/apply_updates = yes/' /etc/dnf/automatic.conf
sudo systemctl enable --now dnf-automatic.timer

# FreeBSD
sudo freebsd-update fetch install
sudo pkg upgrade

Check whether a reboot is waiting: on Debian and Ubuntu the file /var/run/reboot-required exists, and needrestart lists services still running old libraries. On RHEL use dnf needs-restarting -r.

3. Accounts and passwords

Every person gets their own account, and nobody works as root. Full details are in Unix account security; the essentials:

# accounts with user ID 0 (should print only "root")
awk -F: '$3 == 0 {print $1}' /etc/passwd

# accounts with an empty password field
sudo awk -F: '$2 == "" {print $1}' /etc/shadow

# accounts that can log in with a shell
grep -Ev '(nologin|false)$' /etc/passwd

# lock an account and expire it
sudo usermod -L -e 1 olduser

4. Secure remote access with SSH

SSH is the front door of almost every Unix system, so it deserves a careful setup. Telnet, rlogin, rsh and plain FTP send passwords in clear text and should not be installed at all.

  1. Log in with keys instead of passwords: create a key with ssh-keygen -t ed25519 and copy it with ssh-copy-id. See ssh for the details.
  2. Once key login works, turn off password logins and direct root logins.
  3. Allow only the people who need it, for example members of one group.
  4. Slow down password-guessing bots with a tool such as fail2ban or with firewall rate limits.

Put your settings in a drop-in file so package updates do not overwrite them. sshd uses the first value it reads and reads the files in name order, so give yours a low number to beat files such as Ubuntu's 50-cloud-init.conf:

sudo tee /etc/ssh/sshd_config.d/01-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AllowGroups ssh-users
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
EOF
sudo groupadd -f ssh-users
sudo usermod -aG ssh-users "$USER"
sudo sshd -t && sudo systemctl reload ssh    # RHEL: systemctl reload sshd
sudo sshd -T | grep -Ei 'passwordauthentication|permitrootlogin'   # check what sshd will really use

FreeBSD's default sshd_config does not read sshd_config.d: put the lines in /etc/ssh/sshd_config itself and run service sshd reload.

Keep a second session open

Test the new settings from a second terminal before you close the one you are working in. A typo in AllowGroups can lock everyone out, and on a remote server that means a trip to the console.

5. Run as few network services as possible

Every listening service is a way in. List them, and switch off what you do not need:

sudo ss -tulpn                       # TCP and UDP ports with the owning process
systemctl list-units --type=service --state=running
sudo systemctl disable --now cups.service cups.socket cups.path avahi-daemon.service avahi-daemon.socket   # example: printing and mDNS

Then put a host firewall in front of what is left, allowing only the ports you mean to offer. On Ubuntu:

sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw allow 443/tcp
sudo ufw enable

On RHEL and Fedora use firewall-cmd; on Debian you can write nftables rules directly. Both are covered, with NFS, time and name services, in Unix network security.

6. File permissions and file systems

Unix security rests on file ownership and permissions. A few checks catch most mistakes:

# set-user-ID and set-group-ID programs: know why each one is there
sudo find / -xdev -type f \( -perm -4000 -o -perm -2000 \) -exec ls -l {} +

# world-writable directories without the sticky bit
sudo find / -xdev -type d -perm -0002 ! -perm -1000 -print

# files that belong to no user or group (left over from deleted accounts)
sudo find / -xdev \( -nouser -o -nogroup \) -print

Mount /tmp, /var/tmp and removable media with nodev,nosuid,noexec where your software allows it, keep a restrictive umask such as 027 for service accounts, and make sure /etc/shadow is readable only by root. Unix file system security explains each point.

7. Logging, time and monitoring

If you cannot see what happened, you cannot tell whether you were broken into.

journalctl -p warning -b             # warnings and errors since the last boot
journalctl -u ssh --since "1 hour ago"
sudo lslogins --failed                # failed logins (lastb on older systems)
last -n 20                            # recent logins (Debian 13: install the wtmpdb package)

8. Backups that survive an attack

Companies that value their data need a backup plan they have actually tested. Ransomware made one more rule essential: at least one copy must be out of reach of the machines it protects.

Old printouts, disks and tapes with sensitive data should be destroyed, not thrown away.

9. Login banners

A warning banner tells users that the system is private and that use is monitored. In many countries this helps if you later need to act against misuse. Do not greet people with "Welcome", and do not reveal the operating system or its version.

sudo tee /etc/issue.net <<'EOF'
Authorised use only. Activity on this system is logged and monitored.
EOF
sudo cp /etc/issue.net /etc/issue
echo 'Banner /etc/issue.net' | sudo tee /etc/ssh/sshd_config.d/10-banner.conf
sudo sshd -t && sudo systemctl reload ssh

Ask your legal team for the exact wording your organisation needs.

10. People

Many incidents start with a person, not a bug.

11. Test your own systems

Check your work the way an attacker would: scan your own ports, run an audit tool and compare against a published benchmark such as the CIS Benchmarks. Unix security testing lists free tools (Lynis, OpenSCAP, nmap) and how to use them safely. Only scan systems you are responsible for.

12. If you think you have been broken into

  1. Do not panic and do not start deleting things. Evidence disappears quickly.
  2. Isolate the machine from the network, but leave it running if you can, so memory contents are preserved.
  3. Tell the people who need to know: your manager, your security team and, for a company, possibly the national computer emergency response team (CERT/CSIRT) or the data protection authority if personal data was involved.
  4. Reinstall from known-good media. Once someone has had root, you cannot trust any program on the system, including ls and ps.
  5. Change every password and key that was stored on or used from the machine, then restore data from a backup taken before the break-in.
  6. Find out how they got in and fix that hole before you put the system back on the network.

Notes for other Unix systems

FreeBSD, OpenBSD, NetBSD
Use freebsd-update or syspatch (OpenBSD) for patches, pf as the firewall, and securelevel to stop even root from changing protected files on a running system.
IBM AIX
Apply Technology Levels and Service Packs, use AIX Security Expert (aixpert) to apply a hardening profile, and Role Based Access Control instead of sharing root.
Oracle Solaris 11.4
Apply the Support Repository Updates, check the system with the compliance tool (compliance assess -b solaris -p Recommended), and use RBAC roles for administration.
HP-UX
Standard support for HP-UX 11i v3 ended on 31 December 2025. Plan a migration, keep these systems off the internet, and restrict who can reach them.

More detail for each system is on Unix help.