Unable to connect to Postgres via PHP but can conn

2019-01-25 23:07发布

问题:

I've had a quick search around (about 30 minutes) and tried a few bits, but nothing seems to work. Also please note I'm no Linux expert (I can do most basic stuff, simple installs, configurations etc) so some of the config I have may be obviously wrong, but I just don't see it! (feel free to correct any of the configs below)

The Setup

I have a running instance of PostgreSQL 9.3 on a Red Hat Enterprise Linux Server release 7.1 (Maipo) box. It's also running SELinux and IPTables.

IPTables config (added in 80, 443 and 5432.. and also 22, but that was done before...)

# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 5432 -j ACCEPT
-A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

PostgreSQL pg_hba.cong (deleted all comments)

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     ident
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5
host    all             all             0.0.0.0/0               md5

postgresql.conf (only changed the listen address)

listen_addresses = '*'

Setup new users

$ sudo -u postgres /usr/pgsql-9.3/bin/createuser -s "pgadmin"
$ sudo -u postgres /usr/pgsql-9.3/bin/createuser "webuser"
$ sudo -u postgres psql
postgres=# ALTER ROLE "pgadmin" WITH PASSWORD 'weakpassword';
ALTER ROLE
postgres=# ALTER ROLE "webuser" WITH PASSWORD 'anotherweakpassword';
ALTER ROLE
postgres=# \q

Test connection

psql -U [pgadmin|webuser] -h [localhost|127.0.0.1|hostname] -W postgres
Password for user [pgadmin|webuser]: [weakpassword|anotherweakpassword]
psql (9.3.7)
Type "help" for help.

postgres=# \q

As you can see I tested 127.0.0.1, localhost and the hostname on the command line to make sure I could connect use all three identifiers with both different accounts.

I've also connected using PgAdmin from my windows box, and it connects using the hostname and ip address using both users.

The problem...

The problem comes when I try to connect from PHP via Apache (it doesn't happen if I run the same script on the command line)

PHP Test Script

<?php

error_reporting( E_ALL );
ini_set('display_errors', '1');

$conn1 = pg_connect("host='localhost' port='5432' user='pgadmin' password='weakpassword' dbname='postgres'");
$conn2 = pg_connect("host='127.0.0.1' port='5432' user='pgadmin' password='weakpassword' dbname='postgres'");
$conn3 = pg_connect("host='localhost' port='5432' user='webuser' password='anotherweakpassword' dbname='postgres'");
$conn4 = pg_connect("host='127.0.0.1' port='5432' user='webuser' password='anotherweakpassword' dbname='postgres'");

$status1 = pg_connection_status( $conn1 );
$status2 = pg_connection_status( $conn2 );
$status3 = pg_connection_status( $conn3 );
$status4 = pg_connection_status( $conn4 );

# Check connection
if (
$status1 === false || $status1 === PGSQL_CONNECTION_BAD ||
$status2 === false || $status2 === PGSQL_CONNECTION_BAD ||
$status3 === false || $status3 === PGSQL_CONNECTION_BAD ||
$status4 === false || $status4 === PGSQL_CONNECTION_BAD
)
{
    throw new Exception("I'm broken");
}

# Do a query
$res1 = pg_query( $conn1, "SELECT * FROM pg_type LIMIT 1" );
$res2 = pg_query( $conn2, "SELECT * FROM pg_type LIMIT 1" );
$res3 = pg_query( $conn3, "SELECT * FROM pg_type LIMIT 1" );
$res4 = pg_query( $conn4, "SELECT * FROM pg_type LIMIT 1" );

# Test one result.
$row1 = pg_fetch_row($res1);
$row2 = pg_fetch_row($res2);
$row3 = pg_fetch_row($res3);
$row4 = pg_fetch_row($res4);

echo $row1[0] . "\n";
echo $row2[0] . "\n";
echo $row3[0] . "\n";
echo $row4[0] . "\n";

On the command line I get the following output (as expected)

bool
bool
bool
bool

But in the browser I get the following

Warning: pg_connect(): Unable to connect to PostgreSQL server: could not connect to server: Permission denied Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Permission denied Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432? in /var/www/html/test.php on line 6

Warning: pg_connect(): Unable to connect to PostgreSQL server: could not connect to server: Permission denied Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432? in /var/www/html/test.php on line 7

Warning: pg_connect(): Unable to connect to PostgreSQL server: could not connect to server: Permission denied Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Permission denied Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432? in /var/www/html/test.php on line 8

Warning: pg_connect(): Unable to connect to PostgreSQL server: could not connect to server: Permission denied Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432? in /var/www/html/test.php on line 9

Fatal error: Uncaught exception 'Exception' with message 'I'm broken' in /var/www/html/test.php:25 Stack trace: #0 {main} thrown in /var/www/html/test.php on line 25

I've got a feeling it's something to do with IPTables not allowing the connect when coming through Apache for some reason, but I'm stumped (I bet it's stupidly simple)

I think that covers everything...

Help me Stack Overflow, you're my only hope!

回答1:

OK... Answered... Was a problem with SELinux. Needed to run the following....

setsebool -P httpd_can_network_connect_db on

Also if you need to check if SELinux is causing issues it can be turned off with the following

setenforce 0

Then once finished

setenforce 1

Anyways, done... onwards!