我在 CentOS 6 上安装了 opendkim,并在配置文件中将其设置TemporaryDirectory
为。重新启动服务并尝试发送电子邮件后,我在 postfix 日志中收到一条错误,内容为/var/tmp
opendkim.conf
opendkim[27392]: F2C3E20509: dkim_eoh(): resource unavailable: can't create temporary file at /var/tmp/dkim.F2C3E20509.FiOvYB: Permission denied
因此,我查看了 tmp 文件夹的权限(ls -l /var/
),它们是
drwxrwxrwt. 2 root root 4096 Nov 23 20:42 tmp
据我了解,每个人都应该能够写入该/var/tmp
文件夹。为什么会Permission denied
返回错误消息?
答案1
- 更新后的答案*
去/etc/opendkim.conf并修改此行:
TemporaryDirectory /var/tmp
到:
TemporaryDirectory /var/run/opendkim
并重新启动您的邮件服务(例如
# service opendkim restart
# chkconfig opendkim on
# service postfix restart
答案2
根据我的经验,这是由于缺少 SELinux 策略造成的。您可以从审计日志中获取详细说明缺少权限的错误,然后使用该错误生成 SELinux 模块包:
grep opendkim /var/log/audit/audit.log | audit2allow -M opendkim
-M 选项指定模块包的名称,您可以根据需要将其命名为其他名称。该命令将生成两个文件:opendkim.pp(实际的 selinux 模块包)和 opendkim.te(一个文本文件,显示模块包包含哪些策略)。
如果策略看起来不错,则使用以下命令导入模块包:
semodule -i opendkim.pp
答案3
这个问题已经有解决方案了这里
无需允许 OpenDKIM 写入任何其他目录。只需写入默认临时目录 /var/run/opendkim,该目录应该已经存在,并且具有允许其写入的正确 SELinux 上下文。
(和这里是一个解决方案避免SELinux 方式解决这个问题。
所以。非常老的线程无法解决。大约几天前,我发现了这个线程,因为我遇到了同样的问题,并使用 Dedgar 的解决方案解决了。
如果你真的想设置Temporary
为/var/tmp
日志如下:
opendkim[46233]: E9A563F480: dkim_eoh(): resource unavailable: can't create temporary file at /var/tmp/dkim.E9A563F480.IjgWhi: Permission denied
正如 Chloe 所说,这是一个 SELinux 错误,因为everbody should be able to write into the /var/tmp folder
检查日志文件
# grep opendkim /var/log/audit/audit.log
得到:
...
type=SYSCALL msg=audit(1484968513.231:1415886): arch=c000003e syscall=2 success=no exit=-13 a0=7fc21e6e4910 a1=c2 a2=180 a3=0 items=0 ppid=46231 pid=14906 auid=500 uid=497 gid=497 euid=497 suid=497 fsuid=497 egid=497 sgid=497 fsgid=497 tty=(none) ses=3274 comm="opendkim" exe=2F7573722F7362696E2F6F70656E646B696D202864656C6574656429 subj=unconfined_u:system_r:dkim_milter_t:s0 key=(null)
type=AVC msg=audit(1484968573.318:1415887): avc: denied { write } for pid=14916 comm="opendkim" name="tmp" dev=dm-0 ino=129564 scontext=unconfined_u:system_r:dkim_milter_t:s0 tcontext=system_u:object_r:tmp_t:s0 tclass=dir
...
正如 Dedgar 所说,opendkim 似乎缺少一个可以从tmp
文件创建文件的策略。因此,首先,检查目录类型
# ll -Zd /var/tmp/
drwxrwxrwt. root root system_u:object_r:tmp_t:s0 /var/tmp/
然后检查是否opendkim
有权限访问/var/tmp
# ll -Z /usr/sbin/opendkim
-rwxr-xr-x. root root system_u:object_r:dkim_milter_exec_t:s0 /usr/sbin/opendkim
# sesearch -A -s dkim_milter_t| grep tmp_t
输出可能如下所示:
...允许守护进程 puppet_tmp_t:文件 {ioctl 读取 写入 getattr 锁定附加}; 允许 dkim_milter_t tmp_t:文件 {写入创建取消链接打开}; 允许 dkim_milter_t tmp_t:dir {写入 add_name remove_name}; 允许域 tmp_t:dir {getattr 搜索打开}; ...
线路通告
allow dkim_milter_t tmp_t : file { write create unlink open } ;
allow dkim_milter_t tmp_t : dir { write add_name remove_name } ;
它几乎告诉用户dkim_milter_t
有权访问tmp_t
类似类型的目录/var/tmp
,
但大多数情况下我们没有此行输出或者这个配置根本不起作用或者其他情况...
因此,我们需要添加一个策略,为访问文件或目录的策略授予权限dkim_milter_t
。opendkim
最type
tmp_t
简单的方法是使用audit2allow就像 Dedgar 所说:
grep opendkim /var/log/audit/audit.log | audit2allow -M opendkim
semodule -i opendkim.pp
它会生成一个 SELinux 策略来执行之前的操作。但不确定它在 Chloe 的情况下是否有效。把我的 opendkim.te 放进去:
module opendkim 1.0;
require {
type tmp_t;
type dkim_milter_t;
class dir { write remove_name add_name };
class file { write create unlink open };
}
allow dkim_milter_t tmp_t:dir { write remove_name add_name };
allow dkim_milter_t tmp_t:file { write create unlink open };
如果您需要手动重新生成文件(opendkim.pp),该怎么办?
checkmodule -M -m -o opendkim.mod opendkim.te
semodule_package -o opendkim.pp -m opendkim.mod
满足semodule -i opendkim.pp
您的需要。