我对文件功能如何与用户命名空间一起工作感到困惑。据我了解,如果一个文件具有某种功能,那么执行该文件的任何线程/进程都可以获得该功能。
在我的 ping 二进制文件中,我设置了 CAP_NET_RAW 功能,并且没有 setuid。
# CAP_NET_RAW is set
→ getcap `which ping`
/bin/ping = cap_net_raw+ep
# There is no setuid
→ ls -l `which ping`
-rwxr-xr-x 1 root root 64424 Mar 9 2017 /bin/ping
# ping works...
→ ping -c 1 google.com
PING google.com (172.217.6.46) 56(84) bytes of data.
64 bytes from sfo03s08-in-f14.1e100.net (172.217.6.46): icmp_seq=1
ttl=54 time=11.9 ms
--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 11.973/11.973/11.973/0.000 ms
那么为什么我无法从我的用户命名空间 ping 通呢?
→ ping google.com
ping: socket: Operation not permitted
→ capsh --print
Current: = ...cap_net_raw...+ep
Bounding set =...cap_net_raw...
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
→ getcap `which ping`
/bin/ping = cap_net_raw+ep
答案1
由带有 CLONE_NEWUSER 标志的 clone(2) 创建的子进程以新用户命名空间中的一组完整功能开始。同样,使用 unshare(2) 创建新用户命名空间或使用 setns(2) 加入现有用户命名空间的进程将获得该命名空间中的全套功能。另一方面,该进程在父进程中没有任何功能(在clone(2)的情况下)或先前(在unshare(2)和setns(2)的情况下)用户命名空间,即使新的命名空间是由root用户创建或加入的(即,具有用户的进程)根命名空间中的 ID 0)。
...
创建非用户命名空间时,它由创建进程在创建命名空间时所属的用户命名空间拥有。对非用户命名空间的操作需要相应用户命名空间中的功能。
--http://man7.org/linux/man-pages/man7/user_namespaces.7.html
您无法对不属于您的网络接口进行原始网络访问!
$ unshare -r
# ping -c1 127.0.0.1
ping: socket: Operation not permitted
比较:
$ unshare -rn
# ping -c1 127.0.0.1
connect: Network is unreachable
# ip link set dev lo up # apparently the `lo` interface is pre-created.
# ping -c1 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.048 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.048/0.048/0.048/0.000 ms