親愛なるシステムいじり仲間の皆さん、
管理者の友人が私に次の質問をしました:
彼は、多くのネットワーク要素とサーバーで、TACACS+ サーバーに対するリモート認証を使用しています。このような独自のアプライアンスでは、リモートメソッドが「認証サーバーが利用できません」(到達不能、タイムアウト) を返す場合にのみ、認証はローカル認証 DB に問い合わせます。リモート認証サーバーがは利用できず、否定応答が返された場合、問題のボックスはそれを額面通りに受け取り、ローカル ユーザー データベースに対して認証を試行しません。
さて、Linux ベースのボックスで、同じ動作を実現したいと考えています。しかし、どうやらできないようです。Linux OS は最初にリモート認証を試行しますが、明らかに否定的な応答 (サーバーが「認証失敗、有効な資格情報ではありません」と応答) があると、先に進み、ローカル データベースも試行します。
リモート TACACS+ 認証は、pam_tacplus という優れた PAM モジュールによって調整されていることがわかりました。PAM 全般について読んでみると、pam_tacplus に問題があるわけではないことがわかってきました。むしろ、観察された動作は、PAM 全体の動作方法にすぎません。そうであれば、直接的な解決策としては、PAM コードベースに構成可能なグローバル オプションを追加し、場合によっては特定の PAM 構成ファイルのキーワード/構文を追加して、動作を望ましい方向に変更する必要があるでしょう。
このトピックに関するさらなるメモは歓迎します :-)
答え1
...さらに読んだ内容に基づいて、回答を提案させてください。もちろん、追加や修正があれば大歓迎です。
まず最初に、これはかなり昔のものだと気づいたPAM 入門おそらく、長年にわたってその鋭い機知を失っていないでしょう。
中身を覗いてみると、認証モジュールの戻り値は公式のlinux-pamドキュメントに記載されている。
リストには、 PAM_AUTHINFO_UNAVAIL という有望な retval が表示されます。
実際に定義されているlibpam/include/security/_pam_types.h。
#define PAM_SUCCESS 0
#define PAM_AUTHINFO_UNAVAIL 9
#define _PAM_RETURN_VALUES 32
PAM_AUTHINFO_UNAVAILの定義が矛盾しているようです。libpam/include/security/_pam_compat.h
# define PAM_AUTHINFO_UNAVAIL 12
-- おそらく無視しても安全です。
ソースファイルlibpam/pam_dispatch.c には、_pam_dispatch_aux() と呼ばれる重要な関数が含まれています。は、登録された認証モジュールのスタックを実際に走査し、その戻り値に基づいて動作します。そして、それは「retval」に直接基づいて多くのことを行わず、おそらく を含んでいることが判明しましたPAM_AUTHINFO_UNAVAIL
。 の特定の「内部の特別な使用」値に直接応答しますretval
が、 に対して特別な処理はありませんPAM_AUTHINFO_UNAVAIL
。は、それ自体retval
の戻り値ではありません_pam_dispatch_aux()
。むしろ、 は、retval
登録された認証モジュールのスタックを走査する for(;;) ループ内で宣言されたローカル変数にすぎず、ブロックローカルはretval
特定のモジュールの戻り値を収集します。スタックウォーク ループは、実際には他の変数に基づいて重要な決定を行います。そのうちの 1 つは と呼ばれる派生変数でありaction
、もう 1 つはモジュールによって参照によって「返される」と呼ばれる構造体メンバーですimpression
。したがって、結局のところ、モジュール自体のコードによって影響を受ける可能性があります。
実際には、これはaction
「アクションの参照テーブル」から取得されます。
インデックスああretval
!
action = h->actions[cached_retval];
アクションのテーブルはモジュールによって定義されていますか?しかし、_PAM_ACTION_*マクロが#definedである場合、libpam/pam_private.h?
アクション[]テーブルは一般的な方法で初期化される_pam_parse_conf_file()
で呼び出される関数によってlibpam/pam_handlers.c
、直接文字列比較required
、、、requisite
などoptional
のキーワードに(一致)します
sufficient
。
そして、テーブル全体には現在32の位置(上記のマクロ定義を参照)があり、卸売初期化特定のモジュールの設定エントリを解析する前に、_PAM_ACTION_UNDEF に変更します。個々の「強度キーワード」は、個々のretval
を特定の望ましいアクションに再マップします。
したがって、例えば次のようなものからインスピレーションを得るのはかなり明白なようです:
} else if (!strcasecmp("required", tok)) {
D(("*PAM_F_REQUIRED*"));
actions[PAM_SUCCESS] = _PAM_ACTION_OK;
actions[PAM_NEW_AUTHTOK_REQD] = _PAM_ACTION_OK;
actions[PAM_IGNORE] = _PAM_ACTION_IGNORE;
_pam_set_default_control(actions, _PAM_ACTION_BAD);
} else if (!strcasecmp("sufficient", tok)) {
D(("*PAM_F_SUFFICIENT*"));
actions[PAM_SUCCESS] = _PAM_ACTION_DONE;
actions[PAM_NEW_AUTHTOK_REQD] = _PAM_ACTION_DONE;
_pam_set_default_control(actions, _PAM_ACTION_IGNORE);
}
そして、次のようなものを追加します
} else if (!strcasecmp("reqd_if_avail", tok)) {
D(("*PAM_F_REQD_IF_AVAIL*"));
actions[PAM_SUCCESS] = _PAM_ACTION_OK;
actions[PAM_AUTHINFO_UNAVAIL] = _PAM_ACTION_IGNORE; // !!!!!!!!!!
actions[PAM_NEW_AUTHTOK_REQD] = _PAM_ACTION_OK; // ?
actions[PAM_IGNORE] = _PAM_ACTION_IGNORE;
_pam_set_default_control(actions, _PAM_ACTION_BAD); // !!!
}
そしてどうやらpam_tacplusその道を歩むのを助けてくれる。
ソース コードをハッキングすることなく、既存の PAM 構成ファイル構文で同じ効果を実現できれば、確かに便利です。