root 和非 root 使用者之間的 unix 域套接字權限和 umask 集成
我試圖了解 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)聯機幫助頁中錯過了這一點:
在 Linux 上,連接到流套接字對象需要 對該套接字的**寫權限;**將數據報發送到數據報套接字同樣需要對該套接字的寫權限。
當然,您還需要對其路徑中所有前導目錄的搜尋(執行)權限,就像任何其他文件一樣。
您引用的部分是指創建一個套接字,這只發生在
bind(2)
ing 到它時,這就是nc -l -U /path/to/sock
它的作用。同樣,就像創建任何其他文件一樣,umask 將影響已創建套接字的權限(umask == 022 => 其他使用者沒有寫權限 => 他們無法連接到套接字):$ umask 0022 $ nc -Ul sock ^C $ ls -l sock srwxr-xr-x 1 xxx xxx 0 Oct 16 18:35 sock ^ ^ ^
綁定到 unix 域套接字總是必須從頭開始創建它。您不能綁定到現有文件,該文件將失敗並顯示
EADDRINUSE
. 因此,大多數程序(包括nc
)會在綁定之前強制刪除任何具有相同名稱的文件:$ echo text > file $ strace nc -l -U file ... socket(AF_UNIX, SOCK_STREAM, 0) = 3 unlink("file") = 0 bind(3, {sa_family=AF_UNIX, sun_path="file"}, 110) = 0 listen(3, 5) = 0 accept4(3,
注意:這兩個片段都討論了磁碟上的“套接字”特殊文件/inode,而不是代表活動套接字對象的 inode(出現在
/proc/<pid>/fd
,/proc/net/unix
等中):$ nc -lU sock & [1] 4424 $ ls -li sock 20983212 srwxr-xr-x 1 xxx xxx 0 Oct 17 18:01 sock ^^^^^^^^ $ ls -li /proc/4424/fd total 0 43825 lrwx------ 1 xxx xxx 64 Oct 17 18:02 0 -> /dev/pts/4 43826 lrwx------ 1 xxx xxx 64 Oct 17 18:02 1 -> /dev/pts/4 43827 lrwx------ 1 xxx xxx 64 Oct 17 18:02 2 -> /dev/pts/4 43828 lrwx------ 1 xxx xxx 64 Oct 17 18:02 3 -> socket:[46378] ^^^^^ $ grep 46378 /proc/net/unix 00000000ee8c0faa: 00000002 00000000 00010000 0001 01 46378 sock