PAM (Pluggable Authentication Modules)認証で、pam_ldap.so モジュールを使用するとき、LDAPに接続できないと、長いこと待たされる。LDAP側で管理しているユーザではなく、shadowファイルなどで認証チェックがOKとなっても、2分くらい待たされる。なんでじゃ。
PAMのsystem-authはこんな感じ。
#%PAM-1.0 auth required /lib/security/pam_env.so auth sufficient /lib/security/pam_unix.so likeauth nullok auth sufficient /lib/security/pam_ldap.so use_first_pass auth required /lib/security/pam_deny.so
account required /lib/security/pam_unix.so broken_shadow account [default=bad success=ok user_unknown=ignore service_err=ignore system_err=ignore authinfo_unavail=ignore] /lib/security/pam_ldap.so account required /lib/security/pam_permit.so
password required /lib/security/pam_cracklib.so retry=3 type= password sufficient /lib/security/pam_unix.so nullok use_authtok md5 shadow password sufficient /lib/security/pam_ldap.so use_authtok password required /lib/security/pam_deny.so
session required /lib/security/pam_limits.so session required /lib/security/pam_unix.so session optional /lib/security/pam_ldap.so
ついでに、nsswitch.confも。
passwd: files ldap shadow: files ldap group: files ldap
まあ、よくある基本的なLDAP認証の設定です。これで、LDAPに登録したアカウントでの認証もできるし、無論LDAPに登録していない元からのアカウントでの認証もできる。つまり、LDAPが落ちていても、shadowファイルとかに情報があれば、認証をパスできるわけです。
ところが、実際にLDAPを落として、SSHでログインを試みると、ログイン認証ごときに尋常じゃなく待たされる。ログ(/var/log/secure)を見てみたら、こんなことに!
sshd[29791]: Accepted password for plab from xxx port 3496 ssh2 sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 4 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 8 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 16 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 32 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 64 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: could not search LDAP server - Server is unavailable
どうやら認証処理うんぬんではなく、LDAPサーバに接続できるまで、時間を置きながら最大5回までチャレンジしているため、時間がかかりまくっているみたい。何らかの原因でLDAPサービスが落ちたとき、復旧でSSH接続しようとしたら2分かかりました、ってのはキツイ。もうちょっと空気読もうよ、nss_ldapさんっ!
実際、LDAPサービスの死活を判断するのに、トータル124秒も待って5回も再接続を試みる必要があるケースは少ないと思う。同じネットワークエリア内にドメインコントローラを置いたりするなら、これは大げさすぎるんじゃないか、と。
ということで、nss_ldapの再試行回数やタイムアウト時間を変更する方法。
どっかで、再試行回数やタイムアウト時間を設定できるのかな、と思ったけど、設定ファイルでサクっと直すことはできなかった。ldap-nss.h を直接編集するのが正解っぽい。
# vi ldap-nss.h
(100行目付近が該当箇所) #define LDAP_NSS_TRIES 5 /* number of sleeping reconnect attempts */ #define LDAP_NSS_SLEEPTIME 4 /* seconds to sleep; doubled until max */ #define LDAP_NSS_MAXSLEEPTIME 64 /* maximum seconds to sleep */ #define LDAP_NSS_MAXCONNTRIES 2 /* reconnect attempts before sleeping */
上から順に、
「再試行回数」
「1回目の再試行までの待ち時間」
「最大の待ち時間」
「スリープで待つまでに再試行を何回おこなうか」
を設定する。
「再試行回数」と「最大の待ち時間」は、先にリミットに到達した方で制限がかかるのかな。「最大待ち時間」を500とかにしても、「再試行回数」が1回だったら、1回試して終わりになった。ソースちゃんと追ってないので、この辺あやしいかも。
とりあえず、再試行回数を2回までに制限してみた。
# vi ldap-nss.h
(100行目付近が該当箇所) #define LDAP_NSS_TRIES 2 /* number of sleeping reconnect attempts */ #define LDAP_NSS_SLEEPTIME 4 /* seconds to sleep; doubled until max */ #define LDAP_NSS_MAXSLEEPTIME 64 /* maximum seconds to sleep */ #define LDAP_NSS_MAXCONNTRIES 2 /* reconnect attempts before sleeping */
ldap-nss.hを変更したら、もっかいコンパイルしないとダメなのが面倒っちい。
# ./configure --with-ldap-dir=/usr/local/ldap --with-ldap-conf-file=/usr/local/ldap/etc/openldap/ldap.conf # make # make install
こんなちっぽけなことなんだけど、半日ほど費やしてしまった。うぎゃー。納得できない。そんなわけで、「こんな話、世の中のどこに需要があるというのだろうか」と思ったけど、記念に書いておきます。
お疲れさまでした。