LinuxX · Kernel Managementsysctl
sysctl — runtime kernel tuning
What you'll learn
- Read current sysctl values
- Set sysctl values at runtime and persistently
- Identify the most production-relevant sysctl parameters
- Troubleshoot sysctl values that did not persist
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
The kernel exposes hundreds of tunable parameters through the
/proc/sys/ filesystem. Reading and setting these parameters is
how a sysadmin tunes the kernel at runtime — no recompile, no
reboot, just a sysctl call.
Reading sysctl values
$ sysctl net.ipv4.ip_forward; sysctl -a | head -10net.ipv4.ip_forward = 0
abi.vsyscall32 = 1
debug.exception-trace = 1
dev.hpet.max-user-freq = 64
dev.parport.default = 0x3bc
...Illustrative output
The sysctl namespace mirrors the /proc/sys/ directory:
net.ipv4.ip_forward = /proc/sys/net/ipv4/ip_forward
vm.swappiness = /proc/sys/vm/swappiness
kernel.pid_max = /proc/sys/kernel/pid_max
$ sysctl net.ipv4.tcp_syncookies net.ipv4.conf.all.rp_filter net.core.somaxconn vm.swappinessnet.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.core.somaxconn = 4096
vm.swappiness = 60Illustrative output
Setting at runtime
$ sudo sysctl -w net.ipv4.ip_forward=1net.ipv4.ip_forward = 1Illustrative output
Persisting changes
There are three places to put persistent sysctl values:
/etc/sysctl.conf— the legacy single-file configuration./etc/sysctl.d/*.conf— the modern modular configuration. Each file is read in lexical order.- Runtime drop-ins via
systemd-sysctlfor transient values.
$ sudo tee /etc/sysctl.d/99-production.conf >/dev/null <<'EOF'
# Production sysctl overrides
# Network: enable IP forwarding (for router/gateway hosts)
net.ipv4.ip_forward = 1
# TCP: harden against SYN flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096
# Reverse-path filtering
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Kernel: allow more PIDs for high-forking services
kernel.pid_max = 4194304
# VM: tune swappiness for database hosts
vm.swappiness = 10
EOF
sudo sysctl --systemProduction-relevant sysctl parameters
| Subsystem | Parameter | Meaning | Production value |
|---|---|---|---|
| net.ipv4 | ip_forward | IP forwarding | 1 for routers/gateways, 0 otherwise |
| net.ipv4 | tcp_syncookies | SYN flood protection | 1 (enable) |
| net.ipv4 | conf.all.rp_filter | Reverse-path filtering | 1 (enable) |
| net.ipv4 | conf.all.accept_source_route | Source-routed packets | 0 (disable) |
| net.ipv4 | conf.all.accept_redirects | Accept ICMP redirects | 0 everywhere, routers included |
| net.ipv4 | conf.all.secure_redirects | Accept redirects from default gateways only | 0 — narrower than accepting all, still unauthenticated |
| net.ipv4 | conf.all.send_redirects | Emit ICMP redirects | 0 on hosts; 1 only on a router that is deliberately the redirect authority for its segment |
| net.ipv4 | icmp_echo_ignore_broadcasts | Ignore pings to broadcast | 1 (smurf protection) |
| net.ipv4 | tcp_max_syn_backlog | SYN backlog | 4096+ for high-traffic |
| net.core | somaxconn | listen() backlog | 4096+ for high-traffic |
| kernel | pid_max | Maximum PID | 4194304 for high-forking |
| kernel | threads-max | Maximum threads | pid_max × 4 typically |
| vm | swappiness | Swap preference | 10-60 depending on workload |
| fs | file-max | Maximum open files | matches systemd LimitNOFILE |
| fs | nr_open | Maximum per-process open files | matches systemd LimitNOFILE |
$ systemd-sysctlAug 9 12:00:01 host systemd-sysctl[1234]: Successfully applied sysctl: net.ipv4.ip_forward=1
Aug 9 12:00:01 host systemd-sysctl[1234]: Successfully applied sysctl: kernel.pid_max=4194304
...Illustrative output
Investigating “sysctl did not persist”
$ sudo sysctl net.ipv4.ip_forward; cat /proc/sys/net/ipv4/ip_forward; sudo sysctl --system 2>&1 | head...Illustrative output
- Read the current value before changing:
sysctl KEY - Set at runtime to test:
sysctl -w KEY=VALUE - Persist in /etc/sysctl.d/ with a high-priority filename (90-, 99-)
- **Apply with
sysctl --system** and verify the value is now what you want - Add the file to version control (git, etckeeper, configuration management)
- Document the rationale for non-default values; future operators need to know why
Knowledge check
Knowledge check · 3 questions
Q1. Which is the correct way to persist a sysctl change across reboots?
Q2. `net.ipv4.ip_forward = 1` should be set on every Linux host.
Q3. Which of the following are correct sysctl practices? Select all that apply.
Passing score: 75%. Answers are checked in this browser.