3

プロジェクト用の PAM モジュールを作成しています。PAM モジュールは、(毎回すべてを書き直すのではなく) 一部のコマンド ライン ユーティリティによって再利用されるライブラリを使用します。このライブラリでは、リモート ホストのサブネット メンバーシップに応じて、ログやログを区別するポリシーを解釈させたいと考えています。この値はおそらく認証アプリケーションからのものであることがわかりますが、わかりません。共有オブジェクトは libpam から pamh 構造にアクセスできないため、pam_get_item を実行するだけでは (PAM モジュール自体からアクセスできるように) 実行できないため、他の手段に頼る必要がありました。

私が思いついた最善の解決策は、共有オブジェクトが接続された TTY を探すようにすることです。そこにある場合は、utmp に移動し、その TTY に関連付けられたログイン プロセスを見つけ、そこから IP アドレスを抽出します。TTY がない場合は、ネットワーク ユーザーの最初のログインであると想定します。次に、ライブラリはソケットを繰り返し処理し (これは、基本的には、ターゲットのファイル名に「socket」という単語を含むシンボリック リンクとして定義しましたls -l /proc/<pid>/fd)、ソケットの inode 番号を使用して相互参照します。/proc/net/tcpその inode 番号に関連付けられたリモート IP アドレスを抽出します。そこに inode が見つからない場合は、Unix ドメインまたは tcp6 であると想定します (IPv6 のサポートは近日中に行われる予定であり、近い将来にはそれほど重要ではありません)。それでも見つからない場合は、何らかのデーモンがそれに対してリンクしているアプリケーションを呼び出していると想定し、そのように解釈します (価値がある場合は最終的に何かを実行する可能性がありますが、最初の 2 つが実行されない場合は、今のところ大きな NOOP にすぎません)。何も返さない。

動作しているように見えますが、PAM がどのように機能するのかについて、いくつかの高レベルの質問があります。

  1. PAM 操作を管理する公式の標準はありますか? たとえば、どこかの POSIX 標準でカバーされていますか? 複数の PAM 実装があることは知っていますが (これまでに 4 つまたは 5 つ見つけました)、既存の共通点が当然なのか事実上のものなのか、またはたまたまシステムをどのように構成したのかはわかりません。

  2. ls -l /proc/<pid>/fd > /lsOutputモジュール自体から(経由で)実行した後system()

[root@hypervisor pam]# cat /lsOutput 合計 0

lrwx------。1 ルート ルート 64 6 月 15 日 15:09 0 -> /dev/null

lrwx------。1 ルート ルート 64 6 月 15 日 15:09 1 -> /dev/null

lrwx------。1 ルート ルート 64 6 月 15 日 15:09 2 -> /dev/null

lr-x------。1 ルート ルート 64 6 月 15 日 15:09 3 -> ソケット:[426180]

[root@hypervisor pam]#

lsユーザーがログインした後にマニュアルを発行します。

[root@hypervisor pam]# ls -l /proc/18261/fd
total 0
lrwx------. 1 root root 64 Jun 15 15:15 0 -> /dev/null
lrwx------. 1 root root 64 Jun 15 15:15 1 -> /dev/null
lrwx------. 1 root root 64 Jun 15 15:15 11 -> /dev/ptmx
lrwx------. 1 root root 64 Jun 15 15:15 12 -> /dev/ptmx
lrwx------. 1 root root 64 Jun 15 15:15 13 -> socket:[426780]
lrwx------. 1 root root 64 Jun 15 15:15 14 -> socket:[426829]
lrwx------. 1 root root 64 Jun 15 15:15 2 -> /dev/null
lrwx------. 1 root root 64 Jun 15 15:15 3 -> socket:[426180]
lrwx------. 1 root root 64 Jun 15 15:15 4 -> socket:[426322]
lr-x------. 1 root root 64 Jun 15 15:15 5 -> pipe:[426336]
l-wx------. 1 root root 64 Jun 15 15:15 6 -> pipe:[426336]
lrwx------. 1 root root 64 Jun 15 15:15 7 -> socket:[426348]
lrwx------. 1 root root 64 Jun 15 15:15 8 -> socket:[426349]
lrwx------. 1 root root 64 Jun 15 15:15 9 -> /dev/ptmx
[root@hypervisor pam]#

したがって、基本的には、TTY と追加のソケットの両方がセッション モジュールの終了後にのみ開かれるようです (私の一時的なテスト モジュールのセッション処理は、sshdサービスのスタックの最後です)。私はそれを別の方法で取得することができませんでした (または、接続しているクライアントが記述子 3 の TCP ソケットではない場合について考えることさえできます)。

これは私の想像力の欠如によるものですか、それとも必然的なものですか?クライアントとのコミュニケーションは、他の有用なことを行うための前提条件と思われるため、私は後者に傾いています。よくわからないので、誰かに聞いてみようと思います。記述子 3 は常に認証クライアントになります (私の .so は、それが最も小さい番号の TCP ソケットであり、TTY がない場合のみであると仮定しますが、3常に接続クライアントの記述子である必要があるようです)。最初の TCP 記述子をプルすることは、リモート クライアントの ID を確立する「決定論的」な方法でしょうか? それとも、これが実行されるはずの規定された方法はなく、それは私のシステムがどのように構成されているか、または SSH が PAM とのインターフェースとしてどのように選択されているかのどちらかですか?

  1. それsshdrhost 値を設定しているのか、それとも他の場所から来ているのか? grepSSH と libpam の両方のソース コードを試してみましたが、ダイスはありませんでした。何かが pam_set_item を呼び出したときに libpam がホスト値の設定を処理する場所を確認できますが、pam_set_item が実際に呼び出されて特定のホストに設定されたわけではありません。

グーグルで検索しましたが、バレルの底をこすって指先に破片がつき始めています。

私がこれを知ることに興味を持っている主な理由は、「正しい」答えだけでなく、後で驚くようなことがないようにするためです. これを行う可能性のある Solaris プラットフォームがいくつかありますが、私の主な動機は、実際には一定であることに基づいた仮定を立てることです。

また、クライアント プログラム/モジュールにホスト情報をライブラリにフィードさせることもできますが、その場合、コードを 2 ~ 3 回書き直す必要があることも認識しています (CLI ツールは utmp からセッション情報を準備し、pam_get_item から PAM モジュールを準備するため)。プロジェクトが必要以上に複雑に見える可能性があります。

4

1 に答える 1

0

あなたの質問のいくつかに答えます:

「PAM の運用を管理する公式の基準はありますか?」

どうやら、はい。Pluggable_Authentication_Moduleに関するウィキペディアのエントリには、「PAM は X/Open UNIX 標準化プロセスの一部として標準化され、その結果、X/Open シングル サインオン (XSSO) 標準ができた」とあります。これが私の対処に特に関連しているとは思いませんでした。

「これは私の想像力の欠如によるものですか、それとも必然的なものですか?」

<magicEightBall>"Concentrate and ask again"</magicEightBall> (どの「これ」が言及されているかはあいまいです - おそらく明確にできますか?

「記述子 3 は常に認証クライアントになりますか?」

これは、PAM ではなく、アプリケーションの動作です。

最初の TCP 記述子をプルすることは、リモート クライアントの ID を確立する「決定論的」な方法でしょうか?

また、アプリケーションの動作。

「rhost値を設定しているのはsshdですか、それとも別の場所からのものですか?」

rhost 値を設定するのは sshd です。openssh のファイル auth-pam.c、関数 sshpam_init() では、次のことがわかります。

sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost);

一般的な注意事項:

  • TTY をキーオフするのではなく (後から設定することがわかりました)、getppid() と /proc を介してプロセス系列をたどることができます。
  • PAM モジュールの system() を信頼しないでください。これはユーザーの環境を使用するため、期待したものではない可能性があります。代わりに fork()/execlp() を使用してください。
于 2013-06-28T21:23:03.290 に答える