Service Hardening
SocketBindAllow setting
Allow systemd units to use system call bind() on sockets specified with the unit setting SocketBindAllow.
Summary
Why and when to use SocketBindAllow
The setting SocketBindAllow is used together with SocketBindDeny and defines restrictions on the usage of the system call bind on a network socket.
Settings
Both SocketBindAllow and SocketBindDeny use a bind-rule. See SocketBindDeny for the details.
Generic advice
This setting is useful in combination with SocketBindDeny to create an allow-list.
Examples
Allow binding on TCP port 80
SocketBindDeny setting
Restrict systemd units to use system call bind() on sockets specified with the unit setting SocketBindDeny.
Summary
Why and when to use SocketBindDeny
The setting SocketBindDeny can be used alone or together with SocketBindAllow to set restrictions on the usage of the system call bind on a network socket.
Settings
If the SocketBindDeny list is used alone, then it is a deny-list. Everything except the defined ports/protocols will be allowed.
By defining the value ‘any’, all combinations are denied. This is typically used in combination with SocketBindAllow to open up one or more ports.
DevicePolicy setting
Restrict systemd units to access devices in the /dev directory with the unit setting DevicePolicy.
Summary
Why and when to use DevicePolicy
The setting DevicePolicy aims to reduce access to devices in /dev. By default, there is no limitation to access devices.
Settings
The value strict is the most strict, as the name implies. This is suitable for services that do not need any access, like custom shell scripts. Unless output is being redirect to /dev/null, then access could be granted with DeviceAllow=/dev/null.
Generic advice
Aim for using ‘strict’ when possible and define entries that should be allowed. To discover files used by a binary, consider inspecting it with the strings command or look at open files from a running process with lsof.
DeviceAllow setting
Restrict systemd units to access devices in the /dev directory with the unit setting DeviceAllow.
Summary
Why and when to use DeviceAllow
The setting DeviceAllow aims to reduce access or its level to devices in /dev. By default, there is no limitation to access devices.
Settings
Define DeviceAllow with the path and access level.
DeviceAllow=/dev/sda3 r
General advice
For most services it might be easier to use ProtectDevices=yes to reduce the devices that can be access.
MemoryDenyWriteExecute setting
Block the ability for systemd units to create or alter memory segments to become writable and executable as well with the unit setting MemoryDenyWriteExecute.
Summary
Why and when to use MemoryDenyWriteExecute
The setting MemoryDenyWriteExecute will block the creation or alteration of a memory segment to become writable and executable as well. By enabling this limitation, it will increase the bar software exploits to change running code dynamically.
Usage
[Service]
MemoryDenyWriteExecute=yes
InaccessiblePaths=/dev/shm
SystemCallFilter=~memfd_create
Caveats
To prevent circumvention of this setting, access to /dev/shm and the syscall memfd_create should be blocked as well.
Generic advice
For most common services this option can be implemented and will increase the security of a service. That is, if used together with InaccessiblePaths and SystemCallFilter.
InaccessiblePaths setting
Block systemd units to access specified paths with the unit setting InaccessiblePaths.
Summary
Why and when to use InaccessiblePaths
The setting InaccessiblePaths defines paths that should never be accessible. Instead of using the principles of an allow list, it is an explicit deny list. It can be used to block access by a process to a location with sensitive data or a path commonly misused for exploits.
ReadWritePaths setting
Grant systemd units to specified paths to read from and write to new or existing files with the unit setting ReadWritePaths.
Summary
Why and when to use ReadWritePaths
The setting ReadWritePaths grants read and write permissions to defined paths. It can be used in combination with other settings like ‘ProtectSystem=strict’ to make the full file system read-only, and then open up a few paths that are required for a service to run correctly.
Values
Define the paths that are granted write access.
[Service]
ProtectSystem=strict
ReadWritePaths=/run /var/log/nginx
- When a path is prefixed with a minus (-), it is ignored if it does not exist
- When a path is prefixed with a plus (+), the path is considered relative to root of directory (e.g. configured with RootDirectory)
Caveats
This setting will not have effect if a process is missing the normal file permissions or ownership. For additional sandboxing, consider CapabilityBoundingSet=CAP_SYS_ADMIN or SystemCallFilter=@mount.
RestrictAddressFamilies setting
Restrict systemd units using only specified socket address families with the unit setting RestrictAddressFamilies.
Summary
Why and when to use RestrictAddressFamilies
The setting RestrictAddressFamilies aims to restrict what socket address families can be used. When using it, the default is that it is used as an allow-list and define what address families can be used.
Settings
When this setting is not configured, there are no restrictions to what address families can be used.
Setting the value to none will block all address families.
To block specific address families only, a ~ can be used to turn the allow-list into a deny-list.
ProtectProc setting
Restrict systemd units to access information from the /proc directory with the unit setting ProtectProc.
Summary
Why and when to use ProtectProc
The setting ProtectProc aims to protect information that normally can be retrieved from /proc.
Settings
The value default, which is also the default, will not restrict access. Value invisible will hide information, where ptraceable restrict the set to only processes that be monitored with the system call ptrace(). The value noaccess is the most strict option.
Caveats
This setting will not have effect if the kernel does not support the hidepid mount option per individual mount point.
ProtectKernelModules setting
Restrict systemd units to load kernel modules with the ProtectKernelModules unit setting.
Summary
Explanation
Kernel modules can provide additional functionality when using a modular Linux kernel, which is applicable to most systems. When this setting is set to yes, it tries to prevent the unit from loading kernel modules. This is achieved by removing the CAP_SYS_MODULE from the capability bounding set.
Generic advice
Most units do not need the permission to load kernel modules, so typically a unit can be configured with ProtectKernelModules=true.