背景 我正在尝试解决 html 如何无法通过符号链接访问文件的问题。我进行了以下简单的实验,试图了解 apache 如何尝试统计/访问通过 simlink 指向的文件,但我无法理解为什么它不起作用。
作为用户 jzhu,我的主目录中有一个符号链接,指向根目录中名为 other 的目录,其中包含文件 anaconda-ks.cfg,我希望能够在 vi 中统计/读取该文件。但是,当我运行 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。如下所示,other 对该目录具有读取和可执行权限。
[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
所以我想问的两个问题如下。
- 为什么我无法 stat /home/jzhu/other/ 即使我对该目录中的 other 具有读取和可执行权限?
- 为什么我无法统计 anaconda-ks.cfg 文件?
答案1
您的答案在于您提供的第一个输出:
$ 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/other
这使得您的特定用户可以获得对其
/root/other
及其内部任何内容的执行访问权限。
这仍然不理想,因为这些资源是共享的,它们不应该位于根目录的主目录中。
请注意,在这两个解决方案中,我们仅授予执行 ( x
) 位。目录上需要执行位,用户才能访问该目录内的任何内容。但是,您还需要读取 ( r
) 位才能列出 ( ls
) 目录。这意味着如果没有读取位,您必须确切知道/root/other
文件的位置。如果要允许读取,只需将x
最后 2 个setfacl
命令中的 更改为rx
(例如-m u:jzhu:rx
)。
2、将资源转移到外面/root/other
。
这是首选解决方案。您可以删除 处的符号链接/home/jzhu/other
并在其位置创建一个目录,或者将它们放在系统上其他位置的共享位置(不知道它是什么,但我不能推荐一个好的位置)。
这是首选解决方案的原因是,如果这些资源在用户之间共享,那么它们不属于特定用户,也不应该位于该用户的主目录中。