Bug 848158

Summary: PostgreSQL SELinux policy lacks tunables akin to httpd_can_network_connect
Product: Red Hat Enterprise Linux 6 Reporter: Dmitry S. Makovey <dmitry>
Component: selinux-policyAssignee: Miroslav Grepl <mgrepl>
Status: CLOSED NOTABUG QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 6.3CC: dwalsh, mmalik, tgl
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-08-20 09:31:24 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Dmitry S. Makovey 2012-08-14 19:05:20 UTC
Description of problem:

Current postgreSQL startup scripts are flexible enough to be able to spin several instances of PostgreSQL DB on the same box. While no extra coding required for that to happen:

 $ cd /etc/init.d/; ln -s postgresql mypg
 $ su postgres -c 'mkdir /var/lib/pgsql/data.mypg'
 $ echo "PGPORT=9876;PGDATA=/var/lib/pgsql/data.mypg" > /etc/sysconfig/pgsql/mypg
 $ service mypg start

with SELinux on, one has to craft special module. For certain setups I would be beneficial to have tunable "postgres_alternative_ports" or something that would allow either range of the ports to be used by newly spawned postgreSQL instances or any port. 

Admitably this will only work for some cases where PostgreSQL is in "trusted" environment, in other cases custom policy would be a better route. 

Version-Release number of selected component (if applicable):

postgresql-8.4.12-1.el6_2.x86_64

How reproducible:

often

Steps to Reproduce:

1. $ cd /etc/init.d/; ln -s postgresql mypg
2. $ su postgres -c 'mkdir /var/lib/pgsql/data.mypg'
3. $ echo "PGPORT=9876;PGDATA=/var/lib/pgsql/data.mypg" > /etc/sysconfig/pgsql/mypg
4. $ service mypg start
  
Actual results:

SELinux denial of access. Requirement to build a policy module.

Expected results:

tweak of a tunable should allow successfull startup for the situations where security can be less strict

Additional info:

I have posted a bit more information in other bug ( if that is of any interest ) : bug #847357

Comment 2 Daniel Walsh 2012-08-15 10:29:12 UTC
Why wouldn't 

semanage port -a -t  postgresql_port_t -p tcp PORTNUM

Work for you?

Comment 3 Dmitry S. Makovey 2012-08-15 16:58:52 UTC
Thanks Dan,

that indeed is as concise as setting up a tunable, and worth documenting someplace (I mean for postgresql users - "actions to perform to spin up another instance"). I appologize for not noticing "semanage port" to begin with. 

Just for completeness sake - as Tom Lane made me realize /var/lib/pgsql/dataXX would need to be relabeled too... or easier alternative would be to set up /var/lib/pgsql/data/A1 /var/lib/pgsql/data/A2 for A1 and A2 instances of postgres - this way SELinux labeling is preserved. 

From my end it seems to be resolved, but maybe it's worth reassigning to documentation team to get all of the above reflected in current documentation?

Comment 4 Dmitry S. Makovey 2012-08-15 17:19:12 UTC
Just a note: audit2{allow,why} for situation in comment #1 where slightly misleading:

# echo "PGPORT=15432" > /etc/sysconfig/pgsql/postgresql 

# service postgresql start
Starting postgresql service:                               [FAILED]

# audit2allow < /var/log/audit/audit.log


#============= postgresql_t ==============
#!!!! This avc can be allowed using the boolean 'allow_ypbind'

allow postgresql_t port_t:tcp_socket name_bind;

# audit2why < /var/log/audit/audit.log
type=AVC msg=audit(1345051006.095:314): avc:  denied  { name_bind } for  pid=6053 comm="postmaster" src=15432 scontext=unconfined_u:system_r:postgresql_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket

        Was caused by:
        The boolean allow_ypbind was set incorrectly. 
        Description:
        Allow system to run with NIS

        Allow access by executing:
        # setsebool -P allow_ypbind 1
type=AVC msg=audit(1345051006.132:315): avc:  denied  { name_bind } for  pid=6053 comm="postmaster" src=15432 scontext=unconfined_u:system_r:postgresql_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket

        Was caused by:
        The boolean allow_ypbind was set incorrectly. 
        Description:
        Allow system to run with NIS

        Allow access by executing:
        # setsebool -P allow_ypbind 1

Comment 5 Daniel Walsh 2012-08-15 18:21:15 UTC
Yes we have more information in setroublshoot.

sealert -a /tmp/t
100% done'tuple' object has no attribute 'split'
100% donefound 1 alerts in /tmp/t
--------------------------------------------------------------------------------

SELinux is preventing postmaster from name_bind access on the tcp_socket .

*****  Plugin bind_ports (99.5 confidence) suggests  *************************

If you want to allow postmaster to bind to network port 15432
Then you need to modify the port type.
Do
# semanage port -a -t PORT_TYPE -p tcp 15432
    where PORT_TYPE is one of the following: postgresql_port_t.

*****  Plugin catchall (1.49 confidence) suggests  ***************************

If you believe that postmaster should be allowed name_bind access on the  tcp_socket by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep postmaster /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp


Additional Information:
Source Context                unconfined_u:system_r:postgresql_t:s0
Target Context                system_u:object_r:port_t:s0
Target Objects                 [ tcp_socket ]
Source                        postmaster
Source Path                   postmaster
Port                          15432
Host                          <Unknown>
Source RPM Packages           
Target RPM Packages           
Policy RPM                    selinux-policy-3.11.1-7.fc18.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     celtics
Platform                      Linux celtics 3.6.0-0.rc1.git4.1.fc18.x86_64 #1
                              SMP Sun Aug 12 21:19:31 UTC 2012 x86_64 x86_64
Alert Count                   1
First Seen                    2012-08-15 13:16:46 EDT
Last Seen                     2012-08-15 13:16:46 EDT
Local ID                      9d7d6e66-4eec-44fd-827b-39c0a8b44be7

Raw Audit Messages
type=AVC msg=audit(1345051006.95:314): avc:  denied  { name_bind } for  pid=6053 comm="postmaster" src=15432 scontext=unconfined_u:system_r:postgresql_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket


Hash: postmaster,postgresql_t,port_t,tcp_socket,name_bind

audit2allow

#============= postgresql_t ==============
#!!!! This avc can be allowed using the boolean 'nis_enabled'

allow postgresql_t port_t:tcp_socket name_bind;

audit2allow -R

#============= postgresql_t ==============
#!!!! This avc can be allowed using the boolean 'nis_enabled'

allow postgresql_t port_t:tcp_socket name_bind;

Comment 6 Dmitry S. Makovey 2012-08-15 18:44:55 UTC
Thanks Dan, that is useful to know. Does that mean that one should depend more on sealert rather than audit2* tools alone? I do realize that there's inaccuracy involved and it can't be 100% accurate, but I am looking for the best path of troubleshooting it in the future.

Comment 7 Daniel Walsh 2012-08-15 19:17:52 UTC
setroubleshoot/sealert is smarter the audit2allow. (It actually uses audit2allow, but has a richer database.)

Slowly but surely we will be moving some of sealert smarts into audit2allow.

Comment 8 Tom Lane 2012-08-15 19:42:05 UTC
(In reply to comment #3)
> From my end it seems to be resolved, but maybe it's worth reassigning to
> documentation team to get all of the above reflected in current
> documentation?

I'll see about capturing some of this knowledge in the postgresql RPM's README, at least.  I'm not sure if there is anyplace where more formal documentation should go.

In the meantime, this seems like NOTABUG for the selinux-policy crew.

Comment 9 Dmitry S. Makovey 2012-08-15 20:54:19 UTC
works for me. Thanks.

Comment 10 Tom Lane 2012-08-17 16:38:48 UTC
I've added the following text to the README.rpm-dist doc file for postgresql:

If you are running SELinux in enforcing mode (which is highly recommended,
particularly for network-exposed services like PostgreSQL) you will need to
adjust SELinux policy to allow the postmaster to use non-default PGPORT or
PGDATA settings.  To allow use of a non-default port, say 5433, do this
as root:
	semanage port -a -t postgresql_port_t -p tcp 5433
To allow use of a non-default data directory, say /special/pgdata, do:
	semanage fcontext -a -t postgresql_db_t "/special/pgdata(/.*)?"
If you already created the directory, follow that with:
	restorecon -R /special/pgdata
These settings are persistent across reboots.  For more information
see "man semanage".