Currently Available: Need a skilled Software Developer for your next project?
Categories
Linux Servers

How to Make sysctl Kernel Settings Persist Across Reboots on Debian and Ubuntu

On Debian and Ubuntu, sysctl lets you read and change kernel parameters, which control parts of Linux behavior such as network routing. When you change a value while Linux is running, the kernel uses the new value until reboot. The change alone does not save the value for the next boot.

On systems running systemd, save settings you want to persist in a .conf file under /etc/sysctl.d/. At boot, systemd-sysctl reads those files and applies the values. To apply a saved change now, restart the service and read the parameter again to check the result.

Save the setting in /etc/sysctl.d/

First, check the parameter’s current value and make sure the setting fits the machine’s role. For example:

sysctl net.ipv4.ip_forward

The net.ipv4.ip_forward parameter controls whether the kernel forwards IPv4 traffic between network interfaces. Set it to 1 only when the host is meant to route traffic and its network configuration calls for forwarding. Kernel parameters vary by kernel version and configuration, so check the relevant kernel documentation before changing a value.

Create a local configuration file:

sudoedit /etc/sysctl.d/99-local.conf

Add one name = value assignment per line. For example:

# Example only: enable IPv4 forwarding on a host configured to route traffic
net.ipv4.ip_forward = 1

The filename must end in .conf. Blank lines and lines beginning with # or ; are ignored. The systemd sysctl.d documentation describes the file format and how the boot-time loader reads these settings.

Apply and verify the change

Saving the file does not change the live kernel value. Restart the systemd service to apply the settings now:

sudo systemctl restart systemd-sysctl

Then read the parameter again:

sysctl net.ipv4.ip_forward

The result confirms the current runtime value. Rebooting and checking the value again confirms that the boot-time loader applies the saved setting. The systemd-sysctl manual documents restarting the service to reapply sysctl settings.

Check which file sets a value

Systemd reads .conf files from its sysctl configuration directories in filename order. If two files set the same parameter, the setting in the later filename takes precedence. An /etc/sysctl.d/ file with the same name as a vendor file replaces that vendor file. A name such as 99-local.conf makes the intended ordering visible, but inspect existing files before assuming it wins.

To find conflicting settings, search the files under /etc/sysctl.d/ and the vendor configuration directories for the parameter name. If a file installed by a vendor sets a value you want to disable, systemd supports a same-name symlink under /etc/sysctl.d/ that points to /dev/null. Check what the vendor file changes before using that override.

Do not rely on /etc/sysctl.conf to keep settings across Debian releases. The procps utility’s sysctl --system command reads that file, but systemd-sysctl does not. Debian 13’s release notes call out the change for systems that previously relied on /etc/sysctl.conf. Use /etc/sysctl.d/*.conf for settings that the systemd boot-time loader must apply.

Troubleshoot settings that do not stick

If a value changes after restart or reboot, check for another file that sets the same parameter and compare the filenames. A service or kernel module that starts later can also change a value after systemd-sysctl applies it. Compare the value just after boot with its value after that service or module starts.

A kernel module, a piece of code loaded into the running kernel, can make a parameter available only after the module loads. The boot-time loader may run before then. The systemd documentation describes applying these settings with a udev rule, which runs when the module appears, or loading the module before sysctl settings are applied. If the parameter is missing or rejected, check whether it exists for the running kernel and whether its module has loaded.

A successful service restart alone does not prove that every requested value took effect. Some permission errors and attempts to write to parameters that do not exist are logged at debug level, a detailed logging level, without causing the service to fail. Read back each setting you care about, and verify it again after reboot.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *