我试图了解 unix 域套接字的权限,当使用现有文件时,需要更改 umask 以及 dir 权限。
如果我以 root 身份创建一个世界可读的目录并使用 netcat 打开一个套接字:
root$: mkdir /tmp/mydir
root$: chmod 777 /tmp/mydir
root$: nc -l -U /tmp/mydir/sock
然后作为非 root 用户尝试连接到上述套接字它失败,尽管该目录是世界可读的:
https://man7.org/linux/man-pages/man7/unix.7.html
在 Linux 实现中,路径名套接字尊重它们所在目录的权限。如果进程对创建套接字的目录没有写入和搜索(执行)权限,则创建新套接字将失败。
root$: runuser -u user1 -- nc -U /tmp/mydir/sock
nc: unix connect failed: Permission denied
现在通过执行umask 0
,并再次重新启动同一个套接字,它可以从非 root 用户连接。
root$: umask 0
root$: nc -l -U /tmp/mydir/sock
root$: runuser -u user1 -- nc -U /tmp/mydir/sock
ping
此外,将/tmp/mydir
权限修改为chmod 600
将阻止非 root 用户再次访问套接字。
root$: chmod 600 /tmp/mydir
root$: runuser -u user1 -- nc -U /tmp/mydir/sock
nc: unix connect failed: Permission denied
很明显,目录权限按照手册的预期工作,但是如果父目录具有正确的权限,为什么需要 umask 0 ?netcat 是否仍在创建某种其他文件?
您在引用的同一个unix(7)联机帮助页中错过了这一点:
当然,您还需要对其路径中所有前导目录的搜索(执行)权限,就像任何其他文件一样。
您引用的部分是指创建一个套接字,这只发生在
bind(2)
ing 到它时,这就是nc -l -U /path/to/sock
它的作用。同样,就像创建任何其他文件一样,umask 将影响已创建套接字的权限(umask == 022 => 其他用户没有写权限 => 他们无法连接到套接字):绑定到 unix 域套接字总是必须从头开始创建它。您不能绑定到现有文件,该文件将失败并显示
EADDRINUSE
. 因此,大多数程序(包括nc
)会在绑定之前强制删除任何具有相同名称的文件:注意:这两个片段都讨论了磁盘上的“套接字”特殊文件/inode,而不是代表活动套接字对象的 inode(出现在
/proc/<pid>/fd
,/proc/net/unix
等中):