Linux hardening cheatsheet.

SSH

# /etc/ssh/sshd_config
Port 22
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
MaxAuthTries 3
MaxSessions 3
AllowUsers alice bob
sshd -t
systemctl reload sshd

Firewall

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

fail2ban

apt install fail2ban

/etc/fail2ban/jail.d/sshd.conf:

[sshd]
enabled = true
port = 22
maxretry = 5
bantime = 1h
findtime = 10m
systemctl enable --now fail2ban
fail2ban-client status sshd
fail2ban-client unban 1.2.3.4

Kernel sysctl

# /etc/sysctl.d/99-hardening.conf
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.unprivileged_bpf_disabled = 1
net.core.bpf_jit_harden = 2
kernel.yama.ptrace_scope = 1

net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.tcp_syncookies = 1
net.ipv6.conf.all.accept_redirects = 0
sysctl -p /etc/sysctl.d/99-hardening.conf

Filesystem

/etc/fstab mount options:

/tmp    /tmp   ext4   defaults,nodev,nosuid,noexec  0 2
/var    /var   ext4   defaults,nodev                 0 2

Drop privileges in services

systemd:

[Service]
User=myapp
Group=myapp
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
RestrictRealtime=yes
SystemCallArchitectures=native
ReadWritePaths=/var/lib/myapp

systemd-analyze security myapp rates.

SELinux (RHEL family)

sestatus
getenforce                          # Enforcing, Permissive, Disabled
setenforce 1                        # enforcing
restorecon -Rv /var/www             # fix labels
chcon -t httpd_sys_content_t /var/www/x
audit2allow -a                      # generate policy from denied audits

# Find issues
ausearch -m avc -ts recent

AppArmor (Ubuntu/Debian)

apparmor_status
aa-enforce /etc/apparmor.d/usr.sbin.nginx
aa-complain /etc/apparmor.d/usr.sbin.nginx

auditd

apt install auditd
auditctl -w /etc/passwd -p wa -k passwd_changes
auditctl -w /etc/shadow -p wa -k shadow
auditctl -l                         # list
ausearch -k passwd_changes
aureport

Persistent: /etc/audit/rules.d/audit.rules.

Unattended upgrades

apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

Or dnf-automatic on RHEL.

Lynis (audit)

apt install lynis
lynis audit system

Reports hardening gaps.

Clamav (malware scan)

apt install clamav clamav-daemon
freshclam
clamscan -r /home

chkrootkit / rkhunter

apt install rkhunter chkrootkit
rkhunter --update
rkhunter --check
chkrootkit

tripwire / aide (integrity)

apt install aide
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
aide --check

Detects file changes against known baseline.

Cron security

# /etc/cron.allow / /etc/cron.deny
# Allow only specified users

sudo logging

# /etc/sudoers
Defaults log_input, log_output
Defaults logfile=/var/log/sudo.log
Defaults iolog_dir=/var/log/sudo-io

Disable unused services

systemctl list-unit-files --state=enabled
systemctl disable cups bluetooth

CIS / DISA STIG

Run pre-built scripts to apply CIS Benchmark hardening:

  • cis-cat
  • OpenSCAP
  • Ansible roles: dev-sec/ansible-collection-hardening

TLS / certificates

Auto-renewal via certbot. Monitor expiration:

echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

Container hardening

See Docker / K8s cheatsheets. Drop caps, non-root, read-only FS.

Backups + recovery

Hardening means nothing without backups. Test restores.

Common mistakes

  • SSH on port 22 + password auth → brute force.
  • root:root everywhere.
  • Disabled SELinux / AppArmor “to make it work.”
  • No fail2ban.
  • Open services on public interfaces.
  • No log monitoring for auth.

Read this next

If you want my hardening Ansible playbook, it’s at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .