web-dev-qa-db-ja.com

PostgreSQL UNIXドメインソケットに接続できません

PHP WebアプリケーションからPostgreSQL Unixドメインソケットに接続しようとしています。関連するシステムコンポーネント:

  • CentOS 7 x64(SELinux強制)
  • postgresql93 9.3.5-2PGDG.rhel7
  • nginx 1.6.2-1.el7.ngx
  • php-common 5.4.16-23.el7_0.3
  • php-fpm 5.4.16-23.el7_0.3
  • php-pdo 5.4.16-23.el7_0.3
  • php-pgsql 5.4.16-23.el7_0.3

PostgreSQLは標準ポート5432でリッスンしており、127.0.0.1:5432でTCP/IPを介して使用しても問題はありませんが、Unixドメインソケットに接続しようとすると、次のエラーが発生します。

Cannot connect to database: SQLSTATE[08006] [7] could not connect to server:
No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

ファイル/ tmp/.s.PGSQL.5432が存在し、psqlを使用して接続できます:

$ psql -Uusername db_name
psql (9.3.5)
Type "help" for help.

db_name=>

ですから、PostgreSQL側から問題はないはずです。またはありますか?

/ var/lib/pgsql/9.3/data/pg_hba.confからの関連行:

local    all    username        trust

/ var/lib/pgsql/9.3/data/postgresql.conf内のUnixドメインソケットファイルの場所を変更しても役に立たなかった:

unix_socket_directories = '/var/run/pgsql'

/ var/log/audit/audit.logには何もありませんでしたが、念のため、SELinuxを無効にしようとしました:

# setenforce 0

これは役に立たなかったため、SELinuxではありません。

php-fpmstraceからの関連行:

[pid   882] socket(PF_LOCAL, SOCK_STREAM, 0) = 5
[pid   882] fcntl(5, F_SETFL, O_RDONLY|O_NONBLOCK) = 0
[pid   882] fcntl(5, F_SETFD, FD_CLOEXEC) = 0
[pid   882] connect(5, {sa_family=AF_LOCAL, Sun_path="/tmp/.s.PGSQL.5432"}, 110) = -1 ENOENT (No such file or directory)
[pid   882] close(5)                    = 0

ファイル名は正しく、ファイル/ tmp/.s.PGSQL.5432が存在します:

$ ls -l /tmp/.s.PGSQL.5432
srwxrwxrwx. 1 postgres postgres 0 Nov  1 09:47 /tmp/.s.PGSQL.5432

Php-fpmプロセスがchrootされていないようです:

# ls -l /proc/882/root
lrwxrwxrwx. 1 Apache apache 0 Oct 31 19:54 /proc/882/root -> /

この時点では、問題が発生する可能性のあるアイデアはありません。手助けをお願いします。

6

私は問題を解決しました。それの最初の原因は、php-fpm/ usr/lib/systemd/system/php-fpm.serviceのsystemdサービスファイルにありました。

[Service]
PrivateTmp=true

これは、php-fpmが/ tmp/.s.PGSQL.5432にあるものも何も認識できなかったことを意味します/ tmp。この問題を解決するために、次の手順でPostgreSQL Unixドメインソケットファイルの場所を変更しました。

  • 新しいディレクトリを作成します/ var/pgsql(SELinuxファイルのコンテキストを変更することに注意してください):

    # mkdir /var/pgsql
    # chown posgres:postgres /var/pgsql
    # chmod 0755 /var/pgsql
    # semanage fcontext -a -t httpd_var_run_t "/var/pgsql(/.*)?"
    # restorecon -R /var/pgsql
    
  • コメントを外してnix_socket_directoriesパラメータを/ var/lib/pgsql/9.3/data/postgresql.confに変更します(/ tmpは、psqlや他のプログラムを壊さないために必要です):

    unix_socket_directories = '/tmp,/var/pgsql'
    

そして、ここでもう1つトリッキーな部分がありました...元の投稿で、Unixドメインソケットファイルの場所を変更しようとしたところ、実際に変更しました。私が見逃したのは、変更されたエラーメッセージです。エラーは同じだと思いましたが、そうではありませんでした:

Error (256): Cannot connect to database: SQLSTATE[08006] [7] could not connect to
server: Permission denied
    Is the server running locally and accepting
    connections on Unix domain socket "/var/pgsql/.s.PGSQL.5432"?

許可が拒否されました-これは人が戦うことができるものです。

すべてが動作します

# setenforce 0

問題は:

# audit2allow -a

#============= httpd_t ==============
allow httpd_t initrc_t:unix_stream_socket connectto;

そしてそれは修正することができます:

# audit2allow -a -M httpd_postgresql_unix_socket_connect
# semodule -i httpd_postgresql_unix_socket_connect.pp

httpd_postgresql_unix_socket_connect.teの内容:

module httpd_postgresql_unix_socket_connect 1.0;

require {
        type httpd_t;
        type initrc_t;
        class unix_stream_socket connectto;
}

#============= httpd_t ==============
allow httpd_t initrc_t:unix_stream_socket connectto;

SELinuxをオンに戻します。

# setenforce 1

そして、すべてがうまくいきます!

追伸いくつかのファイルコンテキストまたはブール値を変更することによってカスタムSELinuxモジュールを回避する方法があるかどうかを知りたいと思います。 SELinuxはnginxがphp-fpm Unixドメインソケット(/ var/run/php5-fpm.sock)を使用することを許可しているため、そうかもしれませんが、何らかの理由でPostgreSQL Unixドメインソケット(/ var/pgsql/.s.PGSQL.5432)の使用をブロックします。

9