![允许所有者创建和读取文件,但不能修改或删除](https://linux22.com/image/70811/%E5%85%81%E8%AE%B8%E6%89%80%E6%9C%89%E8%80%85%E5%88%9B%E5%BB%BA%E5%92%8C%E8%AF%BB%E5%8F%96%E6%96%87%E4%BB%B6%EF%BC%8C%E4%BD%86%E4%B8%8D%E8%83%BD%E4%BF%AE%E6%94%B9%E6%88%96%E5%88%A0%E9%99%A4.png)
我想授予用户在特定目录中创建和读取文件的权限,但不能修改或删除文件。如果用户可以附加到文件中,那没问题,但我宁愿不这样做。这是在 Ubuntu Linux 上。
我认为这对于标准 Unix 文件权限来说是不可能的,但也许使用 ACL 是可能的?用户将始终使用 SFTP 进行连接,因此如果有某种方法可以在 SFTP 中控制这一点(而不是操作系统权限),那就没问题了。
为了绝对清楚,我想要以下内容:
- echo hello > test # 成功,因为test不存在,允许创建
- echo hello >> test # 可能成功或失败,取决于是否允许附加
- echo hello2 > test #失败,因为test已经存在,不允许修改
- cat test # 成功,因为允许读取
- rm test # 失败,因为不允许删除
如果您想知道我为什么要这样做,是为了让 Duplicati 备份系统能够抵抗勒索软件。
答案1
你可以bindfs
这样使用:
$ ls -ld dir
drwxr-xr-t 2 stephane stephane 4096 Aug 12 12:28 dir/
该目录由 Stephane 拥有,属于 Stephane 组(Stephane 是其唯一成员)。另请注意,t
这会阻止用户重命名或删除不属于他们的条目。
$ sudo bindfs -u root -p u=rwD,g=r,dg=rwx,o=rD dir dir
我们bindfs
dir
对文件和目录具有固定的所有权和权限。所有文件都显示为所有者root
(尽管在真实目录下面,它们仍然属于 Stephane)。
目录获得drwxrwxr-x root stephane
权限,而其他类型的文件获得-rw-r--r-- root stephane
权限。
$ ls -ld dir
drwxrwxr-t 2 root stephane 4096 Aug 12 12:28 dir
现在创建文件可以工作,因为该目录是可写的:
$ echo test > dir/file
$ ls -ld dir/file
-rw-r--r-- 1 root stephane 5 Aug 12 12:29 dir/file
然而不可能再做第二次写 open()
对该文件,因为我们没有权限:
$ echo test > dir/file
zsh: permission denied: dir/file
(请注意,那里不允许附加(这不是您初始要求的一部分))。
dir
限制:虽然由于该位您无法删除或重命名其中的条目t
,但您在其中创建的新目录不会有该t
位,因此您可以在那里重命名或删除条目。
答案2
该chattr +a
选项仅允许附加。文件可以通过这种方式更改,但只能通过向其中添加(即附加行)来更改。您无法删除现有文件,但可以创建新文件。这可能适合您的需求:
sudo chattr -R +a /dir/to/apply/to
从man chattr
设置了“a”属性的文件只能以附加模式打开进行写入。只有超级用户或拥有 CAP_LINUX_IMMUTABLE 能力的进程才能设置或清除该属性。
(请注意,它也适用于目录)
所以你的列表看起来像:
echo hello > test # succeeds, because test doesn't exist, and creation is allowed
echo hello2 > test # fails, because test already exists, and overwriting is not allowed
echo hello3 >> test # succeeds, because appending is allowed
cat test # succeeds, because reads are allowed
rm test # fails, because delete is not allowed