我在启用了 SELinux 的 Centos 7 机器上安装了 PostgresQL,并且更改了其默认数据目录到 /srv/postgres,一个单独的 LUKS 加密 LVM 卷组/逻辑卷,出于移动性的原因,以防我必须移动服务器,以及保密性,以防数据介质在移动过程中被盗或暴露。我认为所涉及的 LUKS/LVM 功能不应该影响我的问题,但出于完整性的原因还是提到它。
现在,当我启动 postgresql 服务时:
root@fafner:~ # systemctl start postgresql
...我在/var/log/audit/audit.log中得到了这个:
root@fafner:~ # tail -f /var/log/audit/audit.log | grep "postgresql"
[..]
type=AVC msg=audit(1476614020.689:522): avc: denied { open } for pid=2900 comm="pg_ctl" path="/srv/postgres/data/postgresql.conf" dev="dm-4" ino=136 scontext=system_u:system_r:postgresql_t:s0 tcontext=unconfined_u:object_r:var_t:s0 tclass=file type=SYSCALL msg=audit(1476614020.689:522): arch=c000003e syscall=2 success=no exit=-13 a0=7ffc681cc430 a1=0 a2=1b6 a3=24 items=1 ppid=1 pid=2900 auid=4294967295 uid=989 gid=986 euid=989 suid=989 fsuid=989 egid=986 sgid=986 fsgid=986 tty=(none) ses=4294967295 comm="pg_ctl" exe="/usr/bin/pg_ctl" subj=system_u:system_r:postgresql_t:s0 key=(null)
type=PATH msg=audit(1476614020.689:522): item=0 name="/srv/postgres/data/postgresql.conf" inode=136 dev=fd:04 mode=0100600 ouid=989 ogid=986 rdev=00:00 obj=unconfined_u:object_r:var_t:s0 objtype=NORMAL
type=AVC msg=audit(1476614020.725:523): avc: denied { open } for pid=2904 comm="postgres" path="/srv/postgres/data/postgresql.conf" dev="dm-4" ino=136 scontext=system_u:system_r:postgresql_t:s0 tcontext=unconfined_u:object_r:var_t:s0 tclass=file type=SYSCALL msg=audit(1476614020.725:523): arch=c000003e syscall=2 success=no exit=-13 a0=befc30 a1=0 a2=1b6 a3=24 items=1 ppid=2900 pid=2904 auid=4294967295 uid=989 gid=986 euid=989 suid=989 fsuid=989 egid=986 sgid=986 fsgid=986 tty=(none) ses=4294967295 comm="postgres" exe="/usr/bin/postgres" subj=system_u:system_r:postgresql_t:s0 key=(null)
type=PATH msg=audit(1476614020.725:523): item=0 name="/srv/postgres/data/postgresql.conf" inode=136 dev=fd:04 mode=0100600 ouid=989 ogid=986 rdev=00:00 obj=unconfined_u:object_r:var_t:s0 objtype=NORMAL
type=SERVICE_START msg=audit(1476614021.712:524): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=postgresql comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=failed'
我尝试使用 audit2allow 来修复该问题:
root@fafner:~ # grep "postgresql" /var/log/audit/audit.log | audit2allow -M postgresql_tskjoedt
root@fafner:~ # semodule -i postgresql_tskjoedt.pp
... 在 /var/log/audit/audit.log 中呈现一些输出,我已 [从帖子中删除,因为它被证明不相关]。但它并没有解决问题,错误仍然以完全相同的形式存在。
我也尝试过:
root@fafner:~ # restorecon -Rv /usr/bin/pg_ctl
root@fafner:~ # restorecon -Rv /usr/bin/postgres
root@fafner:~ # restorecon -Rv /srv/postgres/data
... 甚至在根和 postgres 文件系统上触摸 '.autorelabel' 文件,然后重新启动,以重新标记所涉及的所有内容。但我仍然在 audit.log 中收到相同的“拒绝在 postgresql.conf 上打开 pg_ctl”错误。
我已经做过几次这些事情,假设变化不是累积的。
从这个答案并且根据它引用的一些链接,我发现这些 SELinux 上下文/标签没有正确排列:
root@fafner:~ # ls -Z /usr/bin/pg_ctl
-rwxr-xr-x. root root system_u:object_r:postgresql_exec_t:s0 /usr/bin/pg_ctl
root@fafner:~ # ls -Z /usr/bin/postgres
-rwxr-xr-x. root root system_u:object_r:postgresql_exec_t:s0 /usr/bin/postgres
root@fafner:~ # ls -Z /srv/postgres/data/postgresql.conf
-rw-------. postgres postgres unconfined_u:object_r:var_t:s0 /srv/postgres/data/postgresql.conf
我可以随意调整标签直到某些东西开始工作,但我不想为了让事情正常运转而任意设置或破坏 SELinux 标签;那么我还不如关闭 SELinux。
另外,我不明白为什么“audit2allow”不能解决特定问题;这个命令不是应该这样做吗,本质上,扩大 SELinux 上下文,足以允许特定操作?
整个问题当然源于我对 SELinux 的了解不足,而且 audit.log 输出的大部分内容对我来说比较晦涩难懂。有人能指出我应该注意什么线索吗?
亲切的问候,
兰纳德
答案1
为什么要更改数据目录?这只会让您的工作变得复杂。您可以将文件系统挂载到默认数据目录的位置,这样一切都会正常工作。这也将更易于理解和维护。
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/volgroup-pgsql 1.1T 128K 1.1T 1% /var/lib/pgsql
如果你确实想保留非默认数据目录,那么你需要告诉 SELinux 要将哪些上下文应用于该目录及其内容。这可以通过以下方式完成semanage fcontext
。在本例中,我们将使用该--equal
选项使您的非默认目录具有与默认目录相同的上下文/var/lib/pgsql
。
semanage fcontext --add --equal /var/lib/pgsql /srv/postgres
从手册页中:
-e EQUAL, --equal EQUAL
Substitute target path with sourcepath when generating default
label. This is used with fcontext. Requires source and target
path arguments. The context labeling for the target subtree is
made equivalent to that defined for the source.
这是持久性的,但不会改变现有标签。要完成此操作,您需要运行restorecon
以重置所有标签。
restorecon -rv /srv/postgres