UNIXやLinux: 2019年5月アーカイブ

今回、新たにセットアップしたサーバで 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 ディレクトリの下にある。

# ls -lad /tmp/systemd*
drwx------ 3 root root 4096 Apr 20  2016 /tmp/systemd-private-4ee168e88455407fa3b27bd35ffb371d-ntpd.service-1GgKhB
drwx------ 3 root root 4096 May 22 16:24 /tmp/systemd-private-bf1b49c0e6014448894be7a3091317ee-ntpd.service-5jH2a8
drwx------ 2 root root 4096 Feb  8  2016 /tmp/systemd-private-W69tS0
# ls -la /tmp/systemd-private-4ee168e88455407fa3b27bd35ffb371d-ntpd.service-1GgKhB
total 12
drwx------  3 root root 4096 Apr 20  2016 .
drwxrwxrwt 13 root root 4096 May 31 14:44 ..
drwxrwxrwt  2 root root 4096 Apr 20  2016 tmp
# ls -la /tmp/systemd-private-4ee168e88455407fa3b27bd35ffb371d-ntpd.service-1GgKhB/tmp
total 8
drwxrwxrwt 2 root root 4096 Apr 20  2016 .
drwx------ 3 root root 4096 Apr 20  2016 ..

こういう具合に、systemd が /tmp の下にそれぞれのプロセスごとに専用の /tmp を用意している。

じゃ、どうするかって話なんだけど、ソケットファイルを /tmp 以外のディレクトリに置けばいいんだけど、もう多くの CGI などで明示的に /tmp/mysql.sock を指定しているので全部直すのも大変。

とりあえず、sysytemd 経由での起動をやめる。
手動で apachectl コマンドを叩いて実行。

# systemctl stop httpd
# /usr/local/apache2/bin/apachectl start
# ps auxww|grep http
root     21911  0.0  0.2 114864  4516 ?        Ss   13:45   0:00 /usr/local/apache-2.4.39/bin/httpd -k start
apache   21912  0.0  0.1 114656  2756 ?        S    13:45   0:00 /usr/local/apache-2.4.39/bin/httpd -k start
apache   21913  0.0  0.1 401692  3328 ?        Sl   13:45   0:00 /usr/local/apache-2.4.39/bin/httpd -k start
apache   21914  0.0  0.1 401692  3324 ?        Sl   13:45   0:00 /usr/local/apache-2.4.39/bin/httpd -k start
apache   21916  0.0  0.1 401692  3324 ?        Sl   13:45   0:00 /usr/local/apache-2.4.39/bin/httpd -k start
root     22011  0.0  0.0 112708   948 pts/1    S+   13:45   0:00 grep --color=auto http

これで、CGI からも MySQL へのアクセスが可能となった。

systemd の PrivateTmp 機能を無効にする方法を調べるまでは、とりあえずこの運用とする。
そうか。CentOS7 では daemon の自動起動設定や起動、停止コマンドは chkconfig や service じゃないのか・・・(^^;

現在借りている CentOS6 のレンタルサーバ(root 権限有り)のサービスが終了するということなので、他の会社の CentOS7 のサーバ借りて設定してるんだけど、なんか 6→7 は随分変わってるのね。

sshd の自動起動の設定がどうなっているのか調べようと思って、

# chkconfig --list sshd

したら、

Note: This output shows SysV services only and does not include native
      systemd services. SysV configuration data might be overridden by native
      systemd configuration.

      If you want to list systemd services use 'systemctl list-unit-files'.
      To see services enabled on particular target use
      'systemctl list-dependencies [target]'.

error reading information on service sshd: No such file or directory

とか怒られるし、sshd の再起動しようと思って、

# service sshd restart

したら、

Redirecting to /bin/systemctl restart sshd.service

って。systemctl にリダイレクトされとる(^^;

どうも、自動起動設定や起動、停止等のコマンドは systemctl に移行したんだな。

chkconfig の代わりに

# systemctl list-unit-files|grep sshd
sshd-keygen.service                           static
sshd.service                                  enabled
sshd@.service                                 static
sshd.socket                                   disabled

とかすれば自動起動が ON になっているかわかる(enabled が ON ね)し、systemctl restart sshd とすれば再起動ができる。(sshd の部分は sshd.service でも sshd だけでも良いみたいだ)

systemctl restart sshd
systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2019-05-24 10:50:35 JST; 9s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 27691 (sshd)
   CGroup: /system.slice/sshd.service
           └─27691 /usr/sbin/sshd -D

こんな感じ。

ところで、/etc/rc.d/init.d の下に置いていた起動、停止等の操作用のシェルスクリプトってどこに行ったんやろ???
/usr/lib/systemd/system/ の下にあるファイルは違うしなあ???

このアーカイブについて

このページには、2019年5月以降に書かれたブログ記事のうちUNIXやLinuxカテゴリに属しているものが含まれています。

前のアーカイブはUNIXやLinux: 2018年11月です。

次のアーカイブはUNIXやLinux: 2020年5月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。


月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら