Unix and Linux security: a practical hardening guide
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.
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.
- Lock the room or the rack. Keep servers in a locked room or cage with a short list of key holders. Check for the less obvious ways in: spare keys in a drawer, raised floors and false ceilings that run past the locked door.
- Protect the boot process. Set a firmware (UEFI) administrator password, keep Secure Boot enabled, disable booting from USB and network unless you need it, and set a boot loader password so nobody can add
init=/bin/bashat the GRUB prompt. - Encrypt disks on laptops, desktops and any server that might leave the building: LUKS on Linux, GELI on FreeBSD, ZFS encryption on Solaris and the BSDs. A stolen disk is then just a disk.
- Separate the management network. Out-of-band controllers (iLO, iDRAC, IPMI/BMC, HMC for IBM Power) give full control of the hardware. Put them on their own network, change the factory passwords and keep their firmware updated.
- Use a UPS and plan for power loss. A UPS protects against outages and spikes. Configure the system to shut down cleanly when the battery is running low (for example with Network UPS Tools,
nut).
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
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.
- Install security updates automatically, or at least weekly, and reboot when the kernel or core libraries change.
- Subscribe to your vendor's security announcements (Debian DSA, Ubuntu USN, Red Hat RHSA, FreeBSD advisories, IBM and Oracle bulletins).
- Replace systems that no longer get updates. An operating system past its end of support will never be fixed again, no matter how stable it looks.
# 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:
- Use sudo, not shared root passwords. Give administrators membership of the
sudo(Debian) orwheel(RHEL, BSD) group, and log what they run. - Only root has user ID 0. Check it regularly.
- No empty passwords, no shared accounts, and no accounts for people who have left. Lock or remove them on the day someone leaves.
- Long passwords beat complex ones. Current guidance (NIST SP 800-63B) favours long passphrases, checking against lists of breached passwords and no forced periodic changes. Use multi-factor authentication where you can.
# 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.
- Log in with keys instead of passwords: create a key with
ssh-keygen -t ed25519and copy it withssh-copy-id. Seesshfor the details. - Once key login works, turn off password logins and direct root logins.
- Allow only the people who need it, for example members of one group.
- Slow down password-guessing bots with a tool such as
fail2banor 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.
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.
- Keep accurate time with
chronyorsystemd-timesyncd. Log entries from different machines are useless if their clocks disagree. - Send logs to another machine. An intruder with root can edit local logs, but not the copy on your log server.
rsyslogcan forward everything with one line. - Record security events with the Linux audit system (
auditd), or BSM audit on FreeBSD and Solaris. - Watch for changes to system files with a file integrity checker such as AIDE.
- Actually read the logs, or have something read them for you and alert on failed logins, new sudo users and services that stop.
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.
- Follow the 3-2-1 rule: three copies, on two kinds of media, one of them off site.
- Keep at least one copy offline or immutable (object storage with object lock, a backup server that pulls data and cannot be written by the clients, or tapes in a safe).
- Encrypt backups that leave the building, and store the keys somewhere other than the backup.
- Test a full restore regularly. A backup you have never restored is a hope, not a backup.
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.
- Lock the screen when leaving the desk (Super+L on most Linux desktops) and log out at the end of the day.
- No passwords or hints on sticky notes. Use a password manager.
- Treat unexpected e-mails asking you to log in, run a script or "verify" an account as suspicious, even when they seem to come from a colleague.
- Give each administrator the access their job needs and no more, and review it when their job changes.
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
- Do not panic and do not start deleting things. Evidence disappears quickly.
- Isolate the machine from the network, but leave it running if you can, so memory contents are preserved.
- 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.
- Reinstall from known-good media. Once someone has had root, you cannot trust any program on the system, including
lsandps. - 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.
- 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-updateorsyspatch(OpenBSD) for patches,pfas the firewall, andsecurelevelto 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
compliancetool (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.