この問題を発見したのは、CakePHPをインストールしdatabase.phpのhostにlocalhostを指定すると接続できなかったことが発端で調査しました。
PHPのpg_connect()関数でhost=localhostを指定した時と、psql -h
localhostを指定したとき、Ident認証に失敗しましたが出力されPostgreSQLに接続できない場合の事象について記述します。
今回は、pg_hba.confの修正で直りましたが、各自の環境によっては違う原因でlocalhostに接続できない場合があると思いますので参考記事として利用してください。
追記
以下の設定を行ってもlocalhostを指定すると接続できない場合は、IPv6で接続しようとしているのかもしれません。
IPv6によるlocalhostへの接続および、IPv4によるlocalhost接続方法は以下のリンクの資料が参考になるかもしれません。
環境はCentOS、yumコマンドによりPostgreSQL8.4をインストールしました。
yumにてインストール後、PostgreSQLの設定ファイルは変更していません。
SELinux, iptables, ip6tablesは動作していません。
以下の手順によりデータベースユーザを作成してデータベースを作成しました。
$ su - パスワード:
# su - postgres
-bash-3.2$ createuser sakura 新しいロールをスーパーユーザとしますか? (y/n)y -bash-3.2$ exit logout
sakuraユーザにてデータベースfooを作成しpsqlによる接続確認を行いました。
[sakura@centos ~]$ createdb foo [sakura@centos ~]$ psql foo psql (8.4.9) "help" でヘルプを表示します. foo=# \q
PHPのデータベース接続関数 pg_connect() の引数にhost=localhostに設定するとエラーになりました。
以下のPHPスクリプトで接続しようとするとエラーとなりPostgreSQLに接続できない。
[sakura@centos ~]$ cat pg_connect_ng.php <?php if (!($cn = pg_connect("host=localhost dbname=foo user=sakura password=xxxxxxxx"))) { echo "connect error\n"; } else { echo "connect ok\n"; } ?> [sakura@centos ~]$ php pg_connect_ng.php PHP Warning: pg_connect(): Unable to connect to PostgreSQL server: FATAL: ユーザ"sakura"のIdent認証に失敗しました in /home/sakura/pg_connect_ng.php on line 2 Warning: pg_connect(): Unable to connect to PostgreSQL server: FATAL: ユーザ"sakura"のIdent認証に失敗しました in /home/sakura/pg_connect_ng.php on line 2 connect error
以下のhost=localhostを削除したPHPスクリプトはPostgreSQLに接続できた。
[sakura@centos ~]$ cat pg_connect_ok.php <?php if (!($cn = pg_connect("dbname=foo user=sakura password=xxxxxxxx"))) { echo "connect error\n"; } else { echo "connect ok\n"; } ?> [sakura@centos ~]$ php pg_connect_ok.php connect ok
psql fooでは正常に接続できていたのが、-h localhostを指定すると接続できないことを確認。
[sakura@centos ~]$ psql -h localhost foo psql: FATAL: ユーザ"sakura"のIdent認証に失敗しました
以下の編集および操作は全てrootユーザにて行いました。
/var/lib/pgsql/data/pg_hba.confファイルののIPv4 local connections:を以下のように修正しました。
# IPv4 local connections: host all all 127.0.0.1/32 ident
# IPv4 local connections: host all all 127.0.0.1/32 trust
ident を trustに変更しました。
上記の設定をtrustに変更すると、localhostからの接続はユーザ名指定だけで無条件に接続するようになります。
つまり、localhostからの接続はパスワードなしで接続できるようになります。
※trustを設定したので、以下のPHPスクリプトのpasswordは不要になります。
以下のようにすればパスワードが必要になります。
# IPv4 local connections: host all all 127.0.0.1/32 password
以下のコマンドでPostgreSQLを再起動します。
/etc/init.d/postgresql restart
または
service postgresql restart
sakuraユーザにsuし、以下のコマンドおよびPHPスクリプトを実行してみます。
$ psql -h localhost foo psql (8.4.9) "help" でヘルプを表示します. foo=# \q
[sakura@centos ~]$ cat pg_connect_ng.php <?php if (!($cn = pg_connect("host=localhost dbname=foo user=sakura password=xxxxxxxx"))) { echo "connect error\n"; } else { echo "connect ok\n"; } ?> [sakura@centos ~]$ php pg_connect_ng.php connect ok
localhostを指定して接続できるようになりました。
本資料は、CakePHPをインストールしdatabase.phpのhostにlocalhostをしてすると接続できなかったので調査した資料です。
他のPHPフレームワークや独自で作成した場合も同様のエラーが発生する可能性がありますね。
現に、psql -h localhost データベース名 や pg_connect("host=server...)で接続できないエラーが出ましたので。
同じ原因で本資料が問題の突破口になれば幸いです。
Webアプリケーション屋さんがデータベースの設定に詳しいとは限らないので。
尚、今回はpg_hba.confを参考までに上記のように設定しました。
実際にはpg_hba.confを調査し適切に設定してください。(セキュリティにかかわる部分なので…)