Linux Hardening Checklist: What innerwarden harden Checks and Why
Why hardening matters
Most breaches do not start with a zero-day. They start with a misconfiguration: a default password left in place, a firewall rule that exposes a database, SSH wide open to password brute-force. Verizon's annual breach report consistently shows that misconfigurations and credential attacks account for the majority of incidents.
Hardening is the process of reducing your attack surface by fixing these misconfigurations before an attacker finds them. The problem is that hardening checklists are long, easy to forget, and drift over time as packages get updated and new services are installed. That is why innerwarden harden exists: it checks every item programmatically, scores your system, and tells you exactly what to fix.
SSH hardening
SSH is the most attacked service on any Linux server. Botnets continuously scan the internet for port 22 and attempt credential stuffing with leaked password lists. Inner Warden checks four critical SSH settings:
- PasswordAuthentication no forces key-based auth, making brute-force impossible.
- PermitRootLogin no prevents direct root login, requiring attackers to escalate after initial access.
- MaxAuthTries 3 limits authentication attempts per connection, slowing automated attacks.
- Non-default port moving SSH off port 22 eliminates noise from automated scanners (not security by itself, but reduces log volume by 90%+).
PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3
Port 2222sudo systemctl restart sshdFirewall configuration
A firewall that is installed but not enabled does nothing. Inner Warden checks that UFW (or iptables/nftables) is active and that the default policy denies incoming traffic. It also scans for exposed database ports (MySQL on 3306, Redis on 6379, and MongoDB on 27017) bound to 0.0.0.0 instead of 127.0.0.1. Exposed databases are the single fastest way to lose data.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp # SSH on custom port
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable# These should return nothing or show 127.0.0.1 only
ss -tlnp | grep ':3306' # MySQL
ss -tlnp | grep ':6379' # Redis
ss -tlnp | grep ':27017' # MongoDBKernel parameters
The Linux kernel has several security-relevant parameters that are not always set to their safest values by default. Inner Warden checks five critical sysctl settings:
- ASLR (randomize_va_space=2) randomizes memory layout to make buffer overflow exploits unreliable. Value 2 is full randomization including the heap.
- SYN cookies (tcp_syncookies=1) protects against SYN flood denial-of-service attacks by not allocating resources until the handshake completes.
- IP forwarding disabled (ip_forward=0) prevents the server from routing traffic between networks. Should be 0 unless the machine is explicitly a router.
- ICMP redirects disabled prevents attackers from redirecting traffic by sending crafted ICMP packets.
- Source routing disabled prevents packets from specifying their own route through the network, which can bypass firewall rules.
# ASLR: full randomization
kernel.randomize_va_space = 2
# SYN flood protection
net.ipv4.tcp_syncookies = 1
# Disable IP forwarding
net.ipv4.ip_forward = 0
# Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Disable source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0sudo sysctl --systemFile permissions
Misconfigured file permissions are a silent escalation path. Inner Warden checks three things: world-writable files in /etc (any user can modify system configuration), unexpected SUID binaries (any user can run them as root), and /etc/shadow permissions (password hashes must be readable only by root).
find /etc -type f -perm -o+w 2>/dev/null
# This should return nothing on a hardened systemfind / -perm -4000 -type f 2>/dev/null
# Review each binary. Remove SUID from anything unnecessary
# Common legitimate SUID: /usr/bin/sudo, /usr/bin/passwd, /usr/bin/pingsudo chmod 640 /etc/shadow
sudo chown root:shadow /etc/shadow
ls -la /etc/shadow
# Expected: -rw-r----- 1 root shadowAutomatic security updates
Known vulnerabilities get patched in hours. But if you do not apply the patch, you are running a system with a public exploit. Inner Warden checks whether unattended-upgrades is installed and configured to apply security updates automatically. This is the single highest-impact hardening step for servers that are not actively managed daily.
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgradescat /etc/apt/apt.conf.d/20auto-upgrades
# Should contain:
# APT::Periodic::Update-Package-Lists "1";
# APT::Periodic::Unattended-Upgrade "1";Docker security
Docker introduces its own attack surface. A privileged container has full access to the host kernel. It is root on the host in every meaningful way. Inner Warden checks for two critical Docker misconfigurations:
- No privileged containers containers running with
--privilegedcan escape to the host, mount the host filesystem, and load kernel modules. There is almost never a legitimate reason for this in production. - Docker socket permissions (660) the Docker socket at
/var/run/docker.sockgrants full control over all containers and the host. If it is world-readable (666), any user on the system can escalate to root.
docker ps --quiet | xargs docker inspect \
--format '{{.Name}} privileged={{.HostConfig.Privileged}}' \
| grep 'privileged=true'
# This should return nothingsudo chmod 660 /var/run/docker.sock
ls -la /var/run/docker.sock
# Expected: srw-rw---- 1 root dockerThe hardening score
After checking every item, innerwarden harden calculates a score from 0 to 100. The score starts at 100 and deducts points based on the severity of each failed check:
A score of 80+ means your system follows best practices. Below 60 means there are critical gaps that an attacker could exploit with minimal effort. The score is designed to give you an instant read on your security posture, and to track improvement over time as you fix each issue.
Running the hardening advisor
Run the hardening check with a single command. The default output shows a summary with your score and any failed checks. Use --verbose to see every check including the ones that passed.
innerwarden hardeninnerwarden harden --verbose$ innerwarden harden
Hardening Score: 72 / 100
CRITICAL
x SSH PasswordAuthentication is enabled (-15)
x Firewall is not active (-10)
HIGH
x /etc/shadow is world-readable (-10)
MEDIUM
! SSH is running on default port 22 ( -5)
LOW
~ unattended-upgrades is not installed ( -3)
PASSED (12 checks)
✓ PermitRootLogin is disabled
✓ MaxAuthTries is set to 3
✓ ASLR is enabled (randomize_va_space=2)
✓ SYN cookies are enabled
✓ IP forwarding is disabled
✓ ICMP redirects are disabled
✓ Source routing is disabled
✓ No world-writable files in /etc
✓ No unexpected SUID binaries
✓ No privileged Docker containers
✓ Docker socket permissions are 660
✓ No exposed database ports
Run 'innerwarden harden --verbose' for full details.Fix the issues from the top down: critical first, then high, then medium. Each fix raises your score. Run the check again after applying changes to verify.