aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:11 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-29 11:18:11 +0100
commit75e84558ea71f14adbaa1a461cd5f6e8793b0470 (patch)
tree23419e4c9612752b3610cb1936f19b019a71375b
parent368f2aa6a09d7314b169f87e2a1466ed5a301a77 (diff)
downloaddotfiles-75e84558ea71f14adbaa1a461cd5f6e8793b0470.tar.gz
dotfiles-75e84558ea71f14adbaa1a461cd5f6e8793b0470.tar.bz2
dotfiles-75e84558ea71f14adbaa1a461cd5f6e8793b0470.zip
feat(sysctl): kernel info-disclosure + ICMP/IPv6 RA hardening
Adds standard KSPP-style sysctl hardening that does not interfere with the existing dev workflow: - kptr_restrict=2, unprivileged_bpf_disabled=1, bpf_jit_harden=2 - kexec_load_disabled=1 (no kexec in use) - fs.suid_dumpable=0 - ICMP broadcast/bogus-error ignores - tcp_timestamps=0 (BBR+cake do not need RFC1323 timestamps) - IPv6 RA disabled at kernel layer (systemd-networkd is authoritative) - explicit tcp_syncookies=1 Drops 'kernel.yama.ptrace_scope = 0' so the kernel default 1 (parent only) applies. Debugging own builds via 'gdb ./a.out', 'lldb -- ./bin', 'rust-gdb' still works; only attach-by-PID now needs sudo, accepted trade-off. Intentionally kept dev-permissive: kernel.sysrq=1, kernel.dmesg_restrict=0, kernel.perf_event_paranoid=-1
-rw-r--r--etc/sysctl.d/99-sysctl.conf40
1 files changed, 39 insertions, 1 deletions
diff --git a/etc/sysctl.d/99-sysctl.conf b/etc/sysctl.d/99-sysctl.conf
index 3177c28..3a43da9 100644
--- a/etc/sysctl.d/99-sysctl.conf
+++ b/etc/sysctl.d/99-sysctl.conf
@@ -1,6 +1,13 @@
+# Dev concessions (intentionally not hardened):
+# kernel.sysrq=1 — emergency reboot from a frozen Sway session.
+# kernel.dmesg_restrict=0 — read dmesg as user during driver/kernel debug.
+# kernel.perf_event_paranoid=-1 — `perf record` on own user-space binaries
+# without sudo. Kernel-space tracepoints still need root.
+# kernel.yama.ptrace_scope is left at the kernel default (1, parent-only),
+# which keeps `gdb ./a.out`, `lldb -- ./bin`, `rust-gdb target/...` working;
+# attach-by-PID (`gdb -p`) requires sudo.
kernel.sysrq = 1
kernel.dmesg_restrict = 0
-kernel.yama.ptrace_scope = 0
kernel.perf_event_paranoid = -1
net.core.netdev_max_backlog = 16384
net.core.somaxconn = 8192
@@ -30,3 +37,34 @@ net.ipv4.conf.default.send_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
+
+# Info-disclosure / kernel-surface hardening
+# Hide kernel pointers from /proc and dmesg even with read access.
+kernel.kptr_restrict = 2
+# Block unprivileged eBPF program loading (bpftrace as non-root, etc.).
+# We don't run BPF programs against the system kernel; own user-space
+# profiling via `perf` is unaffected.
+kernel.unprivileged_bpf_disabled = 1
+# Harden the BPF JIT against spectre-style speculative leaks.
+net.core.bpf_jit_harden = 2
+# We never use kexec; disabling permanently closes a rootkit persistence
+# vector. Cannot be re-enabled until reboot once set.
+kernel.kexec_load_disabled = 1
+# SUID processes cannot produce core dumps (prevents leaking secrets).
+fs.suid_dumpable = 0
+
+# ICMP / TCP hygiene
+# Reaffirm syncookie defence (default on, explicit anyway).
+net.ipv4.tcp_syncookies = 1
+# Drop broadcast pings and bogus ICMP errors (smurf-style amplification).
+net.ipv4.icmp_echo_ignore_broadcasts = 1
+net.ipv4.icmp_ignore_bogus_error_responses = 1
+# Disable TCP timestamps — minor uptime/fingerprint info leak; modern
+# congestion control (BBR + cake) does not depend on RFC1323 timestamps.
+net.ipv4.tcp_timestamps = 0
+
+# IPv6 router advertisements are handled by systemd-networkd; ignore RA
+# at the kernel layer in case networkd is bypassed or an attacker forges
+# rogue RAs on a hostile network.
+net.ipv6.conf.all.accept_ra = 0
+net.ipv6.conf.default.accept_ra = 0