4

I've installed PostgresQL on a SELinux-enabled Centos 7 box and changed it's default data directory to /srv/postgres, a separate LUKS-encrypted LVM volume group/logical volume, for reasons of mobility, in case I have to move the server, and confidentiality, should the data media be stolen or exposed while moving. I think that the LUKS/LVM functionality involved shouldn't affect my problem, but mention it for reasons of completeness.

Now, when I start the postgresql service:

root@fafner:~ # systemctl start postgresql

... I get this in /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'

I've tried using audit2allow to fix the issue:

root@fafner:~ # grep "postgresql" /var/log/audit/audit.log | audit2allow -M postgresql_tskjoedt
root@fafner:~ # semodule -i postgresql_tskjoedt.pp

... rendering some output in /var/log/audit/audit.log that I've [removed from the post since it proved irrelevant]. It didn't fix the problem, though, the error persists in exactly the same form.

I've also tried:

root@fafner:~ # restorecon -Rv /usr/bin/pg_ctl
root@fafner:~ # restorecon -Rv /usr/bin/postgres
root@fafner:~ # restorecon -Rv /srv/postgres/data

... and even touch'ing a '.autorelabel'-file on the root and postgres filesystems, and rebooting, to relabel everything involved. But I still get the same "denied open for pg_ctl on postgresql.conf" error in audit.log.

I've done these things a couple of times assuming that the changes are not cumulative.

From this answer and some of the links that it refers to I gather that somehow these SELinux contexts/labels do not line up properly:

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

I could just shuffle the labels around until something may start working, but I don't want to arbitrarily set or ruin SELinux labels just to get things working; then I might as well just turn off SELinux.

Also, I don't understand why 'audit2allow' doesn't fix the specific problem; isn't this command supposed to do exactly that, in essence, widen the SELinux context just enough for the specific operation to be allowed?

This whole question of course stems from my lack of understanding of SELinux, and much of the audit.log output is relatively obscure to me. Can someone pinpoint what clue I should be picking up on?

Kind regards,

LANerd

4

Why change the data directory? That just makes your life complicated. You could have mounted the filesystem at the point of the default data directory, and everything would have just worked. It would also be easier to understand and maintain.

Filesystem                  Size  Used Avail Use% Mounted on
/dev/mapper/volgroup-pgsql  1.1T  128K  1.1T   1% /var/lib/pgsql

If you really mean to keep the non-default data directory, then you need to tell SELinux what contexts to apply to that directory and its contents. This is done with semanage fcontext. In this case, we're going to use the --equal option to make your non-default directory have the same contexts as the default directory /var/lib/pgsql.

semanage fcontext --add --equal /var/lib/pgsql /srv/postgres

From the man page:

       -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.

This is persistent, but it doesn't change existing labels. To finish up, you'll need to run restorecon to reset all the labels.

restorecon -rv /srv/postgres
  • Et voilá! That did it: – LANerd Oct 17 '16 at 3:37
  • You are right about the default location, that is easier. The PostgresQL documentation page says that /var/lib/pgsql is a popular choice, but not with me. Maybe I got it wrong, but I like the FHS (en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard) and try to keep separate binaries, libraries, configuration, data, and so forth. And as much as I love PostgresQL this is one thing that it doesn't do; e.g., the configuration files are kept with the data in $PGDATA. – LANerd Oct 17 '16 at 3:42
  • So, thanks a lot! That 'equal' option is duly noted! – LANerd Oct 17 '16 at 3:43
  • @LANerd The FHS is nice, but making things fit into it is really work for the developers and distribution packagers. Doing this sort of thing yourself is just a recipe for pain, especially in an operations context. I recommend you leave it in place, and file a bug report to get the distro or upstream to package it in an FHS compliant way (or find out why they don't, as there might be a good reason). – Michael Hampton Oct 17 '16 at 4:38
  • I will do that, it never ocurred to me to ask. I simply assumed that is was an idiosyncrasy. Actually I work with databases and generally with security in an operations context. I see three benefits with changing standards to meet the FHS: 1) I remember my newbie days, and it is easier to get newbies (of which we have a bunch) to understand the layout if everything is in the place you'd expect (also, it sits better with my own OCD ;), 2) it makes for cleaner configuration management if you know you have everything in /etc (-like) places, 3) it makes for cleaner backup jobs... – LANerd Oct 20 '16 at 10:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.