Displaying and amending kernel parameters

What is sysctl?

The "sysctl" command is used to display and amend kernel parameters on a Linux system. The kernel parameters are generally set at boot time and are read from a file called:
"/etc/sysctl.conf".

The "sysctl" command is used to modify these parameters at run time.

/etc/sysctl.conf

The "sysctl.conf" file is used to configure kernel parameters on a Linux system. A directory called "/etc/sysctl.d" is also available to store custom kernel settings.


#
# /etc/sysctl.conf - Configuration file for setting system variables
# See /etc/sysctl.d/ for additional system variables.
# See sysctl.conf (5) for information.
#

#kernel.domainname = example.com

# Uncomment the following to stop low-level messages on console
#kernel.printk = 3 4 1 3

##############################################################3
# Functions previously found in netbase
#

# Uncomment the next two lines to enable Spoof protection (reverse-path filter)
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.all.rp_filter=1

# Uncomment the next line to enable TCP/IP SYN cookies
# See http://lwn.net/Articles/277146/
# Note: This may impact IPv6 TCP sessions too
#net.ipv4.tcp_syncookies=1

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1


###################################################################
# Additional settings - these settings can improve the network
# security of the host and prevent against some network attacks
# including spoofing attacks and man in the middle attacks through
# redirection. Some network environments, however, require that these
# settings are disabled so review and enable them as needed.
#
# Do not accept ICMP redirects (prevent MITM attacks)
#net.ipv4.conf.all.accept_redirects = 0
#net.ipv6.conf.all.accept_redirects = 0
# _or_
# Accept ICMP redirects only for gateways listed in our default
# gateway list (enabled by default)
# net.ipv4.conf.all.secure_redirects = 1
#
# Do not send ICMP redirects (we are not a router)
#net.ipv4.conf.all.send_redirects = 0
#
# Do not accept IP source route packets (we are not a router)
#net.ipv4.conf.all.accept_source_route = 0
#net.ipv6.conf.all.accept_source_route = 0
#
# Log Martian Packets
#net.ipv4.conf.all.log_martians = 1
#

###################################################################
# Magic system request Key
# 0=disable, 1=enable all, >1 bitmask of sysrq functions
# See https://www.kernel.org/doc/html/latest/admin-guide/sysrq.html
# for what other values do
#kernel.sysrq=438

Displaying kernel settings

To view the current kernel settings, you can use the "sysctl -a" command as shown below. You can also combine this command with "grep" to filter out other settings.

Below is only a small section of the output.


$ sysctl -a
abi.vsyscall32 = 1
debug.exception-trace = 1
debug.kprobes-optimization = 1
dev.cdrom.autoclose = 1
dev.cdrom.autoeject = 0
dev.cdrom.check_media = 0
dev.cdrom.debug = 0
dev.cdrom.info = CD-ROM information, Id: cdrom.c 3.20 2003/12/17
dev.cdrom.info = 
dev.cdrom.info = drive name:		sr0
dev.cdrom.info = drive speed:		12
dev.cdrom.info = drive # of slots:	1
dev.cdrom.info = Can close tray:		1
dev.cdrom.info = Can open tray:		1
dev.cdrom.info = Can lock tray:		1

If you want to only display specific configurations, you can combine the "sysctl" command with "grep".

If we wanted to view the tcp keep alive settings on our system, we could construct a command similar to the one below:

sysctl -a | grep net.ipv4.tcp_keepalive


# sysctl -a | grep net.ipv4.tcp_keepalive
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 7200

If you know the name of the kernel setting that you want to configure, you can pass the name after the "sysctl" command. For example, If we want to check the following kernel setting for "icmp echo requests", we could issue the following command:
sysctl net.ipv4.icmp_echo_ignore_all


# sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 0

The above "net.ipv4.icmp_echo_ignore_all" kernel parameter has a value of zero "0". This means that our system will respond to an ICMP ping command.

We can demonstrate this by issuing the ping command "ping 192.168.122.76 -c1". We should receive a reply back from the remote server back to my Linux Mint system.


root@mint01a:~# ping 192.168.122.76 -c1
PING 192.168.122.76 (192.168.122.76) 56(84) bytes of data.
64 bytes from 192.168.122.76: icmp_seq=1 ttl=64 time=0.449 ms

--- 192.168.122.76 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.449/0.449/0.449/0.000 ms

Changing a kernel setting

As we have seen, we can view kernel settings by using the "sysctl" command, however, if we needed to change a setting, we can use the same command, however, we need to supply the "-w" flag.

sysctl -w

In the example below, I will amend the "ICMP echo" setting to disable any responses back from the ICMP ping command. To do this, I need to issue the following command as the "root" user.

sysctl -w net.ipv4.icmp_echo_ignore_all=1


[root@client01a ~]# sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 0

[root@client01a ~]# sysctl -w net.ipv4.icmp_echo_ignore_all = 1

[root@client01a ~]# sysctl -w net.ipv4.icmp_echo_ignore_all=1
net.ipv4.icmp_echo_ignore_all = 1

# sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 1

From the above, we can see that the new value has now been applied. The value of "1" will disable icmp echo requests. To prove this, we can now issue the "ping" command against the remote server again. This time it should not respond back.


root@mint01a:~# ping 192.168.122.76 -c1
PING 192.168.122.76 (192.168.122.76) 56(84) bytes of data.

--- 192.168.122.76 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

From the above, we can see that there was no response back from the remote server. A "100%" packet loss was reported.

IMPORTANT: The "-w parameter is only a temporary setting. The changes you have made will not survive a reboot. To make these settings permanent, we need to add the setting into the "/etc/sysctl.conf" file or add an entry into the "/etc/sysctl.d" directory.

Making permanent kernel setting changes

To make any kernel settings survive a system reboot, the actual setting needs to be added in to one of the following locations:

/etc/sysctl.conf or /etc/sysctl.d

In the example below, we will make the "ICMP echo" change permanent.

To demonstrate this example, I have enabled the "icmp echo request" again with the following command:


[root@client01a ~]# sysctl -w net.ipv4.icmp_echo_ignore_all=0
net.ipv4.icmp_echo_ignore_all = 0

[root@client01a ~]# sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 0

Next, I will create a file called "99-custom.conf" in the directory "/etc/sysctl.d".


[root@client01a sysctl.d]# pwd
/etc/sysctl.d

[root@client01a sysctl.d]# ls -l 99-custom.conf 
-rw-r--r--. 1 root root 32 Jun  1 13:44 99-custom.conf

[root@client01a sysctl.d]# cat 99-custom.conf 
net.ipv4.icmp_echo_ignore_all=1

To make this setting live, we have to instruct the system to read its kernel setting file. To do this we issue the following command:

sysctl -p /etc/sysctl.d/99-custom.conf

The above command will load in the settings found in the specified location "/etc/sysctl.d. This method is frequently used for making changes as it avoids having to reboot your system to pick up the changes.

In the example below, we will first check the current value and then reload the kernel settings with the "sysctl -p /etc/sysctl.d/99-custom.conf" command. We will then check to see that the value has now been set.


[root@client01a sysctl.d]# sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 0

[root@client01a sysctl.d]# sysctl -p /etc/sysctl.d/99-custom.conf
net.ipv4.icmp_echo_ignore_all = 1

[root@client01a sysctl.d]# sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 1

As a test, I have rebooted the remote server and checked that the settings have survived the reboot.


[root@client01a ~]# uptime
 14:07:49 up 0 min,  1 user,  load average: 0.54, 0.15, 0.05

[root@client01a ~]# sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 1

As you can see from the above, the server has been rebooted and our icmp setting is still in place.