我有一个 nagios 通知命令,如下所示:
/usr/bin/printf "%b" "NotificationType=$NOTIFICATIONTYPE$\nService=$SERVICEDESC$\nHost=$HOSTALIAS$\nAddress=$HOSTADDRESS$\nState=$SERVICESTATE$\nDateTime=$LONGDATETIME$\nAdditionalInfo=$SERVICEOUTPUT$\n" > $$(mktemp -p $CONTACTADDRESS1$ service.XXXXXXXX.alert)
添加一些换行符以提高可读性
/usr/bin/printf "%b"
"NotificationType=$NOTIFICATIONTYPE$\nService=$SERVICEDESC$\nHost=$HOSTALIAS$\nAddress=$HOSTADDRESS$\nState=$SERVICESTATE$\nDateTime=$LONGDATETIME$\nAdditionalInfo=$SERVICEOUTPUT$\n"
> $$(mktemp -p $CONTACTADDRESS1$ service.XXXXXXXX.alert)
这实际上会在定义的目录中创建一个新文件,$CONTACTADDRESS1$
在我的例子中是/home/alert/NagiosAlerts
.直到最近深入研究了权限和 ACL,我才明白我需要为此文件夹设置 gid 和一些默认 ACL,以确保我的 nagios 用户能够写入此目录,并且我的警报用户可以读取和写入文件在这里创建。所以我设置了以下内容
# setfacl -Rdm g:nagios:rw /home/alert/NagiosAlerts/
# setfacl -Rm g:nagios:rw /home/alert/NagiosAlerts/
所以文件夹权限现在看起来像这样
[kanmonitor01]# pwd
/home/alert/NagiosAlerts
[kanmonitor01]# ll ..
total 4
drwxrws---+ 2 alert nagios 4096 Dec 21 14:27 NagiosAlerts
[kanmonitor01]# getfacl .
# file: .
# owner: alert
# group: nagios
# flags: -s-
user::rwx
group::rwx
group:nagios:rw-
mask::rwx
other::---
default:user::rwx
default:group::rw-
default:group:nagios:rw-
default:mask::rw-
default:other::---
因此,作为 nagios 用户,我触摸了一个新文件......
[nagios@kanmonitor01]$ whoami
nagios
[nagios@kanmonitor01]$ touch file.bagel
[nagios@kanmonitor01]$ ll file.bagel
-rw-rw----+ 1 nagios nagios 0 Dec 21 14:57 file.bagel
我觉得还可以。文件的组权限是 rw- 我认为这是预期的结果。但是,当 nagios 服务执行问题开头的命令时,我最终得到以下结果:
[@kanmonitor01]# ll service.iCSThqzg.alert
-rw-------+ 1 nagios nagios 178 Dec 21 14:51 service.iCSThqzg.alert
[kanmonitor01]# getfacl service.iCSThqzg.alert
# file: service.iCSThqzg.alert
# owner: nagios
# group: nagios
user::rw-
group::rw- #effective:---
group:nagios:rw- #effective:---
mask::---
other::---
所以它有一个 ACL,但不是我想要的。对我来说这不是预期的行为。我看到很多关于某些二进制文件由于默认行为等原因不遵守 ACL 的问题。看来我的情况是mktemp
导致我出现这个问题的原因。我试图避免chmod
每次需要时都需要对每个文件进行操作。
不确定这里有什么好的行动方案。最终,我需要用户 nagios 能够将文件写入此目录,并且用户警报能够读取/写入这些相同的文件。 ACL 似乎是一条出路......
答案1
mktemp
显式创建具有权限 0600 的文件
$ strace -e open mktemp -p .
[...]
open("./tmp.EuTEGOcoEJ", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
这样就会覆盖那些默认的 ACL。mktemp
确实要求组和其他人没有权限。欺骗它以免它发生的方法是错误的。
您可以chmod
在创建后创建文件(事后违背 mktemp 的意愿):
file=$(mktemp....) && chmod g+r -- "$file" && ... > "$file"
或者使用mktemp
查找文件名但不创建它,并让 shell 重定向创建它:
umask 077; ... > "$(mktemp -u ...)"
在这种情况下,ACL 确实优先于umask
.
(此处-u
为 GNU mktemp
)是为了不安全虽然虽然mktemp
会尝试提出一个唯一的文件名,但它不能保证在之间不会创建该文件(可能作为到其他地方的符号链接,这是人们可能需要担心的事情)当它输出它并且 shell 打开它时。即使set -o clobber
无法防范它,因为它也有竞争条件(你需要zsh
's sysopen -o excl
here)。