|
| 1 | +Linux Capabilities |
| 2 | +================== |
| 3 | + |
| 4 | +Finit supports Linux capabilities, allowing services to run with minimal |
| 5 | +required privileges instead of running as root. This significantly improves |
| 6 | +system security by following the principle of least privilege. |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +Linux capabilities divide the traditional root privileges into distinct units |
| 11 | +that can be independently granted to processes. For example, a web server only |
| 12 | +needs the capability to bind to privileged ports (< 1024), not full root access. |
| 13 | + |
| 14 | +Finit uses the modern IAB (Inheritable, Ambient, Bounding) API from libcap, |
| 15 | +which is the same approach used by other modern service managers like dinit. |
| 16 | + |
| 17 | +## Basic Usage |
| 18 | + |
| 19 | +Capabilities are specified using the `caps:` directive in service configuration: |
| 20 | + |
| 21 | +```conf |
| 22 | +service [2345] name:nginx \ |
| 23 | + @www-data:www-data \ |
| 24 | + caps:^cap_net_bind_service \ |
| 25 | + /usr/sbin/nginx -g 'daemon off;' \ |
| 26 | + -- Web server |
| 27 | +``` |
| 28 | + |
| 29 | +This example allows nginx to bind to privileged ports (like 80 and 443) while |
| 30 | +running as the unprivileged `www-data` user. |
| 31 | + |
| 32 | +## IAB Format |
| 33 | + |
| 34 | +The capability string uses the IAB (Inheritable, Ambient, Bounding) format |
| 35 | +with the following prefixes: |
| 36 | + |
| 37 | +- `^` **Ambient** (and Inheritable) - **Recommended for most use cases** |
| 38 | + - Capabilities survive across `exec()` calls |
| 39 | + - Automatically raised to effective after exec |
| 40 | + - Example: `^cap_net_bind_service` |
| 41 | + |
| 42 | +- `%` **Inheritable** only |
| 43 | + - Requires the executed binary to have matching file capabilities |
| 44 | + - Less common, more complex setup |
| 45 | + - Example: `%cap_net_admin` |
| 46 | + |
| 47 | +- `!` **Bounding** - Block capability from bounding set |
| 48 | + - Prevents the service from ever acquiring this capability |
| 49 | + - Useful for security hardening |
| 50 | + - Example: `!cap_sys_admin` |
| 51 | + |
| 52 | +Multiple capabilities can be specified as a comma-separated list: |
| 53 | + |
| 54 | +```conf |
| 55 | +caps:^cap_net_raw,^cap_net_admin,^cap_net_bind_service |
| 56 | +``` |
| 57 | + |
| 58 | +## Common Use Cases |
| 59 | + |
| 60 | +### Web Server (Privileged Ports) |
| 61 | + |
| 62 | +Allow a web server to bind to ports 80 and 443 without running as root: |
| 63 | + |
| 64 | +```conf |
| 65 | +service [2345] name:webserver \ |
| 66 | + @www-data:www-data \ |
| 67 | + caps:^cap_net_bind_service \ |
| 68 | + /usr/sbin/nginx -g 'daemon off;' |
| 69 | +``` |
| 70 | + |
| 71 | +### Network Monitoring (Raw Sockets) |
| 72 | + |
| 73 | +Allow packet capture without root privileges: |
| 74 | + |
| 75 | +```conf |
| 76 | +service [2345] name:tcpdump \ |
| 77 | + @tcpdump \ |
| 78 | + caps:^cap_net_raw,^cap_net_admin \ |
| 79 | + /usr/sbin/tcpdump -i eth0 -w /var/log/capture.pcap |
| 80 | +``` |
| 81 | + |
| 82 | +### NTP Daemon (System Time) |
| 83 | + |
| 84 | +Allow time synchronization without full root: |
| 85 | + |
| 86 | +```conf |
| 87 | +service [2345] name:ntpd \ |
| 88 | + @ntp \ |
| 89 | + caps:^cap_sys_time,^cap_sys_nice \ |
| 90 | + /usr/sbin/ntpd -n |
| 91 | +``` |
| 92 | + |
| 93 | +## Available Capabilities |
| 94 | + |
| 95 | +Common capabilities include (see `man 7 capabilities` for the complete list): |
| 96 | + |
| 97 | +- `cap_chown` - Make arbitrary changes to file UIDs and GIDs |
| 98 | +- `cap_dac_override` - Bypass file read, write, and execute permission checks |
| 99 | +- `cap_dac_read_search` - Bypass file read permission checks |
| 100 | +- `cap_fowner` - Bypass permission checks on operations that normally require filesystem UID |
| 101 | +- `cap_kill` - Bypass permission checks for sending signals |
| 102 | +- `cap_net_admin` - Perform various network-related operations |
| 103 | +- `cap_net_bind_service` - Bind to privileged ports (< 1024) |
| 104 | +- `cap_net_raw` - Use RAW and PACKET sockets |
| 105 | +- `cap_setgid` - Make arbitrary manipulations of process GIDs |
| 106 | +- `cap_setuid` - Make arbitrary manipulations of process UIDs |
| 107 | +- `cap_sys_admin` - Perform system administration operations (very powerful!) |
| 108 | +- `cap_sys_module` - Load and unload kernel modules |
| 109 | +- `cap_sys_nice` - Raise process nice value and change scheduling |
| 110 | +- `cap_sys_time` - Set system clock |
| 111 | + |
| 112 | +## Security Best Practices |
| 113 | + |
| 114 | +1. **Use the minimum required capabilities** |
| 115 | + - Only grant what the service actually needs |
| 116 | + - Don't grant `cap_sys_admin` unless absolutely necessary |
| 117 | + |
| 118 | +2. **Always specify a user** |
| 119 | + - Always use `@user` to drop to a non-root user |
| 120 | + - Capabilities work best when combined with user separation |
| 121 | + |
| 122 | +3. **Use ambient capabilities (`^`)** |
| 123 | + - The `^` prefix ensures capabilities survive exec() |
| 124 | + - Simpler than setting file capabilities on binaries |
| 125 | + |
| 126 | +4. **Block dangerous capabilities** |
| 127 | + - Use `!` to explicitly block capabilities you don't want |
| 128 | + - Example: `!cap_sys_admin,!cap_sys_module` |
| 129 | + |
| 130 | +5. **Test with `getpcaps`** |
| 131 | + - After starting a service, verify its capabilities: |
| 132 | + ```bash |
| 133 | + getpcaps $(pidof nginx) |
| 134 | + ``` |
| 135 | + - Should show only the capabilities you granted |
| 136 | + |
| 137 | +## Verification |
| 138 | + |
| 139 | +After configuring a service with capabilities, verify it works correctly: |
| 140 | + |
| 141 | +```bash |
| 142 | +# Start the service |
| 143 | +initctl start webserver |
| 144 | +
|
| 145 | +# Check the process capabilities |
| 146 | +getpcaps $(pidof nginx) |
| 147 | +
|
| 148 | +# Should show something like: |
| 149 | +# 12345: cap_net_bind_service=eip |
| 150 | +
|
| 151 | +# Verify the user |
| 152 | +ps -o user,pid,cmd -p $(pidof nginx) |
| 153 | +
|
| 154 | +# Should show the service running as the specified user |
| 155 | +``` |
| 156 | + |
| 157 | +## Requirements |
| 158 | + |
| 159 | +- Linux kernel 4.3+ (for ambient capabilities support) |
| 160 | +- libcap library installed |
| 161 | +- Finit built with `--enable-libcap` |
| 162 | + |
| 163 | +## Limitations |
| 164 | + |
| 165 | +- Capabilities are only applied when both `@user` and `caps:` are specified |
| 166 | +- The service must drop to a non-root user for capabilities to be effective |
| 167 | +- Some very old binaries may not work correctly with ambient capabilities |
| 168 | +- File system capabilities are not managed by Finit (use `setcap` for that) |
| 169 | + |
| 170 | +## See Also |
| 171 | + |
| 172 | +- `man 7 capabilities` - Linux capabilities overview |
| 173 | +- `man 3 cap_iab` - IAB capability API documentation |
| 174 | +- `man 8 setcap` - Set file capabilities |
| 175 | +- `man 8 getcap` - Query file capabilities |
| 176 | +- `man 1 capsh` - Capability shell wrapper |
0 commit comments