我之前曾提出过有关阻止用户删除主目录中某些密钥文件/文件夹的问题:
/home
└── [-rw-rw-r-- daedalus ] daedalus
├── [-rw-rw-r-- root ] do_not_delete_file.cpp
├── [-rw-rw-r-- root ] do_not_delete_file.html
├── [-rw-rw-r-- root ] do_not_delete_file.php
├── [drwxrwxr-x root ] do_not_delete_folder
│ ├── [-rw-rw-r-- root ] do_not_delete_file.cpp
│ ├── [-rw-rw-r-- root ] do_not_delete_file.html
│ └── [-rw-rw-r-- root ] do_not_delete_file.php
└── [-rw-rw-r-- daedalus ] index.html
但由于用户daedalus
已在自己的/home/daedalus
文件夹中写入并因此删除了权限,因此失败了。因此,虽然他们无法修改,例如do_not_delete_file.php
,但他们总是可以删除它,然后将其替换掉。
但如果我有这样的东西呢
/home
└── [-rw-rw-r-- root ] daedalus
├── [-rw-rw-r-- root ] do_not_delete_file.cpp
├── [-rw-rw-r-- root ] do_not_delete_file.html
├── [-rw-rw-r-- root ] do_not_delete_file.php
├── [drwxrwxr-x root ] do_not_delete_folder
│ ├── [-rw-rw-r-- root ] do_not_delete_file.cpp
│ ├── [-rw-rw-r-- root ] do_not_delete_file.html
│ └── [-rw-rw-r-- root ] do_not_delete_file.php
├── [drwxrwxr-x daedalus ] Documents
└── [-rw-rw-r-- root ] index.html
我假设这可以通过一些chmod
动作实现,但是当程序自然地假设它们对主目录具有写权限时,是否会导致许多问题?如果这是个坏主意,我是否可以就如何解决这个问题得到一些其他建议。
编辑:我问这个问题的原因与LAMP编程有关。我正在创建一系列VHost,即:
www.user1.example.com
www.user2.example.com
www.userN.example.com
我希望将DocRoot设置为:
/home/user1
/home/user2
/home/userN
然而,我正在努力为个人用户提供太多/太少的自由。在最简单的情况下,我可能需要用户可以访问但不能修改/删除的do_not_delete_folder
。
答案 0 :(得分:3)
这有点棘手,但你可以使用Sticky Bit来做到这一点。
http://en.wikipedia.org/wiki/Sticky_bit
Linux内核忽略了Sticky Bit,除了目录。对于目录,linux只允许超级用户和所有者删除,重命名或取消链接文件。它不允许使用组权限访问该文件的用户。
例如,我的用户名为grape,是葡萄组的成员
要添加粘滞位,请使用chmod:
chmod +t [file]
在这里,您可以创建一个用户有权使用组但由root
拥有的目录drwxrwxr-T 2 root grape 4096 2012-04-19 20:49 st
在这种情况下,用户仍然可以在st中创建/删除自己的文件,但是无法删除root的文件,即使用户具有写权限:
-rwxrwxrwx 1 root root 0 2012-04-19 20:45 test
-rw-rw-r-- 1 grape grape 0 2012-04-19 20:56 test2
我仍然可以读/写这两个文件,但只有我拥有的文件我可以删除/移动
答案 1 :(得分:2)
许多程序 - 和用户 - 希望能够直接在其主目录中创建所需的任何文件。这可能是~/.xsession-errors
,~/.viminfo
,~/.lesshst
,~/.bash_history
或其他我可能错过的 - 或者我没有运行,但您的用户确实在运行。
所以,这不会是无痛的,但这里有一些想法:
您可以通过让其他人拥有主目录并设置目录的粘滞位来接近您想要的东西 - 这将要求用户拥有一个文件或目录它可以删除;来自unlink(2)
:
EPERM or EACCES
The directory containing pathname has the sticky bit
(S_ISVTX) set and the process's effective UID is
neither the UID of the file to be deleted nor that of
the directory containing it, and the process is not
privileged (Linux: does not have the CAP_FOWNER
capability).
您要么使用setfacl(1)
来设置访问控制列表,要么为每个用户提供自己的组。如果没有这两个步骤之一,您可能会意外地授予用户修改彼此数据的权限。
您可以使用chattr(1)
属性i
创建 immutable 文件 - 除特权进程外,不能修改,链接或取消链接。来自chattr(1)
:
A file with the `i' attribute cannot be modified: it cannot
be deleted or renamed, no link can be created to this file
and no data can be written to the file. Only the superuser
or a process possessing the CAP_LINUX_IMMUTABLE capability
can set or clear this attribute.
您可以使用 bind mounts 将文件或目录挂载到用户的主目录中。这可以在用户仍拥有其主目录时完成;只需运行mount -obind /path/to/source /home/daedalus/do_not_delete
。如果目录或文件不归用户所有,则无法修改文件,也无法修改安装点本身。 (他们可以修改更高级别的目录以使路径无意义 - 所以直接在主目录中执行此操作,但不要尝试将其放入子目录中。)
# mount -obind /etc /tmp/sarnold/mount_point/
# mount -obind /etc/passwd /tmp/sarnold/passwd
$ rm mount_point/
rm: cannot remove `mount_point/': Is a directory
$ rmdir mount_point/
rmdir: failed to remove `mount_point/': Device or resource busy
$ mv mount_point/ blob
mv: cannot move `mount_point/' to `blob': Device or resource busy
$ rm /tmp/sarnold/passwd
rm: remove write-protected regular file `/tmp/sarnold/passwd'? y
rm: cannot remove `/tmp/sarnold/passwd': Device or resource busy
$ mv /tmp/sarnold/passwd /tmp/sarnold/old_passwd
mv: cannot move `/tmp/sarnold/passwd' to `/tmp/sarnold/old_passwd': Device or resource busy
(我省略了创建挂载点;这只是一个简单的touch
或mkdir
。)
当然,每次重启时绑定挂载都会消失。您可能需要使用pam_exec(8)
或正确配置fstab(5)
以在每次登录或启动时重新创建绑定挂载。
您可以配置mandatory access control工具,例如AppArmor,SELinux,TOMOYO或SMACK,以限制用户进程可用的权限。 (我已经成为AppArmor团队的成员已有12年了;取决于您的服务器的使用方式,它可能是也可能不是这种用途的理想选择。我相信大多数这些系统都可以配置成你想要的,但由于AppArmor和TOMOYO是基于名称的,我相信他们更有可能控制对SELinux或SMACK的文件和目录的访问,而SELinux或SMACK是基于标签的系统。)