Linux Capabilities in a nutshell (2019)
k3a.me
k3a.me
#1: I disagree with the very first sentence ("Capabilities are being use more and more, mainly thanks to SystemD, Docker and orchestrators like Kubernetes.") - a lot of old-fashioned daemons already use capabilities to limit their privileges and/or raise and lower them as needed.
#2: pspax from pax-utils is a great tool to show process capabilities:
# pspax
USER PID PAX MAPS ETYPE NAME CAPS ATTR
root 1 --- w^x ET_DYN init =ep system_u:system_r:init_t:s0
root 2575 --- w^x ET_DYN udevd =ep system_u:system_r:kernel_t:s0
root 2752 --- w^x ET_DYN dmeventd =ep system_u:system_r:kernel_t:s0
root 60844 --- w^x ET_DYN auditd =ep system_u:system_r:kernel_t:s0
root 60879 --- w^x ET_DYN crond =ep system_u:system_r:kernel_t:s0
root 60910 --- w^x ET_DYN ntpd cap_net_bind_service,cap_ipc_lock,cap_sys_time=ep system_u:system_r:kernel_t:s0
root 61532 --- w^x ET_DYN lxc-start =ep system_u:system_r:kernel_t:s0
-------- 61542 --- w^x ET_EXEC init =eip system_u:system_r:kernel_t:s0
root 66327 --- w^x ET_DYN lxc-start =ep system_u:system_r:kernel_t:s0
-------- 66328 --- w^x ET_EXEC init =eip system_u:system_r:kernel_t:s0
root 70543 --- w^x ET_DYN zebra cap_net_admin,cap_net_raw,cap_sys_admin=p system_u:system_r:kernel_t:s0
root 70785 --- w^x ET_DYN ospfd cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_admin=p system_u:system_r:kernel_t:s0
root 70794 --- w^x ET_DYN ospf6d cap_net_bind_service,cap_net_raw=p system_u:system_r:kernel_t:s0
root 71529 --- w^x ET_DYN bgpd cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_admin=p system_u:system_r:kernel_t:s0
root 71770 --- w^x ET_DYN syslog-ng =ep system_u:system_r:kernel_t:s0
root 71771 --- w^x ET_DYN syslog-ng cap_syslog=ep cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_net_bind_service,cap_net_broadcast,cap_net_raw+p system_u:system_r:kernel_t:s0
[...]
(Note: in some versions of pspax, this is unfortunately broken; if you see everything with only "=ep", that's probably not right.) > pspax
USER PID PAX MAPS ETYPE NAME CAPS ATTR
[1] 3209832 invalid system call (core dumped) pspax
Stack trace of thread 3209832:
#0 0x00007fbdb92d89ab __socket (libc.so.6 + 0x1019ab)
#1 0x00007fbdb930dce0 open_socket (libc.so.6 + 0x136ce0)
#2 0x00007fbdb930e1de __nscd_get_mapping (libc.so.6 + 0x1371de)
#3 0x00007fbdb930e62f __nscd_get_map_ref (libc.so.6 + 0x13762f)
#4 0x00007fbdb930ac47 nscd_getpw_r (libc.so.6 + 0x133c47)
#5 0x00007fbdb930b0b6 __nscd_getpwuid_r (libc.so.6 + 0x1340b6)
#6 0x00007fbdb92a3895 getpwuid_r@@GLIBC_2.2.5 (libc.so.6 + 0xcc895)
#7 0x00007fbdb92a2eeb getpwuid (libc.so.6 + 0xcbeeb)
#8 0x0000558995732566 n/a (pspax + 0x4566)
#9 0x00007fbdb91ff152 __libc_start_main (libc.so.6 + 0x28152)
#10 0x0000558995732e8e n/a (pspax + 0x4e8e)
Dump of assembler code for function socket:
0x00007fb1d04139a0 <+0>: endbr64
0x00007fb1d04139a4 <+4>: mov $0x29,%eax
0x00007fb1d04139a9 <+9>: syscall
=> 0x00007fb1d04139ab <+11>: cmp $0xfffffffffffff001,%rax
0x00007fb1d04139b1 <+17>: jae 0x7fb1d04139b4 <socket+20>
0x00007fb1d04139b3 <+19>: ret
0x00007fb1d04139b4 <+20>: mov 0xc0495(%rip),%rcx # 0x7fb1d04d3e50
This can be a system library incompatibility though as don't have all system packages up-to-date.The code compiled from https://github.com/gentoo/pax-utils runs but displays just = under CAPS for every process.
So I am not sure it is generally usable outside of Gentoo (yet).
--- pspax.c 2021-02-26 09:46:14.304092510 +0100
+++ pspax.c 2021-02-25 11:25:42.439550015 +0100
@@ -413,7 +413,7 @@
/* this is a non-POSIX function */
caps = NULL;
- WRAP_SYSCAP(capgetp(pfd, cap_d));
+ WRAP_SYSCAP(cap_d = cap_get_pid(pid));
WRAP_SYSCAP(caps = cap_to_text(cap_d, &length));
if (pwd && strlen(pwd->pw_name) >= 8)make USE_CAP=yes
Then it showed "=ep" for every process BUT your patch fixed it and now it correctly lists process capabilities.
According to man, capgetp() is deprecated and cap_get_pid() should be used instead anyway.
EDIT: I can see your patch merged upstream, good work! :)
To me, it's barely legible.
It may appear different to others, for example when I looked on my phone, the effect was not as prominent. I'll pass.
It appears somebody doesn't like lynx's User-Agent string and it makes me sad.
GET /linux-capabilities-in-a-nutshell/ HTTP/1.0
Host: k3a.me
User-Agent: Lynx/2.9.0dev.5 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/3.6.13
I am quite surprised actually. It is unfortunate that these clients still haven't been updated to at least HTTP/1.1. :(Just patch Lynx to send HTTP/1.1 without implementing keep-alive or any other HTTP/1.1 functionality and your troubles will most likely end. :P It is better to have broken 1.1 implementation than broken 1.0.
CURL is using 2.0 for HTTPS and 1.1 for HTTP by default. Someone should upgrade these CLI browsers to use libcurl or something like that...
There are about a 100 different voices that I can choose from and they all suck.
A few months ago we trained a pretty nice DNN TTS engine and I wish I had the permission to release as a free software for Linux. I feel Linux has been in need of a good TTS forever.
Interestingly, this is a closed bug in Arch. Guess it's time to reopen it.
[1]https://aur.archlinux.org/packages/festival-freebsoft-utils/
This style habit (along with grey text on white/light-grey) is downright hostile to end-users and needs to stop.
The idea for them comes from one of my former coworkers, Christoph Lameter, when we were having issues with an app that needed CAP_NET_RAW for tcp sockets that we didn't want to be setuid root. Small world :)
# cat /etc/default/tomcat8 | grep AUTHBIND
AUTHBIND=yes
# touch /etc/authbind/byport/80
# chown tomcat8:tomcat8 /etc/authbind/byport/80
I guess instead the capabilities should be added for the start-up script?The actual modern solution here would be to use systemd socket activation (systemd binds the port and lets your process inherit it on startup).
Ahh OK, that makes more sense.
> would be to use systemd socket activation
I have to admit that every time I need one of those systemd scripts for some type of service I have, it's usually just a copy-n-paste from an older one with small modifications of paths/name etc. Perhaps I should actually learn some of that stuff. I guess it is here to stay; even though there was some debate about it a few years ago.
* Set useInheritedChannel="true" on one (and only one) connector
* Create tomcat.socket as described in https://bz.apache.org/bugzilla/show_bug.cgi?id=60560#c8
Shame tomcat can only accept one 'inherited' channel, so you can't have Tomcat's :443 _and_ :80 connectors both make use of systemd-created sockets.
Yes, when seeing the examples, it doesn't look too bad. I guess without any example and no idea (at all) on how to set this up, it would still take quite some time to figure out.
Capabilities are really sort of a poorly thought out boundary. It's like, yes this is technically better than full root, but ultimately most individual capabilities are still extremely powerful/ can be leveraged for root.
At the end of the day I highly recommend capabilities as a measure of last resort - it's a "may as well", not a goal.