DebianのPAM認証
DebianにおいてPAM認証はユーザー管理の一元化には便利なものですがその構造に慣れるまでが難しいです。また使わなくなると忘れがちです、そこでここに覚書を残しておきます。合わせて、独自のPAM認証をしたいときに利用できるPAM-SCRIPTについても使用例を掲載しています。
PAMとは
PAMはPluggable Authentication Moduleの略で、認証機能を提供するものです。
認証そのものを実行するというよりは、数多く存在する認証システムを統合するといった方が近いかもしれません。
そのためPAMで認証を管理しておけば、何がどのような認証をしているかという把握や、それらの変更が容易になります。
PAMの書式
PAMのリストの書式は次のようになります。
[PAMモジュールインターフェース] [コントロールフラグ] [PAMモジュール名] [引数]
また、
@include PAM設定ファイル名
とすると、他のPAM設定ファイルの内容をそのまま使うことができます。
PAMモジュールインターフェース
「PAMモジュールインターフェース」には次のものがあります。
インターフェースはこれは認証が実行されるタイミングだととらえるとわかりやすいかもしれません。
また、設定ファイルの内容はこのインターフェースがひとつのまとまりとなります。
- auth
指定されたモジュールで認証します。
- account
アカウントの期限切れなどをチェックします。
- password
パスワード変更時に用いられます。
- session
認証前後のセッションのopen、close時に用いられます。
コントロールフラグ
複数のモジュールを指定できるPAMでは、モジュール名とともにコントロールフラグも付与します。これにより失敗したら次の認証方法を試すのかそれとも失敗として終了するのかといった挙動をを構成します。
コントロールフラグにはつぎのようなものがあります。
- required
これで指定された認証項目のうち一つでも失敗すると、指定された認証は失敗します。ただし、認証が失敗に終わっても、以降の同じインターフェースにある処理を続けます。
- requistite
requiredとほぼ同じですが、失敗すると一連の処理を終了します。
- sufficient
これ以前にrequiredフラグがついた認証がすべて成功していて、ここでの認証も成功すると以降の認証はされずに成功となります。失敗時は無視されます。
- optional
インターフェースに他の認証が指定されていない場合はこの値が認証結果となり、認証が他に存在する場合はこの結果は無視されます。
- [value=action value=action ...]
モジュールの結果に対すする条件分岐ができます。 たとえば、[success=1 default=ignore] としたときは、成功した時の1は読み飛ばし行数を意味し、この行に続く1行を読み飛ばします。他の結果時(default)の時はignore(無視)して次の行から再開します。
他のvalueの値には、「try_again」や「abort」にactionの値には、成功として終了する「done」や、失敗として終了する「die」などがあります。
他にも多くの値があり、「man pam.d」から出力されるドキュメントで確認ができます。
- include
引数で指定されたファイルにしたがった処理をします。ファイル内の書式は上記の内容となります。
@includeではファイル全体の参照となりますが、ここではインターフェース毎の参照となります。
- substack
includeとほぼ同じですが、こちらを使うとファイル内で処理が完結となります。つまりファイル内での結果が認証の結果となります。
requiredがすぐに結果を返さない理由
requiredでチェックが行われたとき直列化されているどれか一つがエラーになれば認証は失敗となるのになぜ処理を継続するかという理由ですが、これはセキュリティーの一種です。不正アクセスの手法に、複数のモジュールを利用する認証のレスポンスまでにかかる時間から認証状況を判断するというものがあります。そのため認証ではエラーの際はどこでエラーになっても同様のレスポンスをすることが理想とされています。その為認証失敗の際でも他の処理を実行しレスポンスタイムの均一化をさせます。
PAMの種類
Debianにおいては、/usr/lib/[アーキテクチャ]/securityディレクトリの中にPAMのライブラリがあります。これらのファイルはpam_から始まり.soで終わります。
インストールされていないものを探す際は、apt search libpamとすると、libpamから始まるPAMのライブラリが検索できます。
その中にはlibpam-mysqlや、libpam-ldapといったライブラリがあると思います。
また、モジュール別にパラメータが違いますが、その内容を確認したいケースがあると思います。多くは「man pam_unix」等、manコマンドで参照することができます。
使用例
ここではpam_unixとpam_listfile使った認証を設定したいと思います。どちらも初期状態でDebianに存在するライブラリだと思います。pam_unixはOSのユーザー認証、pam_listfileはファイルによる認証です。
dovecotというPOPサーバーがインストールしてあり、そのメールアカウントを持っているユーザのみを認証させるケースを設定します。
# nano /etc/pam.d/dovecot
auth requistite pam_unix.so auth require pam_listfile.so item=user sense=allow file=/etc/.../dovecotusers onerr=succeed ...
pam_unix.soはOSのユーザー認証です。今回はユーザーの管理はOSで一元管理したいと思っているので、まずOSでの認証を必須とします。
次にユーザーリストによる判断をします。OSにはメールボックスを保持していないユーザー、例えばFTP専用のアカウントなども登録されていますので、それを除外するためにユーザーのリストによる制限をします。ユーザーリストによる制限はpam_listfileが使えます。
pam_listfileの引数ですが、まずitemによって後で示されるリストと何を照合するか指定します。ここではユーザー名なのでuserとします。senseではリストが許可リスト(allow)なのか拒否リスト(deny)なのかを指定します。fileにはリストへのパスを指定します。onerrではファイルがオープンできないとき失敗(fail)にするか成功(succeed)にするか設定します。セキュリティと使い勝手のどちらを優先するかという運用に値は左右されると思いますがここではsucceedを指定しました。
あとはfileに指定しするファイルには次のようにユーザー名を一行ずつ記載しておきます。
user01 user02 ...
PAMでオリジナルの認証をしたい場合
pam-scriptというPAMライブラリがあります。このライブラリはPAMからスクリプトを呼び出すことができます。呼び出した独自のスクリプトから0が返ると成功とし、1が返ると失敗となります。
またこの機能を応用して、認証とは直接関係のないスクリプトを動かすこともできます。
この機能を利用する場合はPAMライブラリを追加します。
# apt install libpam-script ...
インストールしたら、/usr/share/libpam-script/pam-script.d/ディレクトリに、名前がわかるようにサブディレクトリを作成し、その中にpam_script_authという実行権限のあるファイルを作成し、スクリプトを記述します。
このファイル名はあらかじめ決められていてauthの時に実行するスクリプトならpam_script_auth、account時ならpam_script_acctという名前になります。詳しくはDebian:PAM-SCRIPT(7)をご確認ください。
作成したスクリプトを呼び出すためのPAMファイルの記述例は次のようになります。ファイル名はPAMインターフェースによって決まるのでディレクトリ名だけで指定します。
ファイルが存在しなかったり、オープンできなかった場合の結果をonerrに設定します。
auth required pam_script.so onerr=success dir=/usr/share/libpam-script/pam-script.d/dirname ...
公式のページにも記述はどこにも見つからなかったので他の設定の影響かもしれませんが、筆者の環境では、ここで設定するpam_script_authスクリプトファイルの所有権はroot、権限は711か755にしないと稼働しませんでした。777では不可でした。ver:1.1.9-4で確認しました。
pam_scriptをインストールすると/pam.d/内のcommon-の接頭がついたファイルにpam_scriptでの認証を加えてしまうようです。不要ならコメントアウトしましょう。そうしないとセッションのオープンやクローズ、rootをとったりする際にもpam_scriptが動いてしまいます。