15 KiB
title | slug | date | draft | authors | tags | categories | |||||
---|---|---|---|---|---|---|---|---|---|---|---|
Security improvements | security-improvents | 2024-08-14 | false |
|
|
|
The security of a Linux system can be further improved as will be outlined in the chapters of this blog entry. These chapters will discuss how to harden the different layers of the operating system and are based on the Madaidans-insecurities page, various Linux man pages and the security considerations of PlagueOS and secureblue. Hardening the system is done to prevent as many exploits as possible. Such that in the end, you, and only you are in control of your system.
Linux Security modules
Linux Security Modules (LSM) is a framework that allows the implementation of various security models in the Linux kernel.
These security modules may be enabled by adding them to the kernel cmdline
:
... lsm=landlock,lockdown,yama,integrity ...
Landlock
Landlock (landlock
) is an access-control system that enables any processes to securely restrict themselves and their future children, i.e. sandboxing.
Lockdown
Lockdown (lockdown
) prevents both direct and indirect access to a running kernel image, attempting to protect against unauthorized modification of the kernel image and to prevent access to security and cryptographic data located in kernel memory, whilst still permitting driver modules to be loaded.
Yama
Yama (yama
) restricts the usage of ptrace
(process-trace). Where ptrace
is a system call that enables the tracing of a process or signalling to a process from within another process. Although by default (without yama) only limited communication is possible due to the small fixed-size block of memory that can be passed between the two processes. Yama attaches a ptrace
permission level (0-3) to each process, with these levels defined as
Level | Restriction |
---|---|
0 | No |
1 | Descendants-only attach |
2 | Admin-only attach |
3 | No attach |
and therefore restricts which processes can trace or signal other processes, helping to mitigate certain types of attacks, such as privilege escalation.
Integrity Policy Enforcement
Integrity Policy Enforcement (IPE) (integrity
) takes a complementary approach to access control. Focusing on the immutable security properties inherent to system components. These properties are fundamental attributes or features of a system component that cannot be altered, ensuring a consistent and reliable basis for security decisions.
SELinux
Security-Enhanced Linux implements mandatory access control (MAC) policies that restrict how processes interact with each other and with files.
AppArmor
AppArmor is a security module that provides a simpler alternative to SELinux. It can dissallow access to files which the process would not require, as defined by the apparmor profile. Install the necessary packages: (1) { .annotate }
- For Gentoo Linux make sure to set the
apparmor
USE flag.
=== "Alpine Linux"
``` shell-session
sh# apk add apparmor apparmor-utils apparmor-profiles
```
=== "Gentoo Linux"
``` shell-session
sh# emerge -a apparmor apparmor-utils apparmor-profiles
```
and add it to the boot runlevel:
sh# rc-update add apparmor boot
Add apparmor
to the kernel cmdline
to make it operational:
... lsm=...,apparmor apparmor=1 ...
Then reconfigure the kernel
:
=== "Alpine Linux"
``` shell-session
sh# apk fix kernel-hooks
```
=== "Gentoo Linux"
``` shell-session
sh# emerge --config gentoo-kernel
```
You can check the status of apparmor
with apparmor-utils
:
sh# aa-status
Kernel boot parameters
Boot parameters configure the bootloader to parse the relevant settings to the kernel at boot. Hardening the boot process will improve the overall security of the system. The listed boot parameters in this chapter can be parsed into the kernel cmdline
:
... slab_nomerge init_on_alloc=1 init_on_free=1 page_alloc.shuffle=1 pti=on ...
Mitigations of system vulnerabilities
-
The setting
slab_nomerge
disables slab merging which helps to protect against heap exploitation. -
The settings
init_on_alloc=1 init_on_free=1
enable zeroing of memory during allocation and free time, which helps to mitigate use-after-free vulnerabilities. -
The setting
page_alloc.shuffle=1
randomises page allocator freelists, making page allocations less predictable. (1) { .annotate }- Setting this parameter actually improves performance.
-
The setting
pti=on
enables kernel page-table isolation that mitigates the meltdown vulnerability and helps to protect against attempts to bypass kernel address space layout randomisation. -
The setting
randomize_kstack_offset=on
randomises the kernel stack offset on each syscall, which helps to protect against attacks that rely on deterministic kernel stack layouts. -
The setting
vsyscall=none
disables the deprecatedvsyscalls
. -
The setting
debugfs=off
disables the debugfs, removing a source of sensitive information about the kernel. -
The setting
module.sig_enforce=1
enforces that only signed kernel modules can be loaded. -
The setting
lockdown=confidentiality
sets the strictest option of thelockdown
security module. -
The setting
mce=0
causes the kernel to panic on uncorrectable errors in ECC memory. This setting is unnecessary for non-ECC memory. (1) { .annotate }- ECC memory from a security and a redundancy perspective is always recommended. The ZFS filesystem also functions better with ECC memory.
Hardware specific mitigations of vulnerabilities
-
The setting
spectre_v2=on
enables the mitigation of spectre, a speculative execution CPU vulnerability that is present in all pre-2019 CPUs. -
The setting
spec_store_bypass_disable=on
disables Speculative Store Bypass (SSB), in all pre-2019 CPUs there is a vulnerability in the SSB. -
The setting
tsx=off
disables Transactional Synchronisation Extensions (TSX), which is a feature of pre-2019 Intel CPUs. TSXs are vulnerable to cache side-channel attacks. -
The setting
tsx_async_abort=full
mitigates the TSX vulnerability if you are stupid enough to keep TSX enabled. -
The setting
mds=full
enables the mitigation of the Micro-architectural Data Sampling (MDS), a set of weaknesses in pre-2020 Intel x86_64 CPUs. -
The setting
l1tf=flush
mitigates the L1 Terminal Fault vulnerability present in pre-2019, by conditional flushing of the Level 1 Data Cache. -
The setting
kvm.nx_huge_pages=force
mitigates the iTLB multihit vulnerability present in pre-2019 Intel CPUs.
So if you have a pre-2019 Intel CPU, throw it out of the window right now! The performance hit is quite significant with all these mitigations.
Hardening the boot process
-
The settings
quiet loglevel=0
prevent information leaks during boot and must be used in combination with thekernel.printk
sysctl setting. -
The settings
rd.shell=0 rd.emergency.reboot=reboot
impose that at critical failure in the boot process the system should be rebooted and that the shell cannot be accessed at all times during this process. Hardening the boot process.
Kernel sysctl settings
Kernel self-protection can be configured by creating:
kernel.kptr_restrict=2 #(1)!
kernel.dmesg_restrict=1 #(2)!
kernel.printk=3 3 3 3 #(3)!
kernel.unprivileged_bpf_disabled=1 #(4)!
net.core.bpf_jit_harden=2 #(5)!
dev.tty.ldisc_autoload=0 #(6)!
kernel.kexec_load_disabled=1 #(7)!
kernel.sysrq=0 #(8)!
kernel.perf_event_paranoid=3 #(9)!
- Mitigate kernel pointer leaks.
- Restrict kernel log to
CAP_SYSLOG
capability. - Restrict kernel log in console during boot.
- Restrict eBPF to
CAP_SYSLOG
capability. - Restrict eBPF to
CAP_SYSLOG
capability. - Restrict TTY line disciplines to
CAP_SYS_MODULE
capability. - Disable kexec (system call to boot another kernel during runtime).
- Disable SysRq key (debugging functionality).
- Restrict performance events to
CAP_PERFORM
capability.
Network protection can be configured by creating:
net.ipv4.icmp_echo_ignore_all=1 #(1)!
net.ipv4.tcp_syncookies=1 #(2)!
net.ipv4.tcp_rfc1337=1 #(3)!
net.ipv4.tcp_sack=0 #(4)!
net.ipv4.tcp_dsack=0 #(5)!
net.ipv4.tcp_fack=0 #(6)!
net.ipv4.conf.all.rp_filter=1 #(7)!
net.ipv4.conf.default.rp_filter=1 #(8)!
net.ipv4.conf.all.accept_redirects=0 #(9)!
net.ipv4.conf.default.accept_redirects=0 #(10)!
net.ipv4.conf.all.secure_redirects=0 #(11)!
net.ipv4.conf.default.secure_redirects=0 #(12)!
net.ipv6.conf.all.accept_redirects=0 #(13)!
net.ipv6.conf.default.accept_redirects=0 #(14)!
net.ipv4.conf.all.send_redirects=0 #(15)!
net.ipv4.conf.default.send_redirects=0 #(16)!
net.ipv4.conf.all.accept_source_route=0 #(17)!
net.ipv4.conf.default.accept_source_route=0 #(18)!
net.ipv6.conf.all.accept_source_route=0 #(19)!
net.ipv6.conf.default.accept_source_route=0 #(20)!
- Ignore all ICMP requests, to avoid Smurf attacks.
- Restricts resources handling SYN requests, helps protect against SYN flood attacks.
- Drops RST packets for sockets in the time-wait state, to avoid time-wait assassination attacks.
- Disables TCP SACK, for servers it could be relevant to keep this enabled.
- Disables TCP SACK, for servers it could be relevant to keep this enabled.
- Disables TCP SACK, for servers it could be relevant to keep this enabled.
- Enables source validation of packets received from all interfaces, to avoid IP spoofing.
- Enables source validation of packets received from all interfaces, to avoid IP spoofing.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables ICMP redirect acceptance and sending to prevent man-in-the-middle attacks.
- Disables source routing to prevent man-in-the-middle attacks.
- Disables source routing to prevent man-in-the-middle attacks.
- Disables source routing to prevent man-in-the-middle attacks.
- Disables source routing to prevent man-in-the-middle attacks.
Protection of the user space can be configured by creating:
kernel.yama.ptrace_scope=2 #(1)!
vm.mmap_rnd_bits=32 #(2)!
vm.mmap_rnd_compat_bits=16 #(3)!
fs.protected_symlinks=1 #(4)!
fs.protected_hardlinks=1 #(5)!
fs.protected_fifos=2 #(6)!
fs.protected_regular=2 #(7)!
- Restrict
ptrace
usage to level 2 (only processes withCAP_SYS_PTRACE
capability). - Increase the entropy for mmap ASLR, compatible with
x86_64
. - Increase the entropy for mmap ASLR, compatible with
x86_64
. - Restricts symlink following to only well-defined owner paths, preventing TOC/TOU races.
- Restricts symlink following to only well-defined owner paths, preventing TOC/TOU races.
- Prevent file creation in high-risk environments, helps to protect against spoofing attakcs.
- Prevent file creation in high-risk environments, helps to protect against spoofing attakcs.
Hardened memory allocator
The default memory allocator of musl
is already reasonably secure but not as secure as hardened-malloc, install it with:
=== "Alpine Linux"
``` shell-session
sh# apk add hardened-malloc
```
=== "Gentoo Linux"
``` shell-session
sh# emerge -a hardened-malloc
```
and set it to system-wide edit:
/usr/lib/libhardened_malloc.so #(1)!
/lib
/usr/lib
/usr/local/lib
- If problems with graphical applications occur the light variant of hardened-malloc
/usr/lib/libhardened_malloc-light.so
may also be used instead of/usr/lib/libhardened_malloc.so
.
To accomodate the large number of guard pages created by hardened-malloc
impose that we should set the following:
vm.max_map_count=1048576
Entropy
Improve the security of the system by increasing the entropy with the jitterentropy
kernel module, install it with:
=== "Alpine Linux"
``` shell-session
sh# apk add jitterentropy-library
```
=== "Gentoo Linux"
``` shell-session
sh# emerge -a jitterentropy
```
and make sure that the module gets loaded:
jitterentropy_rng