AlmaLinux 9.4 セットアップメモ
Section 5.3 PHPとDB接続編
About
SELinuxの関係で、PHPからDatabaseを使おうと思うとハマるので、それについて解説します。
Database を作成して、PHPで connect するという単純なものを作成してどうなるかを見ていきましょう。
環境は、Section 5.2を行った直後の状態からとなります。
検証用のDatabse作成
Section 3.1 で作成していれば、それをそのまま使います。作っていなければ作成してください。
[root@localhost ~]# su - postgres -c "createuser -S -R -d -P vagrant"
新しいロールのためのパスワード:
もう一度入力してください:
[root@localhost ~]# su - postgres -c "createdb -O vagrant -E UTF-8 vagrant"
[root@localhost ~]#
接続確認だけなので、テーブルは作成しません。
接続できるか確認してみましょう。パスワードはロール作成時に設定したパスワードを使います。
[root@localhost ~]# psql -h localhost -U vagrant -d vagrant
Password for user vagrant:
psql (15.3)
Type "help" for help.
vagrant=> \q
ここまででDBの準備が完了しました。
検証用のPHPスクリプトを作成
コードは PHPのマニュアルにあるサンプルコードを少し変えたものを使用します。
[root@localhost ~]# vi /var/www/html/db_test.php
<?php
try {
$dbp = new PDO('pgsql:host=localhost;dbname=vagrant', 'vagrant', 'vagrant');
$dbp = null;
echo 'Postgres OK';
$dbm = new PDO('mysql:host=localhost;dbname=vagrant', 'vagrant', 'vagrant');
$dbm = null;
echo '/MariaDB OK';
} catch (PDOException $e) {
print $e->getMessage();
die();
}
echo "\n";
?>
[root@localhost ~]#
これで準備ができました。
一応、動作確認はしておきましょう
[root@localhost ~]# php /var/www/html/db_test.php
Postgres OK/MariaDB OK
[root@localhost ~]
ではブラウザから確認しましょう。おそらく下記のようなメッセージが表示されると思います。
SQLSTATE[08006] [7] could not connect to server: Permission denied Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Permission denied Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?
エラーについて確認する
コマンドラインから実行して動作していることが確認できているので、SELinuxが理由なことは確定です。
ということで、ログを確認してみます。 SELinuxでの不正アクセスなどのログは、/var/log/audit/audit.logに記録されているので、検索をかけて確認します。
[root@localhost ~]# grep "avc: denied" /var/log/audit/audit.log
type=AVC msg=audit(0000000000.000:000): avc: denied { name_connect } for pid=5712 comm="php-fpm" dest=5432 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:postgresql_port_t:s0 tclass=tcp_socket permissive=0
上記のログを確認すると、scontext=user_u:system_r:httpd_tが、tcontext=system_u:object_r:postgresql_port_tへアクセスしようとして、拒否されているというログになります。
SELinuxが有効でなければポートさえあっていれば動作するのですが、そういう部分にも権限がついて回るという状態です。
なので、これを許可する設定を行っていきます。
許可設定を行う
基本的に、何かしら設定すれば使えるようにOS側で設定されているので、それを変更していきます。
SELinux BooleanやSELinux bool値などで検索すると出てくる設定です。
getseboolコマンドで変更できる項目が確認できるので実行していきます。すべて表示すると大変なのでhttpdサービスに関連するものを探します。
[root@localhost ~]# getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_manage_courier_spool --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_graceful_shutdown --> off
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_ipa --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> off
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_opencryptoki --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off
[root@localhost ~]#
この中から関係のありそうな項目を探すと、httpd_can_network_connect_dbというのが値がoffになっているので、接続できないようになっています。この設定を変えてみましょう。
何気に、Webサービスを立ち上げて権限エラーが出たら、おおむねこの設定を変えれば解決するでしょう……おそらく。
問い合わせフォームからメールを出す場合など、httpd_can_sendmailをonにする必要がありそうですし……
ということで設定を変更します。
[root@localhost ~]# setsebool -P httpd_can_network_connect_db on
-P オプションをつけないと再起動時にリセットされてしまうので、-Pをつけましょう。実験的にやる場合は-Pをつけずに確認して、その後、永続化するのが正しい手順です。
これで、ラベルが変わったのでブラウザから見てもPostgres OK/MariaDB OKが出てくると思います。
この件はここまで。