systemd の PrivateTmp 機能で /tmp/mysql.sock が見えないというお話し[UNIXやLinux]
(2019-05-31 15:33:20) by shinoda


< ページ移動: 1 2 >

今回、新たにセットアップしたサーバで CGI から MySQL への接続がうまくいかない。

環境は、

CentOS 7.4(1708)
Apache 2.4.39
MySQL 8.0.16
Perl 5.16.3
DBI 1.627
DBD::mysql 4.023

というソフトウェア構成。

Apache は systemd(init に変わる起動処理やシステム管理を行う仕組み)を使って起動している。
(systemctl start httpd.service というコマンドで起動しているというわけね)

で、この環境で、CGI から DBI/DBD 経由で MySQL にアクセスすると、

Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

というエラーが発生してしまう。

しかし、/tmp/mysql.sock は存在している。権限関係も問題ない。

# ls -la /tmp/mysql*
srwxrwxrwx 1 mysql mysql 0 May 31 09:55 /tmp/mysql.sock
-rw------- 1 mysql mysql 5 May 31 09:55 /tmp/mysql.sock.lock

いやぁ、ハマったわぁ〜(^^;

結局、オチから言うと、これって systemd の PrivateTmp 機能による問題で、例えばソケットの置き場所を /var/lib/mysql/mysql.sock とかにしていた人には発生しない。

どういうことかというと、今回、ソースビルドした Apache についても systemd で管理(起動等)をしているのは上に書いたとおり。
で、systemd 経由で起動したデーモン(今回は Apache)は、それぞれ独自の /tmp ディレクトリが用意される。

つまり、Apache 上で実行される CGI プログラムが見ている /tmp と、本来の /tmp ディレクトリは全然別物なので、いくら MySQL が(本来の)/tmp ディレクトリ上にソケットファイル(mysql.sock)を用意しても、CGI プログラムからは見えないのである。

結果、

DBI connect('dbname=hoge_db;host=localhost;port=3306;mysql_socket=/tmp/mysql.sock','hoge_admin',...) failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) at ./db_connect_test.pl line 42.

というエラーとなってしまう。
反対に、ソケットファイルの置き場を /tmp ではなく /var/lib/mysql/mysql.sock などにしていた場合は CGI からも見ることができる。これは、/tmp(/var/tmp も?)だけの問題である。

tmp は temporary の略で、/tmp ディレクトリというのは文字通り「一時ファイル」の置き場所。そのため、誰でも読み書きできるようになっており、それを専用に用意することで安全性や利便性を上げようって思想なんだろうけど、裏目に出たなあ>俺のところでは(^^;

ちなみに、じゃあ、プロセス毎の /tmp ってどこにあるの?というと、/tmp ディレクトリの下にある。

< ページ移動: 1 2 >


コメント投稿
次の記事へ >
< 前の記事へ
TOPへ戻る

Powered by
MT4i 3.0.8