我们如何锁定符号链接以使其无法被删除?
使用普通的文件/目录chattr +i /file/location
可以实现这一点,但是使用符号链接来实现这一点,我们得到chattr: Operation not supported while reading flags on my-file
。
有一个类似的问题,如何为我的“/etc/resolv.conf”设置“chattr +i”?,但没有可以应用于此处的解决方案。
答案1
这没有提供解决方案,但它解释了为什么chattr
不能使符号链接不可变。
在 Linux 上,不可变属性是一组标志的一部分,这些标志使用FS_IOC_SETFLAGS
ioctl
.从历史上看,这是首先在 ext2 中实现的,并且chattr
它本身仍然是e2fsprogs
.当它尝试时检索标志,在设置它们之前,chattr
显式检查它正在处理的文件是常规文件还是目录:
if (!lstat(name, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
goto notsupp;
}
人们可能认为删除这些检查,或更改它们以允许符号链接,将是允许符号链接不可变的良好第一步chattr
,但此后立即出现下一个障碍:
fd = open (name, OPEN_FLAGS);
if (fd == -1)
return -1;
r = ioctl (fd, EXT2_IOC_GETFLAGS, &f);
ioctl
对文件描述符进行操作,这意味着必须先打开目标,然后才能设置其标志。符号链接无法打开以用于ioctl
;尽管open
支持O_NOFOLLOW
和O_NOPATH
在符号链接上,前者本身将失败并显示ELOOP
,而后者将返回一个不能与 一起使用的文件描述符ioctl
。
答案2
符号链接不支持 chattr,但您可以使用绑定安装创建不可删除的链接。
对于目录:
$ mkdir a b
$ echo a>a/ok
$ sudo mount --bind a b
$ cat b/ok
a
$ rmdir b
rmdir: failed to remove 'b': Device or resource busy
对于文件:
$ mkdir c d
$ echo c>c/ok
$ echo d>d/ok
$ sudo mount --bind c/ok d/ok
$ cat d/ok
c
$ rm d/ok
rm: cannot remove 'd/ok': Device or resource busy
答案3
因为我无法发表评论:
chattr 最有可能使用 chmod、fchmod() 或 fchmodat() 系统调用之一,或 ioctl(其中没有提及任何有关符号链接的内容)。不过现在找不到哪个。使用此处的 Ubuntu 手册页,其中一些内容可能会发生变化。
来自 chmod 手册页:
chmod 永远不会更改符号链接的权限; chmod 系统调用无法更改其权限。这不是问题,因为符号链接的权限从未被使用过。然而,对于命令行上列出的每个符号链接,chmod 都会更改指向文件的权限。相反,chmod 会忽略递归目录遍历期间遇到的符号链接。
浏览 fchmod、chmod 和 fchmodat 系统调用的联机帮助页,它们都没有实现它。 Chmod-ing 只会取消引用路径,并且 fchmodat() 系统调用尚未实现 AT_SYMLINK_NOFOLLOW:
AT_SYMLINK_NOFOLLOW 如果路径名是符号链接,则不要取消引用它:而是对链接本身进行操作。该标志当前尚未实现。