このエントリーをはてなブックマークに追加


host=localhost, psql -h localhostを指定すると接続できない場合の対処方法

この問題を発見したのは、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は動作していません。

以下の手順によりデータベースユーザを作成してデータベースを作成しました。

データベースユーザの追加

  1. スーパーユーザにsu
    $ su -
    パスワード:
     
  2. postgresユーザにsu
    # su - postgres
     
  3. 今回利用したユーザsakuraをデータベースユーザとして作成
    -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()関数による接続

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 -h localhost foo で接続してもエラー

psql fooでは正常に接続できていたのが、-h localhostを指定すると接続できないことを確認。

[sakura@centos ~]$ psql -h localhost foo
psql: FATAL:  ユーザ"sakura"のIdent認証に失敗しました

pg_hba.confを修正しlocalhost指定の接続を可能にする

以下の編集および操作は全て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

identtrustに変更しました。
上記の設定を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コマンド
    $ psql -h localhost foo
    psql (8.4.9)
    "help" でヘルプを表示します.
    
    foo=# \q
  • phpスクリプト
    [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を指定して接続できるようになりました。

調査結果のまとめ

  • pg_hba.confのローカル接続の設定がデフォルトのまま(ident)の場合は、host名を指定しなければ接続できる。
  • pg_hba.confのローカル接続の設定をtrust(ロカールからの無条件接続)にするとユーザ名の指定のみで接続できる。

備考

本資料は、CakePHPをインストールしdatabase.phpのhostにlocalhostをしてすると接続できなかったので調査した資料です。
他のPHPフレームワークや独自で作成した場合も同様のエラーが発生する可能性がありますね。
現に、psql -h localhost データベース名 や pg_connect("host=server...)で接続できないエラーが出ましたので。
同じ原因で本資料が問題の突破口になれば幸いです。
Webアプリケーション屋さんがデータベースの設定に詳しいとは限らないので。
尚、今回はpg_hba.confを参考までに上記のように設定しました。
実際にはpg_hba.confを調査し適切に設定してください。(セキュリティにかかわる部分なので…)


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-03-20 (金) 22:08:00