Zum Inhalt

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 / FIDO2 ed25519-sk), kernel /etc/sysctl.d/ network and memory exploit mitigations, stateful nftables host firewalling, behavioral intrusion prevention (CrowdSec / Fail2ban), and Linux Kernel Audit (auditd) + Mandatory Access Control (AppArmor / SELinux).

  • OpenSSH Cryptographic Lockdown


    Restrict sshd to curve25519-sha256, chacha20-poly1305, and ssh-ed25519 / FIDO2 hardware keys (ed25519-sk) while disabling root and password auth.

  • Stateful nftables Perimeter


    Enforce a default-drop ingress policy with rate-limited ICMPv4/ICMPv6, invalid connection-state dropping, and dynamic threat-intel IP sets.

  • Kernel sysctl Exploit 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 (auditd rules on /etc/shadow and execve), 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:

/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!):

Removing Small Diffie-Hellman Moduli & Validating sshd Syntax
# 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:

/etc/sysctl.d/99-cis-kernel-hardening.conf
# --- 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:

/etc/nftables.conf
#!/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:

Validating & Enabling nftables
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:

/etc/audit/rules.d/50-sovereign-hardening.rules
# 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:

Loading auditd Rules, Searching Audit Logs & Running Lynis CIS Audit
# 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