Linux Capabilities ================== Finit supports Linux capabilities, allowing services to run with minimal required privileges instead of running as root. This significantly improves system security by following the principle of least privilege. ## Overview Linux capabilities divide the traditional root privileges into distinct units that can be independently granted to processes. For example, a web server only needs the capability to bind to privileged ports (< 1024), not full root access. Finit uses the modern IAB (Inheritable, Ambient, Bounding) API from libcap, which is the same approach used by other modern service managers like dinit. ## Basic Usage Capabilities are specified using the `caps:` directive in service configuration: ```conf service [2345] name:nginx \ @www-data:www-data \ caps:^cap_net_bind_service \ /usr/sbin/nginx -g 'daemon off;' \ -- Web server ``` This example allows nginx to bind to privileged ports (like 80 and 443) while running as the unprivileged `www-data` user. ## IAB Format The capability string uses the IAB (Inheritable, Ambient, Bounding) format with the following prefixes: - `^` **Ambient** (and Inheritable) - **Recommended for most use cases** - Capabilities survive across `exec()` calls - Automatically raised to effective after exec - Example: `^cap_net_bind_service` - `%` **Inheritable** only - Requires the executed binary to have matching file capabilities - Less common, more complex setup - Example: `%cap_net_admin` - `!` **Bounding** - Block capability from bounding set - Prevents the service from ever acquiring this capability - Useful for security hardening - Example: `!cap_sys_admin` Multiple capabilities can be specified as a comma-separated list: ```conf caps:^cap_net_raw,^cap_net_admin,^cap_net_bind_service ``` ## Common Use Cases ### Web Server (Privileged Ports) Allow a web server to bind to ports 80 and 443 without running as root: ```conf service [2345] name:webserver \ @www-data:www-data \ caps:^cap_net_bind_service \ /usr/sbin/nginx -g 'daemon off;' ``` ### Network Monitoring (Raw Sockets) Allow packet capture without root privileges: ```conf service [2345] name:tcpdump \ @tcpdump \ caps:^cap_net_raw,^cap_net_admin \ /usr/sbin/tcpdump -i eth0 -w /var/log/capture.pcap ``` ### NTP Daemon (System Time) Allow time synchronization without full root: ```conf service [2345] name:ntpd \ @ntp \ caps:^cap_sys_time,^cap_sys_nice \ /usr/sbin/ntpd -n ``` ## Available Capabilities Common capabilities include (see `man 7 capabilities` for the complete list): - `cap_chown` - Make arbitrary changes to file UIDs and GIDs - `cap_dac_override` - Bypass file read, write, and execute permission checks - `cap_dac_read_search` - Bypass file read permission checks - `cap_fowner` - Bypass permission checks on operations that normally require filesystem UID - `cap_kill` - Bypass permission checks for sending signals - `cap_net_admin` - Perform various network-related operations - `cap_net_bind_service` - Bind to privileged ports (< 1024) - `cap_net_raw` - Use RAW and PACKET sockets - `cap_setgid` - Make arbitrary manipulations of process GIDs - `cap_setuid` - Make arbitrary manipulations of process UIDs - `cap_sys_admin` - Perform system administration operations (very powerful!) - `cap_sys_module` - Load and unload kernel modules - `cap_sys_nice` - Raise process nice value and change scheduling - `cap_sys_time` - Set system clock ## Security Best Practices 1. **Use the minimum required capabilities** - Only grant what the service actually needs - Don't grant `cap_sys_admin` unless absolutely necessary 2. **Specify a user (preferably non-root)** - The `@user` directive is **required** for `caps:` to take effect - For ambient capabilities (`^`), use a non-root user (not `@root`) - Example: `@www-data`, `@nginx`, `@tcpdump` 3. **Use ambient capabilities (`^`)** - The `^` prefix ensures capabilities survive exec() - Simpler than setting file capabilities on binaries 4. **Block dangerous capabilities** - Use `!` to explicitly block capabilities you don't want - Example: `!cap_sys_admin,!cap_sys_module` 5. **Test with `getpcaps`** - After starting a service, verify its capabilities: ```bash getpcaps $(pidof nginx) ``` - Should show only the capabilities you granted ## Verification After configuring a service with capabilities, verify it works correctly: ```bash # Start the service initctl start webserver # Check the process capabilities getpcaps $(pidof nginx) # Should show something like: # 12345: cap_net_bind_service=eip # Verify the user ps -o user,pid,cmd -p $(pidof nginx) # Should show the service running as the specified user ``` ## Requirements - Linux kernel 4.3+ (for ambient capabilities support) - libcap library installed - Finit built with `--enable-libcap` ## Limitations - The `caps:` directive requires `@user` to be specified for it to take effect - Without `@user`, the service runs as root with full capabilities and the `caps:` configuration is silently ignored - You can use `@root` with `caps:`, but see below about ambient capabilities - For ambient capabilities (`^`, recommended), the user **must be non-root** - Using `@root` with `caps:^...` will not work effectively, as ambient capabilities are only added to the effective set when euid ≠ 0 - Use inheritable (`%`) or bounding (`!`) capabilities with `@root` if needed - Services without `caps:` use standard privilege dropping: - Services with `@user` (non-root) have no special capabilities - Services without `@user` run as root with full capabilities - Some very old binaries may not work correctly with ambient capabilities - File system capabilities are not managed by Finit (use `setcap` for that) ## See Also - [capabilities(7)](https://man7.org/linux/man-pages/man7/capabilities.7.html) - Linux capabilities overview - [cap_iab(3)](https://man7.org/linux/man-pages/man3/cap_iab.3.html) - IAB capability API documentation - [setcap(8)](https://man7.org/linux/man-pages/man8/setcap.8.html) - Set file capabilities - [getcap(8)](https://man7.org/linux/man-pages/man8/getcap.8.html) - Query file capabilities - [capsh(1)](https://man7.org/linux/man-pages/man1/capsh.1.html) - Capability shell wrapper