読者です 読者をやめる 読者になる 読者になる

GeekFactory

int128.hatenablog.com

PAMによる認証の仕組みを調べてみた

Linux

/etc/pam.d/system-authが気になって夜も眠れないので調べてみました。この設定ファイルはOS全体の認証*1を司るものです。コンソールでログインするとき、SSHで接続するとき、su(switch user)するときなど、多くの場面で利用されます。

/etc/pam.d以下にあるファイルは下記の書式になっています。

タイプ コントロールフラグ モジュール [オプション]

タイプは4種類あります。

auth 認証を許可するかどうかです。ユーザが本物であるかを、パスワードなどの入力によって確認をします。また認証方法を変更することも可能です。
account パスワードの有効期間や認証時の時間などでアカウントの有効性をチェックします。authとセットで使用されます。
password 認証方法を変更するメカニズムを提供します。通常はパスワードの設定/変更する場合です。
session ユーザの認証前または認証後で実行することを指定します。 ユーザディレクトリのマウントやアンマウント、ログインやログアウト時のログ記録、ユーザが利用できるサービスの制限、といったことが含まれます。
http://www.stackasterisk.jp/tech/systemManagement/pam01_01.jsp

コントロールフラグは4種類が定義されています。自分で細かい条件を設定することも可能です。

コントロールフラグは PAM モジュールが「成功」「失敗」のステータスを返した時にどのような処理を行なうかを指定します。基本は required, requisite, sufficient, optional の四種類です。

required
(必要条件)
そのモジュールから成功のステータスが返る事を要求します。required となっているモジュールが失敗のステータスを返すと他のモジュールの処理の結果にかかわらずログインに失敗します。ただし、処理は打ち切られる事なく次のモジュールに進みます。
requisite
(必須条件)
required と似ていますが、requisite となっているモジュールが失敗するとその時点でそのモジュールタイプの処理は打ち切られます。
sufficient
(充分条件)
sufficient となっているモジュールが成功のステータスを返すと、既に required のモジュールのどれかが失敗していない限り、そのモジュールタイプの処理は成功と見なされ、以降のモジュールは処理されません。
optional
(オプション)
optional とされているモジュールは通常はそのステータスを無視されます。しかし、他のモジュールが全て「無視」のステータスを返した場合、optional のモジュールのステータスが使われます。
http://d.hatena.ne.jp/dayflower/20070821/1187684992

それでは、/etc/pam.d/system-authの中身を1行ずつ見ていきます。ここで引用している内容はGentoo Linuxのデフォルト設定です。

認証に関する設定

auth            required        pam_env.so

pam_env.soは/etc/security/pam_env.confにある環境変数をセットします。

auth            required        pam_unix.so try_first_pass likeauth nullok

pam_unix.soは/etc/passwd, /etc/shadowの内容を基に認証を行います。try_first_passは認証方式を2つ以上指定している時に使います。1つめの認証モジュールで入力したパスワードを後続のモジュールで再利用します。これを指定しないと、認証モジュールそれぞれでパスワードプロンプトが出ます。

PAMは、ユーザーからのパスワードの取得をサポートする。各行ではPAMに対し、パスワードが必要であることと、ユーザーから取得済みのパスワードを再利用するか(use_first_pass)、あるいは既に取得したパスワードがあればそれを再利用し、なければ入力を促すか(try_first_pass)を指定することができる。これは便利な機能である。あるサービスに対するPAM認証が2行存在する場合に try_first_passを用いれば、その2行から呼び出される認証サービスにおいてパスワードは2回必要となるが、PAMが処理してくれるおかげで入力は1回で済む。

http://sourceforge.jp/magazine/08/11/11/0153210/2

引数は「likeauth」と「nullok」の2つある。

1つ目は、/etc/pam.d/system-authファイルを呼び出す際のモジュール(pam_stack.so)が使っていた認証等の値を、pam_unix.soでも使えるようにするための処置だ。

2つ目は、ノーパスワードを認めるという設定だ。

http://www.geocities.jp/sugachan1973/doc/funto47.html

アカウントに関する設定

account         required        pam_unix.so

pam_unix.soは/etc/passwd, /etc/shadowの内容を基にアカウントが有効か確認します。

シャドウパスワードが有効な場合、pam_unix.soモジュールは、アカウントの期限が切れていないか、ユーザーがパスワードを変更していないか、パスワード変更に関する猶予期間が切れていないかをチェックします。

http://www.jp.redhat.com/manual/Doc73/RH-DOCS/rhl-rg-ja/s1-pam-samples.html

パスワードに関する設定

password        required        pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3

pam_cracklib.soはユーザが指定したパスワードが条件に適合しているかチェックします。passwdコマンドでパスワードを変更するときに利用されます。

The action of this module is to prompt the user for a password and check its strength against a system dictionary and a set of rules for identifying poor choices.

The first action is to prompt for a single password, check its strength and then, if it is considered strong, prompt for the password a second time (to verify that it was typed correctly on the first occasion). All being well, the password is passed on to subsequent modules to be installed as the new authentication token.

http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-pam_cracklib.html
password        required        pam_unix.so try_first_pass use_authtok nullok sha512 shadow

pam_cracklib.soのチェックが通ると、pam_unix.soで実際に/etc/shadowが書き換えられます。pam_cracklib.soで入力したパスワードをそのまま使うため、try_first_passとuse_authtokを指定します。sha512はSHA-512で保存すること、shadowは/etc/passwdの代わりに/etc/shadowを使うという意味です。

ログインセッションに関する設定

session         required        pam_limits.so

pam_limits.soは/etc/security/limits.confに書かれた制限を適用します。ulimitで指定できる内容と同じです。

session         required        pam_env.so

pam_env.soは/etc/security/pam_env.confにある環境変数をセットします。authでも同じことを書きましたが、両方必要なのか分かりません。

session         required        pam_unix.so

pam_unix.soはログイン時、ログアウト時にログを残すようにします。

session         optional        pam_permit.so

pam_permit.soは常にログインを許可します。optionalに書くことで、何らかの原因でrequiredのモジュールがignoreを返した場合にもログインできるようになります。

*1:ただしPAMを使っているものに限る