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


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


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.



Disable automatic loading TTY line disciplines that rarely anyone uses:

dev.tty.ldisc_autoload = 0

See commit 7c0cca7c847e6e0 introducing the sysctl.


Do not allow O_CREAT open on FIFOs in world-writable, sticky directories:

fs.protected_fifos = 2

See fs.protected_fifos (kernel docs)


Do not allow O_CREAT open on regular files in world-writable, sticky directories:

fs.protected_regular = 2

See fs.protected_regular (kernel docs)


Restrict access to kernel logs via dmesg to super users (CAP_SYSLOG):

kernel.dmesg_restrict = 1

See kernel.dmesg_restrict (kernel docs)


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

See kernel.kexec_load_disabled (kernel docs)


Do not expose any kernel pointer via /proc/:

kernel.kptr_restrict = 2

See kernel.kptr_restrict (kernel docs)


Do not allow unprivileged users to load eBPF programs (via bpf(2)):

kernel.unprivileged_bpf_disabled = 1

See kernel.unprivileged_bpf_disabled (kernel docs)


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

See kernel.yama.ptrace_scope (kernel docs)


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.

See kernel.panic_on_oops (kernel docs)


Do not allow unprivileged user to create user namespaces:

kernel.unprivileged_userns_clone = 0


This sysctl option was not accepted upstream but is carried by many distrubitons including Debian.


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.

See unprivileged_userns_clone patch


Enable BPF JIT compiler hardening for all users:

net.core.bpf_jit_harden = 2

See net.core.bpf_jit_harden (kernel docs)


Disable user namespaces entirely:

user.max_user_namespaces = 0

User namespaces don’t have the best security track record.


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.



Disallow any unprivileged use of perf events:

kernel.perf_event_paranoid = 3


Patch for support of value 3 for this setting has been declined upstream bun many distribution, including Debian, carry it.



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:

while echo $((i+1)) >/proc/sys/vm/mmap_rnd_bits 2>/dev/null; do ((i++)); done;
echo $i

See vm.mmap_rnd_bits (kernel docs)


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:

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.

See vm.mmap_rnd_compat_bits (kernel docs)


Do not allow unprivileged users to handle page faults:

vm.unprivileged_userfaultfd = 0

See vm.unprivileged_userfaultfd (kernel docs)

Other Resources