Kernel Hardening via Sysctl¶
Using sysctl
¶
Settings that can be modified via /proc/ filesystem or sysctl(8).
Example sysctl config (/etc/sysctl.d/50-custom.conf
):
kernel.dmesg_restrict = 1
fs.protected_symlinks = 1
Load config:
sysctl -p /etc/sysctl.d/50-custom.conf
Tip
On Debian, the package hardening-runtime can be installed which
configures many of this parameters for you. Look at
/usr/lib/sysctl.d/10-hardening.conf
after installing it.
Sysctl Parameters¶
abi.vsyscall32¶
Disable VDSO for 32 bit syscalls:
abi.vsyscall32 = 0
This setting is only meaningful on 64 bit architectures and will likely break any 32 bit application. Luckily those no longer really exist.
See:
dev.tty.ldisc_autoload¶
Disable automatic loading TTY line disciplines that rarely anyone uses:
dev.tty.ldisc_autoload = 0
See commit 7c0cca7c847e6e0 introducing the sysctl.
fs.protected_fifos¶
Do not allow O_CREAT open on FIFOs in world-writable, sticky directories:
fs.protected_fifos = 2
fs.protected_regular¶
Do not allow O_CREAT open on regular files in world-writable, sticky directories:
fs.protected_regular = 2
fs.protected_symlinks¶
Do not blindly follow symlinks in stick, world-writable directories (like /tmp/):
fs.protected_symlinks = 1
fs.protected_hardlinks¶
Only allow creation of hardlinks when user has read/write access:
fs.protected_hardlinks = 1
kernel.dmesg_restrict¶
Restrict access to kernel logs via dmesg
to super users (CAP_SYSLOG):
kernel.dmesg_restrict = 1
kernel.kexec_load_disabled¶
Do not allow a new kernel to be loaded via kexec(8) in order to skip hardware initialization during reboot:
kernel.kexec_load_disabled = 1
kernel.kptr_restrict¶
Do not expose any kernel pointer via /proc/
:
kernel.kptr_restrict = 2
kernel.unprivileged_bpf_disabled¶
Do not allow unprivileged users to load eBPF programs (via bpf(2)):
kernel.unprivileged_bpf_disabled = 1
kernel.yama.ptrace_scope¶
Only allow admins to attach via ptrace:
kernel.yama.ptrace_scope = 2
Only allow admins and parent processes to attach via ptrace:
kernel.yama.ptrace_scope = 1
Disable ptrace attachment entirely (reboot required to undo):
kernel.yama.ptrace_scope = 3
kernel.panic_on_oops¶
Trigger a kernel panic on BUG and oops:
kernel.panic_on_oops = 1
This will make certain attacks harder as it will be harder to corrupt the kernel. Drawback is that DoS attacks may be easier to carry out as the kernel is more likely to panic.
Set kernel.panic also to force a reboot on panic.
kernel.unprivileged_userns_clone¶
Do not allow unprivileged user to create user namespaces:
kernel.unprivileged_userns_clone = 0
Note
This sysctl option was not accepted upstream but is carried by many distrubitons including Debian.
Note
Some application use an unprivileged user namespace for sandboxing, including Firefox, and thus disabling this feature may weaken sandboxes. When unprivileged user namespaces aren’t used they can be safely disabled. If they are used, consider restricting access by critical services using RestrictNamespaces=user.
net.core.bpf_jit_harden¶
Enable BPF JIT compiler hardening for all users:
net.core.bpf_jit_harden = 2
user.max_user_namespaces¶
Disable user namespaces entirely:
user.max_user_namespaces = 0
User namespaces don’t have the best security track record.
Note
Some processes may relay on this feature for sandboxing. See also note on kernel.unprivileged_userns_clone.
This will also render the (rarely used) PrivateUser systemd directive ineffective.
See:
kernel.unprivileged_userns_clone (disable unprivileged user namespaces only)
kernel.perf_event_paranoid¶
Disallow any unprivileged use of perf events:
kernel.perf_event_paranoid = 3
Note
Patch for support of value 3
for this setting has been
declined upstream bun many distribution, including Debian,
carry it.
See:
vm.mmap_rnd_bits¶
Increase entropy used to map memory randomly:
vm.mmap_rnd_bits = 32
A higher value indicates higher entropy. Obtain the highest allowed value like this:
i=$(</proc/sys/vm/mmap_rnd_bits)
while echo $((i+1)) >/proc/sys/vm/mmap_rnd_bits 2>/dev/null; do ((i++)); done;
echo $i
vm.mmap_rnd_compat_bits¶
Increase entropy used to map memory randomly in compat mode:
vm.mmap_rnd_compat_bits = 16
A higher value indicates higher entropy. Obtain the highest allowed value like this:
i=$(</proc/sys/vm/mmap_rnd_compat_bits)
while echo $((i+1)) >/proc/sys/vm/mmap_rnd_compat_bits 2>/dev/null; do ((i++)); done;
echo $i
This is only useful on architectures with a compatibility mode. For instance, on x86_64 which has an x86 compatibility mode.
vm.unprivileged_userfaultfd¶
Do not allow unprivileged users to handle page faults:
vm.unprivileged_userfaultfd = 0
Other Resources¶
Kernel Self Protection Project has recommendation for compile-time, boot-time and run-time parameters.