Let’s first define what sysctl is, and I usually go to Wikipedia for some great definitions, so, from Wikipedia we have:
Sysctl is an interface for examining and dynamically changing parameters in the BSD and Linux operating systems. The implementation mechanism in these two systems is very different.
In BSD these parameters are generally objects in a management information base (MIB) that describe tunable limits such as the size of a shared memory segment, the number of threads the operating system will use as an NFS client, or the maximum number of processes on the system; or describe, enable or disable behaviors such as IP forwarding, security restrictions on the superuser (the “securelevel”), or debugging output.
In Linux the sysctl interface mechanism is also exported as part of procfs under the sys directory. This difference means checking the value of some parameter requires opening a file in a virtual filesystem, reading its contents, parsing them and closing the file. The sysctl system call does exist on Linux, but does not have a wrapping function in glibc and is not recommended for use.
Some differences about how sysctl work on BSD and Linux systems.
In BSD the system call is implemented directly in the kernel, as described in the sysctl(3) manual page. In Linux, the sysctl is implemented as a wrapper around file system routines that access contents of files in the /proc directory. The result is that it is much more expensive to use the sysctl interface in Linux. The effect of this can be easily seen with system monitoring tools. On Linux, running top and holding the spacebar to force it to refresh quickly uses large amounts of CPU time, which is not the case on BSD systems. On Linux sysctl interfaces are typically not called repeatedly or frequently in this fashion so this impact is rarely an important consideration.
OK, but basically what sysctl does, is to change “on the fly” kernel parameters, that let the user fine tune the kernel itself, without the need to rebuild the kernel, and reboot the computer.
As you may imply from the above, it is indeed a powerful tool, and if you know how to use it, you can tweak the kernel, and the changes are applied immediately.
Read the kernel variables with sysctl
First, let’s see how to read the actual parameters with sysctl.
Run as root:
And you will a big output, these are some of the lines that command sent to the terminal of my Slackware PC.
kernel.sched_child_runs_first = 0
kernel.sched_min_granularity_ns = 2000000
kernel.sched_latency_ns = 10000000
kernel.sched_wakeup_granularity_ns = 2000000
kernel.sched_shares_ratelimit = 500000
kernel.sched_tunable_scaling = 1
kernel.sched_shares_thresh = 4
kernel.sched_migration_cost = 500000
kernel.sched_nr_migrate = 32
kernel.sched_time_avg = 1000
kernel.timer_migration = 1
kernel.sched_rt_period_us = 1000000
kernel.sched_rt_runtime_us = 950000
kernel.sched_compat_yield = 0
kernel.panic = 0
kernel.core_uses_pid = 0
kernel.core_pattern = core
kernel.core_pipe_limit = 0
kernel.tainted = 0
kernel.real-root-dev = 0
kernel.print-fatal-signals = 0
kernel.ctrl-alt-del = 0
kernel.ftrace_enabled = 1
kernel.ftrace_dump_on_oops = 0
kernel.modprobe = /sbin/modprobe
kernel.modules_disabled = 0
kernel.acct = 4 2 30
kernel.sysrq = 1
kernel.cad_pid = 1
Let’s look for some specific parameters.
sysctl -a | grep net.ipv4.icmp_echo_ignore_all
My output is:
net.ipv4.icmp_echo_ignore_all = 0
sysctl -a | grep net.ipv4.ip_forward
The output is:
net.ipv4.ip_forward = 0
Which means that my PC do respond to ping requests, but does not act as a router, or gateway by forwarding IP packets through it.
Change the kernel behaviour with sysctl
Let’s now change the way the kernel acts, in this case I will make it not to answer to ping requests.
We’ll use the -w switch to write a value to a given key variable.
sysctl -w net.ipv4.icmp_echo_ignore_all=1
In this case, this variable has logical parameters where 1 is on and 0 is off, so, with the above command we instructed the kernel to ignore all icmp echo requests.
This is immediately applied, but will only last ‘till the next boot, so it is not a permanent change.
Make sysctl changes permanent
If you want to make a change permanent, or at least until you change it again, you will need to edit or create the file /etc/sysctl.conf and add the changes there. Using our example above, we’ll make that change permanent.
So, open or create the file /etc/sysctl.conf with your favorite text editor, mine is vim
Of course you need to enter that command as root, and then add or modify the value of the variable you are interested in. In our example, we’ll add this line:
net.ipv4.icmp_echo_ignore_all = 1
Now, even if you reboot the system, your computer will not respond to ping requests.
This is really a powerful tool, use it care, there are a lot of kernel parameters you do not want to mess with, unless you really know what you are doing. Run man sysctl before you start working with it, and be informed about any variable, and what it affect before changing the value of it.