QA@IT

OpenLDAPでshadowLastChangeが更新されません

7876 PV

■環境
下記が導入されたサーバーが2台
RHEL 7.2
OpenLDAP 2.4.44 (ユーザー管理)
FreeRADIUS 3.0.13 (RADIUS認証処理)

上記環境のサーバーをVPNの認証サーバーとして利用しています。
ユーザー情報はOpenLDAPに格納し、2台の各サーバー両方にプロバイダとコンシューマの設定をして相互にレプリケーションするように構成しています。
ログインパスワードについては、OpenLDAPのshadowMAXやshadowLastChangeを元にパスワードの有効期限を計算し、
ログイン時にパスワードが有効期限切れの場合。FreeRADIUSのlocal_cpwでユーザー側にパスワード更新画面を出力して、パスワードを更新しています。パスワード更新処理はシェルで実現しています。

■困っていること
パスワードの更新処理については、以下の処理をシェルで実行していますが、
方系のサーバーに限ってはパスワードが更新されますが、shadowLastChangeが更新されないという事象が起きています。
①ログインユーザーのパスワード更新(ldappasswd)
②パスワード更新日(shadowLastChange)の更新(ldapmodify)

②のshadowLastChangeの更新コマンドを2回実行するようにしたところ、shadowLastChangeが更新されるようになりましたが、
なぜこのような結果になるのかがわかりません。

なぜ、shadowLastChangeが方系だけ更新されないか、理由を教えていただきたいです。

  • パスワードとshadowLastChangeの更新はプロバイダ側に対して行っているのでしょうか?あとプロバイダとコンシューマ間の「相互にレプリケーションする」構成は正しく動いているのでしょうか? -
  • 相互にレプリケーションする構成は正しく動いています。お互いの更新内容が対向のサーバーに反映されることはテスト済みです。 -
  • ただ、テストの際は1台の認証サーバーに更新をかけていました。本番稼働してからは、とある事情で2経路からのVPNアクセスが異なる認証サーバーに対して更新をかけることになり、方系のサーバーでのshadowLastChangeが更新できない事象が起きていました。 -
  • ②のldapmodifyを手で叩いて現象が再現するなら、-dでデバッグレベルを指定して、うまくいく方とだめな方の両方のデバッグ情報を比較すると原因がわかる可能性があると思います。あと2台のサーバーでOpenLDAPの設定は完全に対照的になっているのでしょうか?違いがあれば教えて下さい。 -
  • -dでデバッグレベルを指定してますが、出力結果が変わらないようです。設定は対象になっています。 -
  • あと、コマンドだけで実行した場合は再現しません。
    FreeRADIUSのlocal_cpwとの連携も関係してたりしますでしょうか。
    -
  • 上記の出力結果が変わらないというところですが、-dでデバッグレベルを指定しましたが、指定していないときと変わらないという意味です。 -
  • 補足ですが、LDAPに登録しているユーザー数約2000程です。テスト時は5ユーザー程登録した状態で実施していました。そのため、検索はテスト時が一瞬だったことに対して、今は3〜4かかっている状況です。今回の不具合の原因として推測していることは、ldappasswdとldapmodifyを連続して実行しているため、ldappasswdの処理が完了する前にldapmodifyを実行しているためだと考えて -
  • います。テスト時にうまくいって、今上手くいかない理由としては、更新時のエントリー検索に時間がかかり、ldappasswdの処理が完了する前にldapmodifyを実行しているため、ldapへの更新ができてないものかと思ってます。 -
  • 考え方としていかがでしょうか? -
  • 五月雨のようにコメントしてすみません。ldappasswdとldapmodifyの間にsleepをいれてみましたが、やはり解決しませんでした。ldapmodify -dでのデバッグが不可でしたので、ログレベルを変えられないかやってみようと思います。 -

回答

あと、コマンドだけで実行した場合は再現しません。
FreeRADIUSのlocal_cpwとの連携も関係してたりしますでしょうか。

とするとシェルスクリプトの書き方が関係するかもしれません。

ldapmodifyの入力は下のようにヒアドキュメントを使って標準入力から食わせているのでしょうか?

ldapmodify -x -D "uid=ldapuser,ou=People,dc=nodomain" -w password123 << EOS
dn: uid=ldapuser,ou=People,dc=nodomain
changetype: modify
replace: shadowLastChange
shadowLastChange: 20000
EOS

それとも下のようにldifファイルを作ってそれを食わせているのでしょうか?

echo "dn: uid=ldapuser,ou=People,dc=nodomain" > modify.ldif
echo "changetype: modify"                     >> modify.ldif
echo "replace: shadowLastChange"              >> modify.ldif
echo "shadowLastChange: 20000"                >> modify.ldif
ldapmodify -x -D "uid=ldapuser,ou=People,dc=nodomain" -w password123 -f modify.ldif

テスト時にうまくいって、今上手くいかない理由としては、更新時のエントリー検索に時間がかかり、
ldappasswdの処理が完了する前にldapmodifyを実行しているため、ldapへの更新ができてないものかと思ってます。

更新に時間がかかると、NASからRADIUSサーバーに対するリトライが発生しうるので、シェルスクリプトが二重起動されることもあるのではないかと思います。

例えば一つの可能性として、もしldifファイルを作っていて、かつファイル名がユニークでない場合は、タイミングによってはldifファイルが壊れる可能性もあるのではないかと思います。

実際の原因はもう少し情報がないとわかりませんが、とりあえず思いついたのはこんなところですかね。

追記
いい忘れてましたが、あともう一つ気になるのはやはりシェルスクリプトの書き方で、下記のどちらなんだろうかということです。

  • サーバーAのスクリプトはLDAPの更新をAのLDAPサーバーに対してかけ、サーバーBのスクリプトはLDAPの更新をBのLDAPサーバーに対してかけるようになっている。
  • サーバーAのスクリプトもサーバーBのスクリプトも通常はLDAPの更新をAのLDAPサーバーに対してだけかけるようにし、サーバーAが落ちた時はサーバーBのスクリプトが更新先をAからBに切り替えるようになっている。

一般的には後者だろうと思います。ただ前者がNGかというとはっきりわかりませんが。

NASにプライマリーRADIUSサーバーとセカンダリーRADIUSサーバーを設定しているのではないかと思いますが、更新に時間がかかると、両方のRADIUSサーバーにリクエストが飛んでいくと思います。

その場合2台のサーバー上でシェルスクリプトが起動されると思いますが、そのこととOpenLDAPの「相互にレプリケーションする」構成の関係はとても気になります。

プロバイダ(マスタ)が2台いるわけですが、スクリプトの書き方が前者のケースだったとき、同時に2台のプロバイダ(マスタ)に更新をかけたときに好ましくない副作用がおきないかといったことです。

追記(2018/09/24)

今回の不具合の原因として推測していることは、ldappasswdとldapmodifyを連続して実行しているため、ldappasswdの処理が 完了する前にldapmodifyを実行しているためだと考えています。
テスト時にうまくいって、今上手くいかない理由としては、更新時のエントリー検索に時間がかかり、ldappasswdの処理が完了する前にldapmodifyを実行しているため、ldapへの更新ができてないものかと思ってます。
考え方としていかがでしょうか?

考え方はわかります。ただ「ldappasswdの処理が完了する前に」の箇所は、すっきりしませんよね?もしそうだとすると、ldappasswdの実行が終わって、いったん呼び出し側のプロセスに制御が返ってきて、次にldapmodifyの実行を開始したとき、その時点ではLDAPのパスワード更新はまだできておらず、後の時点ではじめてLDAPのパスワード更新が(非同期に)完了することになると思いますが、自分にはそういった状況は考えにくいです(「ない」ともいいきれませんが)。

他の可能性として、例えばldappasswdがエラーになって、その結果ldapmodifyが失敗する場合もあると思います。その場合は2回目のldapmodifyが成功するのは、LDAPのレプリケーションにより、対向側のサーバーから新しいパスワードがコピーされたと考えられるのではないかと思います。もちろんこれもあくまで推測の域をでません。

繰り返しになりますが、実際の原因はもう少し情報がないとわからないです。

編集 履歴 (5)
  • シェルは「サーバーAのスクリプトはLDAPの更新をAのLDAPサーバーに対してかけ、サーバーBのスクリプトはLDAPの更新をBのLDAPサーバーに対してかけるようになっている。」です。
    ldapの設定を見直していた際に、片方のサーバーのolcServerIDが「MSA=」となっており、もう片方は「2」となっていますが、この辺が関係していたりすることは考えられますかね?
    -
  • 上記のMSA=については「1」がbase64にエンコードされて設定されているようでした。
    ログレベルをanyに変更した場合、ldapmodifyを2回実行するパターンと1回実行するパターンの両方が失敗してしまいました。
    -
  • ldapmodifyが失敗したときのログを見ればエラーの原因はわかるのではないかと思いますが。
    -

誤って回答に記入してしまいました

編集 履歴 (1)
ウォッチ

この質問への回答やコメントをメールでお知らせします。