Linux Server Security & Kernel Hardening: OpenSSH Cryptography, nftables, sysctl, Auditd & CrowdSec
Executive Summary: A freshly provisioned Linux server exposed to a public IPv4 address receives automated SSH credential-stuffing and port-scanning probes within seconds. This comprehensive security reference details defense-in-depth hardening across five layers: OpenSSH cryptographic cipher/KEX restriction (
Ed25519/ FIDO2ed25519-sk), kernel/etc/sysctl.d/network and memory exploit mitigations, statefulnftableshost firewalling, behavioral intrusion prevention (CrowdSec/Fail2ban), and Linux Kernel Audit (auditd) + Mandatory Access Control (AppArmor/SELinux).
-
OpenSSH Cryptographic Lockdown
Restrict
sshdtocurve25519-sha256,chacha20-poly1305, andssh-ed25519/ FIDO2 hardware keys (ed25519-sk) while disabling root and password auth. -
Stateful
nftablesPerimeter
Enforce a default-drop ingress policy with rate-limited ICMPv4/ICMPv6, invalid connection-state dropping, and dynamic threat-intel IP sets.
-
Kernel
sysctlExploit Mitigations
Enable
kptr_restrict,dmesg_restrict,yama.ptrace_scope, strict Reverse Path Filtering (rp_filter), and TCP SYN cookies. -
Auditd, Lynis & AIDE Integrity
Log immutable kernel syscall events (
auditdrules on/etc/shadowandexecve), verify CIS compliance (lynis), and detect binary tampering.
1. Architecture: Defense-in-Depth Linux Security Layers
Relying on a single perimeter control (such as changing the SSH port) fails the moment an application vulnerability or leaked credential is exploited. True server hardening enforces independent concentric boundaries from the NIC driver all the way to kernel syscall auditing:
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
subgraph Layer1["1. Network Perimeter"]
NFT["nftables Default-Drop<br/>+ CrowdSec IP Set Bouncer"]
end
subgraph Layer2["2. Cryptographic Access"]
SSHD["Hardened OpenSSH<br/>Ed25519 / FIDO2 Hardware Keys<br/>Zero Password / Root Login"]
end
subgraph Layer3["3. Mandatory Access (LSM)"]
MAC["AppArmor / SELinux<br/>+ Systemd Unit Sandboxing"]
end
subgraph Layer4["4. Kernel & Audit Core"]
Sysctl["Kernel sysctl Hardening<br/>(ptrace, kptr, bpf, symlink)"]
Auditd["auditd Syscall Monitor<br/>+ AIDE File Hash Baseline"]
end
Layer1 --> Layer2 --> Layer3 --> Layer4
2. Cryptographic OpenSSH Hardening (/etc/ssh/sshd_config.d/)
Generate either a standard Ed25519 keypair (ssh-keygen -t ed25519 -a 100) or a hardware-backed FIDO2 YubiKey resident key (ssh-keygen -t ed25519-sk -O resident -O verify-required) on your workstation, copy the public key to the server, and deploy a drop-in hardening file in /etc/ssh/sshd_config.d/00-hardened.conf:
# --- Authentication & Privilege Isolation ---
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
AllowUsers nejat
# --- Cryptographic Algorithm Restrictions (Mozilla Modern / ssh-audit A+ Grade) ---
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com
# --- Attack Surface Reduction (Disable Unused Forwarding & X11) ---
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding local
PermitTunnel no
MaxAuthTries 3
MaxSessions 4
LoginGraceTime 20
ClientAliveInterval 300
ClientAliveCountMax 2
Validate the configuration before reloading sshd (keep your existing SSH terminal open while testing a new connection in a second terminal!):
# 1. Strip weak Diffie-Hellman moduli (< 3071 bits) from /etc/ssh/moduli
sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.safe >/dev/null
sudo mv /etc/ssh/moduli.safe /etc/ssh/moduli
# 2. Validate sshd syntax and effective configuration before reloading
sudo sshd -t && sudo systemctl reload ssh
3. Kernel Exploit & Network Stack Hardening (/etc/sysctl.d/)
Apply kernel-level protections against pointer leaks, unprivileged ptrace process injection, symlink/hardlink race conditions in /tmp, and ICMP redirect MITM attacks:
# --- Kernel Memory & Pointer Leak Protection ---
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.perf_event_paranoid = 3
kernel.unprivileged_bpf_disabled = 1
net.core.bpf_jit_harden = 2
dev.tty.ldisc_autoload = 0
# --- Restrict ptrace() to Direct Parent Processes Only (Blocks Credential Dumping) ---
kernel.yama.ptrace_scope = 1
# --- Prevent Hardlink/Symlink Race Condition Exploits in World-Writable Directories ---
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
fs.protected_fifos = 2
fs.protected_regular = 2
fs.suid_dumpable = 0
# --- Network Stack Anti-Spoofing & DoS Hardening ---
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
Apply immediately via sudo sysctl --system.
4. Stateful Host Firewalling with nftables (/etc/nftables.conf)
Replace legacy iptables scripts with an atomic dual-stack (inet family covers both IPv4 and IPv6 simultaneously) nftables ruleset:
#!/usr/sbin/nft -f
flush ruleset
table inet host_firewall {
chain input {
type filter hook input priority filter; policy drop;
# 1. Accept loopback traffic and drop spoofed loopback packets on physical NICs
iif "lo" accept
iif != "lo" ip daddr 127.0.0.0/8 counter drop
iif != "lo" ip6 daddr ::1/128 counter drop
# 2. Accept established/related connections and drop invalid conntrack states
ct state vmap { established : accept, related : accept, invalid : drop }
# 3. Accept essential ICMPv4 and ICMPv6 (Neighbor Discovery / PMTUD is mandatory for IPv6!)
ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded } limit rate 10/second accept
ip6 nexthdr icmpv6 icmpv6 type { echo-request, destination-unreachable, packet-too-big, time-exceeded, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
# 4. Rate-Limit Inbound SSH (Max 6 new SYN connections per minute per source IP)
tcp dport 22 ct state new meter ssh_ratelimit { ip saddr limit rate 6/minute burst 3 packets } accept
# 5. Accept Public HTTPS / HTTP/3 Ingress (if running Edge Reverse Proxy)
tcp dport { 80, 443 } accept
udp dport 443 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
Enable and load the ruleset atomically:
sudo nft -c -f /etc/nftables.conf && sudo systemctl enable --now nftables
5. Kernel Syscall Auditing (auditd) & Automated CIS Auditing (lynis)
Install auditd and lynis (sudo apt install auditd lynis) to record immutable kernel audit trails whenever sensitive files (/etc/passwd, /etc/shadow, /etc/sudoers, /etc/ssh/sshd_config) are modified or privileged commands are executed:
# Delete existing rules and increase kernel audit buffer to 8192 events
-D
-b 8192
# Monitor modifications (write 'w' or attribute change 'a') to identity & privilege files
-w /etc/passwd -p wa -k identity_tamper
-w /etc/shadow -p wa -k identity_tamper
-w /etc/group -p wa -k identity_tamper
-w /etc/sudoers -p wa -k sudoers_tamper
-w /etc/sudoers.d/ -p wa -k sudoers_tamper
-w /etc/ssh/sshd_config -p wa -k sshd_tamper
-w /etc/ssh/sshd_config.d/ -p wa -k sshd_tamper
# Make the audit configuration immutable until next reboot (-e 2)
-e 2
Load the audit rules and run a full system hardening audit with lynis:
# 1. Compile and load /etc/audit/rules.d/*.rules into the kernel
sudo augenrules --load
# 2. Search kernel audit logs for any modifications to sudoers or identity files
sudo ausearch -k sudoers_tamper -k identity_tamper -i
# 3. Execute a comprehensive local security audit and view the Hardening Index score
sudo lynis audit system --quick