[xzilla@luigi ~]$ uname -a
Linux luigi 2.6.18-8.el5 #1 SMP Fri Jan 26 14:15:21 EST 2007 i686 athlon i386 GNU/Linux
[xzilla@luigi ~]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5 (Tikanga)
[xzilla@luigi ~]$ httpd -v
Server version: Apache/2.2.3
Server built: Nov 29 2006 06:33:19
[xzilla@luigi ~]$ pg_config –version
PostgreSQL 8.2.4
[xzilla@luigi ~]$ php -v
PHP 5.1.6 (cli) (built: May 4 2007 10:06:08)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies
When I showed up, PostgreSQL, Apache, and PHP were already installed on the machine, my goal was to get phpPgAdmin installed. Step one was installing PostgreSQL support into PHP, which was a simple yum command away. Once that was done, I download ppa 4.1.3 and went about unpacking and configure it. Then the moment of truth… I tried to login and got the mysterious “login failed” message. No big deal, I walked the steps of troubleshooting like I have done 1000 times before… check postgresql.conf for tcp/ip, check pg_hba.conf for access, verify I can login with psql, everything seems ok. I try a few more times, but no dice. What is bothering me most is that the PostgreSQL logs do not show any FATAL errors (or errors of any kind for that matter), which 99% of the time means my connection attempt is not reaching the PostgreSQL server. The other 1% is that I am logging in ok, but am having a browser issue…
As it turns out, I’ve been trying to do this with elinks, so I spend some time working around the no X solution (ended up port forwarding Apache back to my desktop) so I could use Galeon to login. In any case, that still didn’t work, and by now I was getting annoyed :-) I hack the pg_connect commands to spit out errors to the log files, and I see that all I’m getting is the “is postgres running and accepting tcp/ip connections error?” message, which it was, but I verify but telnetting to port 5432. Suddenly I remember, this is a Red hat box, and get suspicious of an SELinux issue. I do a check to see if I can login as the apache user using psql and I can, which is a little befuddling, but all the pieces fit together: httpd can’t reach PostgreSQL, but other things can, and there are no firewalls in the way (verified with iptables). This is about the time I whine a little to Dave. Dave is smart, and I figure he might have a clue about where to go from here. Unfortunately he claims no knowledge of SELinux, but he was smart enough to look in /var/log/messages and see the following message: (NOTE: pay attention, this is the important part!)
Jul 17 11:23:58 luigi setroubleshoot: SELinux is preventing the http daemon from connecting to a database. For complete SELinux messages. run sealert -l 8173a62-d27a-437-8045-e5fb6aec42
OK, easy enough, we run that and sure enough it’s complaining about httpd trying to access the socket file…
[xzilla@luigi ~]$ sealert -l 8173a62-d27a-437-8045-e5fb6aec42
Summary
SELinux is preventing the httpd from using potentially mislabeled
files (.s.PGSQL.5432).
Detailed Description
SELinux has denied httpd access to potentially mislabeled file(s)
(.s.PGSQL.5432). This means that SELinux will not allow httpd to
use these files. It is common for users to edit files in their home
directory or tmp directories and then move (mv) them to system directories.
The problem is that the files end up with the wrong file context which
confined applications are not allowed to access.
Allowing Access
If you want httpd to access this files, you need to relabel them
using restorecon -v .s.PGSQL.5432. You might want to relabel the entire
directory using restorecon -R -v .
It’s important to note it was not complaining that the apache user was trying to get access, but that httpd was (which is why apache/psql worked ok earlier). So, we go ahead and run the recommended command *restorecon -v .s.PGSQL.5432*, and try again, but still no dice. While I check the PostgreSQL logs and the Apache logs, Dave taps me on the shoulder and points out that we have a different error from SELinux (see, Dave is smart)
Jul 17 13:57:09 luigi setroubleshoot: SELinux is preventing the http daemon from connecting to a database. For complete SELinux messages. run sealert -l acfb116c-d533-57c-bdf1-ac3ebbbea
Of course this has a big handy message to go with it as well:
[xzilla@luigi ~]$ sealert -l acfb116c-d533-57c-bdf1-ac3ebbbea
Summary
SELinux is preventing the http daemon from connecting to a database.
Detailed Description
SELinux has denied the http daemon from connecting to a database. An http
script is trying to connect to a database port. If you did not setup httpd
to allow database connections, this could signal a intrusion attempt.
Allowing Access
If you want httpd to allow database connections you need to turn on the
httpd_can_network_connect_db boolean: “setsebool -P
httpd_can_network_connect_db=1”
The following command will allow this access:
setsebool -P httpd_can_network_connect_db=1
So, we run that handy command it recommend here, *httpd_can_network_connect_db=1*, and… hold one… is it me or is that flag a bit lolcode or something? “apache can has database?” sure!… anyway, we run that command and try it again and wallah, we’re in! So we worked around SELinux, now we have to put all the other security stuff back in place (did i leave out the part where I set the pg_hba all trust? :-P ).
I’m not entirely sure this is the best way to go about things (please do drop suggestions / advice / general wisdom in the comments) but it will work for now while we get things running and can discuss more fully a security policy. Hopefully this post will help others to look in the right places, and again, any pointers would be very welcome. Also, if you know if it’s possible to modify the php-pgsql rpm file to update the SELinux policy automagically, I’d be curious about that too.