Linux
iproute2 ss - 如果使用者與偵聽程序不是同一使用者,則不顯示程序/pid 資訊?
這是正常行為還是錯誤,當我執行時
ss -nltp
,如果我正在執行ss -nltp
的使用者與偵聽程序是同一使用者,我只會看到程序/pid 資訊?$ docker run -it --rm tianon/network-toolbox root@bc058746626a:/# apt update ... root@bc058746626a:/# apt install gosu ... root@bc058746626a:/# nc -l 4444 [... check ss in another terminal] ^C root@bc058746626a:/# gosu nobody nc -l 4444 .... $ docker exec -it admiring_keller bash $ # both running as root root@bc058746626a:/# ss -nltp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 1 0.0.0.0:4444 0.0.0.0:* users:(("nc",pid=325,fd=3)) $ # process running as nobody, ss as root root@bc058746626a:/# ss -nltp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 1 0.0.0.0:4444 0.0.0.0:* $ # process still as nobody , ss as nobody root@bc058746626a:/# gosu nobody ss -nltp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 1 0.0.0.0:4444 0.0.0.0:* users:(("nc",pid=343,fd=3)) root@bc058746626a:/# exit $ # process still as nobody , ss as nobody $ docker exec -it --user nobody admiring_keller bash nobody@bc058746626a:/$ ss -nltp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 1 0.0.0.0:4444 0.0.0.0:* users:(("nc",pid=343,fd=3)) nobody@bc058746626a:/$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 4764 4124 pts/0 SNs 16:42 0:00 bash --login -i nobody 343 0.0 0.0 3204 864 pts/0 SN+ 16:45 0:00 nc -l 4444 nobody 369 0.0 0.0 3872 3152 pts/1 SNs 16:50 0:00 bash nobody 377 0.0 0.0 7644 2708 pts/1 RN+ 16:54 0:00 ps aux
對於普通使用者來說,這是正常行為。為了能夠將套接字與程序相關聯,在某些時候,
/proc/<pid>/fd/
必須由ss
. 只有同一個使用者或特權程序(包括以 root 身份執行)才能訪問它。這是關於 Docker 之外發生的事情的 strace 摘錄。
# runuser -u test -- sh -c 'echo $$; exec socat tcp4-listen:5555,reuseaddr -' 445406
旁邊:
user@host$ strace ss -tlnp sport == 5555 2>&1 |egrep -w '445406|^LISTEN' openat(AT_FDCWD, "/proc/445406/attr/current", O_RDONLY|O_CLOEXEC) = 4 openat(AT_FDCWD, "/proc/445406/fd/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = -1 EACCES (Permission denied) LISTEN 0 5 0.0.0.0:5555 0.0.0.0:*
不受約束的root使用者不會獲得 EACCESS,可以訪問所需的資訊,並且最終能夠顯示 PID。
但是 Docker 不能以普通 root使用者身份執行:一些功能(一個功能是root的“權力”。預設情況下, root擁有所有這些功能)被刪除了。並且由於容器中的這個root得到了與普通使用者相同的錯誤,無法訪問所需的資訊來將套接字與程序相關聯。
root@1589d8b38814:/# apt install libcap2-bin [...] oot@1589d8b38814:/# cat /proc/$$/status|grep ^Cap CapInh: 00000000a80425fb CapPrm: 00000000a80425fb CapEff: 00000000a80425fb CapBnd: 00000000a80425fb CapAmb: 0000000000000000 root@1589d8b38814:/# capsh --decode=00000000a80425fb 0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid, cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service, cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
當實際的root使用者或在特權模式下執行 Docker 容器時 (
--privileged
):root@cce7fc1de1c3:/# cat /proc/$$/status |grep ^Cap CapInh: 0000003fffffffff CapPrm: 0000003fffffffff CapEff: 0000003fffffffff CapBnd: 0000003fffffffff CapAmb: 0000000000000000 root@cce7fc1de1c3:/# capsh --decode=0000003fffffffff 0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search, cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap, cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin, cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio, cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot, cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod, cap_lease,cap_audit_write,cap_audit_control,cap_setfcap, cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm, cap_block_suspend,cap_audit_read
多得多。
在這裡丟棄
cap_sys_ptrace
(影響訪問/proc
)足以使其脫軌。請注意,非特權 Docker 容器不會授予cap_sys_ptrace
其 root 使用者。socat 以無人身份執行,pid 為 392,旁邊是特權 docker root 使用者:
root@df29c4a57b3f:/# capsh --inh= --caps= -- -c 'ss -tlnp sport == 5555' State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 5 0.0.0.0:5555 0.0.0.0:* users:(("socat",pid=392,fd=5)) root@df29c4a57b3f:/# capsh --drop=cap_sys_ptrace --inh= --caps= -- -c 'ss -tlnp sport == 5555' State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 5 0.0.0.0:5555 0.0.0.0:*