それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

mariadb でPAM認証を有効にしてログインする。PAMデフォルト設定でのエラー対応

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

参考資料