- commit
- 5a95a78a8e733ab76417fbaa0d81de2506236331
- parent
- a650f40fc10f6b13745c9b61d681a5c97d2d7067
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-06-24 06:15
add post on linux security mechanisms
Diffstat
A | _content/posts/2024-06-23-linux-security-mechanisms/index.md | 200 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 files changed, 200 insertions, 0 deletions
diff --git a/_content/posts/2024-06-23-linux-security-mechanisms/index.md b/_content/posts/2024-06-23-linux-security-mechanisms/index.md
@@ -0,0 +1,200 @@ -1 1 --- -1 2 title: Tier list of Linux security mechanisms -1 3 date: 2024-06-23 -1 4 tags: [code, linux, security] -1 5 description: Linux has quite some security mechanisms. So let's look at some of them and rate them by usability and power. -1 6 --- -1 7 -1 8 Linux has quite some security mechanisms. So let's look at some of them and -1 9 rate them by usability and power. -1 10 -1 11 ## File permissions -1 12 -1 13 Every file has read/write/execute permissions for its owner, group, and others. -1 14 This is usually expressed in octal: 755 means everyone can read and execute, but -1 15 only the owner can write. 600 means everyone is blocked but the owner can read -1 16 and write. -1 17 -1 18 This system is pretty old and has served us well. For example, home directories -1 19 are typically 700 to block access from other users. And system services can run -1 20 as separate users so they cannot change the system or access users' home -1 21 directories. -1 22 -1 23 File permissions are simple and powerful. They are a foundational tool for any -1 24 Linux user. However, they lack some of the flexibility of other items on the -1 25 list. -1 26 -1 27 A Tier -1 28 -1 29 ## Capabilities -1 30 -1 31 The root user has a lot of special permissions. For example, they can access -1 32 any file or bind ports below 1024. At some point, the Linux community decided -1 33 to divide this role into -1 34 [Capabilities](https://www.man7.org/linux/man-pages/man7/capabilities.7.html) -1 35 to allow more granular access control. -1 36 -1 37 However, the list of Capabilities is long and complicated. Regular users will -1 38 hardly be able to understand which capabilities a process needs. Some -1 39 Capabilities even allow [privilege -1 40 escalations](https://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-capabilities). -1 41 -1 42 Docker by default runs containers as root, but [drops most -1 43 capabilities](https://docs.docker.com/engine/security/#linux-kernel-capabilities). -1 44 Running with a limited set of capabilities is better than running as root. But -1 45 in practice, you rarely even need any capabilities. Just running as a regular -1 46 user will work 99% of the time. -1 47 -1 48 B Tier -1 49 -1 50 ## seccomp -1 51 -1 52 [seccomp](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html) -1 53 allows to filter which syscalls a process has access to. For me, this has much -1 54 the same pros and cons as Capabilities: The list of syscalls is just too long -1 55 and complicated. -1 56 -1 57 On top of that, creating a seccomp filter is also complicated. bwrap wants a -1 58 [compiled cBPF program](https://www.man7.org/linux/man-pages/man3/seccomp_export_bpf.3.html). -1 59 Docker will take a [JSON seccomp profile](https://docs.docker.com/engine/security/seccomp/). -1 60 Systemd has probably the most usable interface by providing presets like -1 61 `@system-service`. -1 62 -1 63 B Tier -1 64 -1 65 ## No new privileges -1 66 -1 67 [`PR_SET_NO_NEW_PRIVS`](https://docs.kernel.org/userspace-api/no_new_privs.html) -1 68 blocks setuid (e.g. sudo) and a bunch of other privilege escalations. Highly -1 69 recommended. -1 70 -1 71 bwrap uses it unconditionally, in systemd it is [implied by a bunch of -1 72 settings](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#NoNewPrivileges=), -1 73 and Docker has an [option to enable -1 74 it](https://docs.docker.com/reference/cli/docker/container/run/#security-opt). -1 75 -1 76 S Tier -1 77 -1 78 ## AppArmor / SELinux -1 79 -1 80 These are effectively file permissions on steroids. Where file permissions only -1 81 allow you to assign permissions for owner and group, these allow you to assign -1 82 permissions for every binary individually. This means that every application -1 83 can come with a specific AppArmor / SELinux profile that exactly lists the -1 84 files it needs access to. -1 85 -1 86 My impression is that very few applications come with AppArmor or SELinux -1 87 profiles. Writing them is cumbersome, especially if they are not maintained -1 88 along with the application itself. -1 89 -1 90 I don't think these mechanisms are actively harmful. Maybe I am too harsh, but -1 91 given the alternatives we will discuss later, I don't see any reason to use -1 92 them. -1 93 -1 94 C Tier -1 95 -1 96 ## cgroups -1 97 -1 98 So far we mainly looked at mechanisms to restrict file access and syscalls. -1 99 [Control Groups](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html) -1 100 allow to restrict system resources (mostly CPU and memory). This is what -1 101 resource control in systemd and Docker is build upon. -1 102 -1 103 cgroups are a useful mechanism for servers, especially if you rent out -1 104 computing time to others. For single users systems, they are much less -1 105 relevant. -1 106 -1 107 B Tier -1 108 -1 109 ## Namespaces -1 110 -1 111 [Namespaces](https://www.man7.org/linux/man-pages/man7/namespaces.7.html) have -1 112 fueled the container revolution of the past years, including Docker and -1 113 Flatpak. Network and PID namespaces are useful, but the real star is mount -1 114 namespaces, which allows to construct a separate file hierarchy for each -1 115 process. -1 116 -1 117 You can use this mechanism a lot like AppArmor / SELinux, but instead of -1 118 blocking access to a file, you just don't include it in the hierarchy. In that -1 119 case you still have to maintain the list of files that should be made -1 120 available, which is quite complex to get right. -1 121 -1 122 The other option is to use a completely separate file hierarchy that only -1 123 shares some select data folders with the host system. This is easier, but also -1 124 results in many redundant and potentially unpatched directory trees. -1 125 -1 126 Despite the downsides, I really like how powerful this mechanism is while also -1 127 being quite intuitive. -1 128 -1 129 A Tier -1 130 -1 131 ## Landlock -1 132 -1 133 Landlock is yet another way to limit access to files, and was only added to the -1 134 kernel in 5.13. -1 135 -1 136 While it could be used to sandbox applications, I think we already have more -1 137 than enough mechanisms for that (AppArmor, SELinux, mount namespaces). However, -1 138 it could be interesting as a mechanism for processes to restrict themselves. -1 139 Landlock was actually modelled after a BSD mechanism called `pledge`, as in "I -1 140 pledge to not ever access those files". -1 141 -1 142 C Tier -1 143 -1 144 ## polkit -1 145 -1 146 A trend in recent years is to have services that can perform privileged -1 147 actions, so that applications can talk to those services over dbus instead of -1 148 having to perform the privileged actions themselves. On its own, this is just a -1 149 security bypass. But the services in turn ask polkit whether an action should -1 150 be allowed. polkit will then consult its configuration and either allow the -1 151 request, deny the request, or ask the user to authorize the request by entering -1 152 their password. -1 153 -1 154 Polkit gives instant privilege escalation while having a voluptuous attack -1 155 surface. That doesn't mean that it is insecure. But if I wanted to attack a -1 156 Linux desktop system, this is where I would start. -1 157 -1 158 Proponents of polkit argue that it gives much more flexibility. But polkit -1 159 rules decide requests mainly based on group membership. I cannot see how -1 160 polkit should make nuanced decisions based on this limited information. -1 161 -1 162 The main benefit or polkit is that it allows to get the user into the loop. -1 163 There is a good idea somewhere in here. But the current implementation is not -1 164 that. -1 165 -1 166 Unfortunately, polkit is a central part of most modern Linux desktops. I wish -1 167 we had something else, but for now we are stuck with it. -1 168 -1 169 D Tier -1 170 -1 171 ## xdg-dbus-proxy -1 172 -1 173 The Flatpak project realized that polkit is not sufficient and came up with an -1 174 additional mechanism: They build -1 175 [xdg-dbus-proxy](https://github.com/flatpak/xdg-dbus-proxy), a dbus proxy that -1 176 filters which services are available. They then mount the proxy instead of the -1 177 original socket in their mount namespace. -1 178 -1 179 (Aside: This would not be necessary if dbus would use a separate socket for -1 180 each service. Then you could use mount namespaces directly without a need for a -1 181 proxy.) -1 182 -1 183 As far as I understand, they do not do much work on this project because they -1 184 want to [move this functionality into dbus -1 185 itself](https://gitlab.freedesktop.org/dbus/dbus/-/issues/171). However, the -1 186 ticket was created in 2017 and there has not been much progress. So I am not -1 187 really sure about the status. -1 188 -1 189 C Tier -1 190 -1 191 ## Summary -1 192 -1 193 There you have it, this is my ranking of linux security mechanisms: -1 194 -1 195 - S Tier: No new privileges (great!) -1 196 - A Tier: File permissions, Namespaces (tools for everyday use) -1 197 - B Tier: Capabilities, seccomp, cgroups (only for select occasions) -1 198 - C Tier: AppArmor / SELinux, Landlock, xdg-dbus-proxy (better options are available) -1 199 - D Tier: polkit (I would like to see this one replaced) -1 200 - F Tier: -