PHP WebアプリケーションからPostgreSQL Unixドメインソケットに接続しようとしています。関連するシステムコンポーネント:
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-fpmのstraceからの関連行:
[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 -> /
この時点では、問題が発生する可能性のあるアイデアはありません。手助けをお願いします。
私は問題を解決しました。それの最初の原因は、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)の使用をブロックします。