Symlink

無法統計到文件的符號連結

  • November 4, 2013

背景 我試圖弄清楚 html 如何無法通過符號連結訪問文件。我進行了以下簡單的實驗,試圖了解 apache 將如何嘗試統計/訪問通過 simlink 指向的文件,但我無法理解它為什麼不起作用。

作為使用者 jzhu,我在我的主目錄中有一個符號連結,指向名為 other 的根目錄,其中包含我希望能夠在 vi 中統計/讀取的文件 anaconda-ks.cfg。但是,當我執行 stat 命令時,我得到了以下結果。

[jzhu@localhost ~]$ stat /home/jzhu/other/anaconda-ks.cfg
stat: cannot stat `/home/jzhu/other/anaconda-ks.cfg': Permission denied

這是 /home/jzhu/other 符號連結的 stat 命令,因此您可以進一步說明我的設置方式。

[jzhu@localhost ~]$ stat /home/jzhu/other
 File: `/home/jzhu/other' -> `/root/other/'
 Size: 12          Blocks: 0          IO Block: 4096   symbolic link
Device: fd00h/64768d    Inode: 43313       Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:52:20.602126433 +0000
Modify: 2013-11-03 08:52:20.187918394 +0000
Change: 2013-11-03 08:52:20.187918394 +0000

查找 lstat 的手冊頁,我看到以下引用:

這些函式返回有關文件的資訊。文件本身不需要權限,但在 stat() 和 lstat() 的情況下,需要對指向文件的路徑中的所有目錄具有執行(搜尋)權限。

據我了解,stat 命令不需要 /root 本身的可執行權限,因為與 lstat 不同,它開始的根目錄是執行它的目前目錄,這意味著它不會使用“/”的完整路徑root/other/”,但將使用路徑“/home/jzhu/other/”。我通過以下相關輸出通過 strace 確認了這一點

lstat("/home/jzhu/other/anaconda-ks.cfg", 0x7fff14d5a7c0) = -1 EACCES (Permission denied)

所以為了讓我統計這個文件,我只需要 /home /home/jzhu 和 /home/jzhu/other 的可執行權限

作為 jzhu,我在 /home 和 /home/jzhu 上執行了一個統計資訊,以確認我具有可執行權限。如下圖

[jzhu@localhost ~]$ stat /home/
 File: `/home/'
 Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 2278        Links: 4
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:52:13.797724760 +0000
Modify: 2013-11-04 00:03:45.377150769 +0000
Change: 2013-11-04 00:03:45.377150769 +0000
[jzhu@localhost ~]$ stat /home/jzhu
 File: `/home/jzhu'
 Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 43317       Links: 3
Access: (0700/drwx------)  Uid: (  500/    jzhu)   Gid: (  500/    jzhu)
Access: 2013-11-04 00:00:30.809916040 +0000
Modify: 2013-11-03 23:49:54.781060426 +0000
Change: 2013-11-03 23:49:54.781060426 +0000

但是我無法將 /home/jzhu/other 設為 jzhu:

[jzhu@localhost ~]$ stat /home/jzhu/other/
stat: cannot stat `/home/jzhu/other/': Permission denied

也改回來並在目錄上執行 stat 。我對為什麼無法將目錄統計為 jzhu 感到困惑。如下所示,其他人對該目錄具有讀取和可執行權限。

[root@localhost jzhu]# stat /home/jzhu/other/
 File: `/home/jzhu/other/'
 Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 32674       Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:50:36.935318703 +0000
Modify: 2013-11-03 08:50:35.772737444 +0000
Change: 2013-11-03 08:50:35.772737444 +0000
[root@localhost jzhu]# stat /home/jzhu/other/anaconda-ks.cfg 
 File: `/home/jzhu/other/anaconda-ks.cfg'
 Size: 985         Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 43297       Links: 1
Access: (0777/-rwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-11-03 08:50:35.772737444 +0000
Modify: 2013-11-03 08:50:35.781741701 +0000
Change: 2013-11-03 08:54:50.814196796 +0000

所以我想問的兩個問題如下。

  1. 為什麼我無法 stat /home/jzhu/other/ 即使我對該目錄中的 other 具有讀取和可執行權限?
  2. 為什麼我無法統計 anaconda-ks.cfg 文件?

您的答案在於您提供的第一個輸出:

$ stat /home/jzhu/other
 File: `/home/jzhu/other' -> `/root/other/'

這表明這/home/jzhu/other是一個符號連結/root/other

所以基本上要訪問/home/jzhu/other/你需要訪問的任何內容/root/other。這意味著您的使用者必須對/root和都具有執行權限/root/other


接下來讓我們繼續執行此命令:

$ stat /home/jzhu/other/
stat: cannot stat `/home/jzhu/other/': Permission denied

這失敗並且上述一個有效的原因是因為尾隨/. 在任何與路徑一起工作的命令上,如果該路徑的最終組件(例如other:)是符號連結,並且路徑以尾隨 結尾/,那麼任何對該路徑進行操作的系統呼叫都將嘗試取消引用該符號連結,並進行操作關於符號連結指向的內容而不是符號連結本身。


解決方案:

對此有兩種可能的解決方案。

1.更改權限/root/other

如前所述,為/root和都添加執行功能/root/other。您可以使用基本或擴展文件系統屬性來做到這一點。

  • 您可以將jzhu使用者添加到root組 ( usermod -a -G root jzhu) 並將組執行添加到路徑 ( chmod g+x /root; chmod g+x /root/other)。

這不是一個理想的解決方案,因為它授予您對僅限於該root組的任何內容的訪問權限。

  • 使用文件系統 ACL。
setfacl -mu:jzhu:x /root
setfacl -R -mu:jzhu:x /root/其他
setfacl -d -R -mu:jzhu:x /root/其他

這使得您的特定使用者可以執行訪問權限/root/other以及其中的任何內容。

如果這些資源是共享的,它們仍然不理想,它們不應該在根目錄的主目錄中。

請注意,在這兩種解決方案中,我們只授予執行 ( x) 位。目錄上需要執行位,使用者才能訪問該目錄內的任何內容。但是,您還需要讀取 ( r) 位才能列出 ( ls) 目錄。這意味著如果沒有讀取位,您將必須確切知道/root/other文件的位置。如果要允許讀取,只需x將最後 2 個setfacl命令中的 更改為rx(例如,-m u:jzhu:rx)。

2.將資源外移/root/other

這是首選的解決方案。您可以擺脫符號連結/home/jzhu/other並在其位置創建一個目錄,或者將它們放在系統上其他位置的共享位置(雖然不知道它是什麼,但我不能推荐一個好的位置)。

這是首選解決方案的原因是,如果這些資源在使用者之間共享,那麼它們不屬於特定使用者,也不應該在該使用者的主目錄中。

引用自:https://unix.stackexchange.com/questions/98754