MariaDB で PAM 認証する。
mariadb でもPAM認証したが、最近のアップデートにより、うまく接続できないことが増えたのでメモ。
PAM認証とは?
mysql の pam プラグインを使います。mysql のユーザ認証を、/etc/passwd,/etc/shadow
を使って行います。
メリットは、ユーザのパスワードの管理がメチャクチャ楽ちんになります。
デメリットは、NOUNCEを用いた認証ができないので、サーバーとクライアント間で平文パスワードを「直接送信します」とても危うい。手軽なデメリットの解消なのは、SSH経由でmysql localhost
を実行しsocks経由でMysql を使うことです。
MariaDBのデータベース設定
公式マニュアルに従います。いまのMariaDBは、プリインPAMなので、とても楽です。
plugin を有効化する。
# echo "INSTALL SONAME 'auth_pam';" | mysql -p mysql -u root
有効を確認します。
# echo 'show plugins ' | mysql -p mysql -u root | grep pam Enter password: pam ACTIVE AUTHENTICATION auth_pam.so GPL
MariaDBの設定
MariaDBのサーバーの設定を行います。
/etc/mysql/mariadb.conf.d/50-server.cnf
[mariadb] plugin_load_add = auth_pam pam_use_cleartext_plugin
設定したら。再起動します。
systemctl restart mysql
pam_use_cleartext_plugin
は認証時に文字列をそのまま流す設定です。これを設定しないと、mysql-client コマンドやSOCK以外の接続でうまく認証できません。
たとえば、PyMSQLやNodeJSなどはこの設定がないとパスワードを送れずにエラーになります。(dialogで送ろうとしてエラーになる。)
PyMySQLのエラー例。
Index out of Range Packet sequence number wrong - got 5 expected 1
などが出てしまいます。
この設定は、サーバーからクライアントに平文を選択肢として許可する設定で、これを指定しないと一部のクライアントからPAM認証ができない。(そもそも、最近はパスワード認証で平文を送信するようになっていない。mariadb が平文で受け取ってそれをPAMに流すため。このあたりを考慮するとLDAPのほうがいいんだけど、めんどくさい。SSHで保護しておけば大丈夫)
PAM認証するユーザーを作成します。
PAM認証するユーザーは、Linuxのユーザー(/etc/passwdなど)に存在するユーザー名を指定します。
CREATE USER takuya@localhost IDENTIFIED VIA pam;
ユーザー作成が終われば権限を設定します。
## 作成したユーザーに権限を渡します。 grant all on takuya_db.* to 'takuya'@'localhost' ## 権限を更新します。 flush PRIVILEGES;
LDAPに直接つなぐより、PAM経由でLDAPに行ったほうが楽だと思います。ただし、PAM連携するとログインに時間がかかります。体感だけど +4-600msくらい追加で必要です
接続テストをします。
sock 経由で接続テスト
mysql -p -u takuya
TCP経由で接続テスト
mysql -p -u takuya --protocol=TCP -h localhost
mysql-client の設定を書きます。~/.my.cnf
このままだと、takuya ユーザーでログインしたときに、エラーになります。
mariadbは現在の初期設定だと、mysql ユーザを使ってしまいます。ログインユーザー名を使ってくれません。PAMは想定されてないので当然です。
takuya@:~$ mysql -p ERROR: takuya@:~$ mysql (1045, "Access denied for user 'mysql'@'localhost' (using password: YES)")
~/.my.cnf にユーザー設定をしてあげます。
[client] host = 127.0.0.1 user = takuya password = dummy # indispensability port = 3306
password = dummy
はそのまま記述する必要がありました。。password がないと通常の接続設定が走るのでPAMのcleartextになりませんでした。
これで、takuya ユーザーがssh ログイン後に mysql コマンドでユーザー名takuyaを使って、接続できるようになります。
takuya@:~$ mysql -p Enter password: ERROR 1045 (28000): Access denied for user 'takuya'@'localhost' (using password: NO) takuya@:~$ mysql ERROR 1045 (28000): Access denied for user 'takuya'@'localhost' (using password: NO) takuya@:~$ takuya@:~$ mysql -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 98 Server version: 10.5.12-MariaDB-0+deb11u1 Debian 11 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
mycli からも接続できます。
mycli -u takuya
mycli は 2021-12-02 入れたバージョンでは、index out of range のエラーになります。
これはクリアテキスト(平文)使うため、サーバーからmycliへ平文を認証で要求するようにしてあげないとエラーになります。
~/.my.cnfにpasswod=tekitou_na_dummy
を書かないとだめでした。
mysql の設定に次をいれて、クリアテキストも要求できるように指定してあげる
[mariadb] plugin_load_add = auth_pam pam_use_cleartext_plugin
設定したバージョン
takuya@:~$ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 11 (bullseye) Release: 11 Codename: bullseye
Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 137 Server version: 10.5.12-MariaDB-0+deb11u1 Debian 11
参考資料
- Authentication Plugin - PAM - MariaDB Knowledge Base
- MySQLのユーザーをPAM認証(/etc/shadow)をつかってパスワードログインする - それマグで!
- https://takuya-1st.hatenablog.jp/entry/2019/03/11/115831
- https://michael.mior.ca/blog/mysql-client-configuration/
- https://github.com/PyMySQL/PyMySQL/blob/v0.9.2/pymysql/connections.py#L898
- https://github.com/dbcli/mycli/issues/550
- https://www.mycli.net/connect