iproute2 ss -не показывает информацию о процессе/pid, если пользователь не является тем же пользователем, что и слушающий процесс?

с помощью оператора &&

cp a.txt b.txt && vi b.txt
1
23.06.2021, 13:10
1 ответ

Для обычного пользователя это нормальное поведение. Чтобы иметь возможность связать сокет с процессом, в какой-то момент /proc/<pid>/fd/должен быть прочитан ss. Только тот же пользователь или привилегированный процесс (, в том числе запущенный как root ), имеет доступ к этому.

Вот выдержка о том, что происходит за пределами Docker.

# 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

При фактическом привилегированном пользователе или при запуске контейнера 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, работающим от имени none с идентификатором pid 392 и привилегированным корневым пользователем docker рядом:

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:*       
1
28.07.2021, 11:22

Теги

Похожие вопросы