heroku pg:pull 実行時に「FATAL: Ident authentication failed for user」というエラー
Heroku 上の PostgreSQL データベースのデータをローカルの開発環境の PostgreSQL にダンプしようとしてハマった。
対象のアプリが古くて開発環境では SQLite を使っており、開発環境に PostgreSQL をインストールしたばかりという状況だったので状況としては特殊かもしれない。
症状
heroku pg:pull のコマンドを実行すると pg_restore のところで「FATAL: Ident authentication failed for user」というエラーが出て止まる。
原因
- 開発環境の PostgreSQL にパスワードなしのユーザーを作成した
- pgsql コマンドに「-h localhost」をつけた際に認証が失敗する状態になっていた
対処
「PostgreSQL/localhostを指定すると接続できない場合の対処方法 – 調べる.db」を参考に pg_hba.conf ファイルの内容を修正。このファイルは /var/lib/pgsql/data/pg_hba.conf にあるが環境によっては /var/lib/pgsql/9.5/data/pg_hba.conf などにある。
具体的には「host all all 127.0.0.1/32 ident」となっている行の「ident」を「trust」に変更する。
# IPv4 local connections: #host all all 127.0.0.1/32 ident host all all 127.0.0.1/32 trust
修正後、保存して postgresql を再起動。
なお CentOS 6 系など IPv6 が有効になっている場合は、「::1/128」の行のほうの「ident」を「trust」に変更するようにします。
調査
heroku pg:pull コマンド実行時のエラー部分のログは以下の通り。
pg_dump: dumping contents of table messages pg_restore: connecting to database for restore pg_restore: [archiver (db)] connection to database "mylocaldb" failed: FATAL: Ident authentication failed for user "vagrant" pg_restore: mylocaldb aborted because of error psql: FATAL: Ident authentication failed for user "vagrant" ! Heroku client internal error. ! Search for help at: https://help.heroku.com ! Or report a bug at: https://github.com/heroku/heroku/issues/new Error: psql failed. exit status 512, output: "" (RuntimeError) Command: heroku pg:pull HEROKU_POSTGRESQL_COBALT mylocaldb --app *** Version: heroku-toolbelt/3.27.1 (x86_64-linux) ruby/1.8.7 Error ID: c6be0ded672f41b69bb893e2e4db73cb More information in /home/vagrant/.heroku/error.log
認証まわりのエラーというのは見れば分かるのだが、パスワードなしのユーザーなのになぜ認証に失敗しているのか、意味が分からない。
よく見ると最終行に ~/.heroku/error.log に詳細な情報が書きだされているとあったのでそのログを見てみた。ちなみにこの「More information in /home/vagrant/.heroku/error.log」に気づくのに時間がかかった。
.heroku/error.log の内容は以下の通り。
Heroku client internal error. psql failed. exit status 512, output: "" /home/vagrant/.heroku/client/lib/heroku/command/pg.rb:617:in `exec_sql_on_uri' /home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:108:in `send' /home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:108:in `exec_sql_on_uri' /home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:89:in `verify_extensions_match' /home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:28:in `verify' /home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:16:in `execute' /home/vagrant/.heroku/client/lib/heroku/command/pg.rb:359:in `pull' /home/vagrant/.heroku/client/lib/heroku/command.rb:223:in `send' /home/vagrant/.heroku/client/lib/heroku/command.rb:223:in `run' /home/vagrant/.heroku/client/lib/heroku/cli.rb:40:in `start' /usr/local/heroku/bin/heroku:24
lib/heroku/command/pg.rb の 617 行目でエラーになっている。該当箇所は以下のメソッド。
def exec_sql_on_uri(sql,uri) begin ENV["PGPASSWORD"] = uri.password ENV["PGSSLMODE"] = (uri.host == 'localhost' ? 'prefer' : 'require' ) user_part = uri.user ? "-U #{uri.user}" : "" output = `#{psql_cmd} -c "#{sql}" #{user_part} -h #{uri.host} -p #{uri.port || 5432} #{uri.path[1..-1]}` if (! $?.success?) || output.nil? || output.empty? raise "psql failed. exit status #{$?.to_i}, output: #{output.inspect}" end output rescue Errno::ENOENT output_with_bang "The local psql command could not be located" output_with_bang "For help installing psql, see https://devcenter.heroku.com/articles/heroku-postgresql#local-setup" abort end end
変数 output に実行結果を格納しているコマンドが原因っぽいので、そのコマンドを出力してみると以下のようなものだった。
"command psql -c \"SELECT extname FROM pg_extension ORDER BY extname;\" -h localhost -p 5432 mylocaldb"
このコマンドをシェル上で直接実行してみると、
$ psql -c "SELECT extname FROM pg_extension ORDER BY extname;" -h localhost -p 5432 mylocaldb psql: FATAL: Ident authentication failed for user "vagrant"
確かにエラー。PostgreSQL の認証エラーについて色々調べてるときに -h localhost をつけるつけないといった話があったので試しに外して実行してみると、
$ psql -c "SELECT extname FROM pg_extension ORDER BY extname;" -p 5432 mylocaldb extname --------- plpgsql (1 row)
エラーにならない!というわけで原因が判明した。。
コメントを残す