GNU/Linux >> Linux の 問題 >  >> Linux

条件付き PAM エントリを作成する方法

ここに私のために働く解決策があります。私の /etc/pam.d/sudo :

#%PAM-1.0
auth            [success=1]     pam_exec.so    /tmp/test-pam
auth            required        pam_deny.so
auth            include         system-auth
account         include         system-auth
session         include         system-auth

そして /tmp/test-pam :

#! /bin/bash
/bin/last -i -p now ${PAM_TTY#/dev/} | \
    /bin/awk 'NR==1 { if ($3 != "0.0.0.0") exit 9; exit 0; }'

私はこの動作を取得します:

$ sudo date
[sudo] password for jdoe:
Thu Jun 28 23:51:58 MDT 2018
$ ssh localhost
Last login: Thu Jun 28 23:40:23 2018 from ::1
valli$ sudo date
/tmp/test-pam failed: exit code 9
[sudo] password for jdoe:
sudo: PAM authentication error: System error
valli$

デフォルトの pam.d/sudo に追加された最初の行 pam_exec を呼び出します 成功した場合は、次のエントリをスキップします。 2 行目は無条件にアクセスを拒否するだけです。

/tmp/test-pamlast と呼びます pam が呼び出された TTY に関連付けられた IP アドレスを取得します。 ${PAM_TTY#/dev/} /dev/ を削除します last であるため、値の先頭から 完全なデバイス パスを認識しません。 -i フラグは last になります IP アドレスまたはプレースホルダー 0.0.0.0 のいずれかを表示します IP アドレスがない場合。デフォルトでは、確認がはるかに難しい情報文字列が表示されます。これが last を使用した理由でもあります who の代わりに または w;それらには同様のオプションがありません。 -p now awk が表示されるため、オプションは厳密には必要ありません。 出力の最初の行のみをチェックしていますが、 last を制限しています 現在ログインしているユーザーのみを表示します。

awk コマンドは最初の行をチェックするだけで、3 番目のフィールドが 0.0.0.0 でない場合 エラーで終了します。これは /tmp/test-pam の最後のコマンドなので 、awk の終了コードがスクリプトの終了コードになります。

私のシステムでは、あなたが deny-ssh-user.sh で試していたテストはどれもありませんでした 動作します。 env > /tmp/test-pam.log を入れると スクリプトの先頭で、環境が削除されていることがわかります。そのため、SSH_FOO 変数は設定されません。 $PPID は、任意の数のプロセスを指すことができます。たとえば、perl -e 'system("sudo cat /etc/passwd")' を実行します。 $PPID が perl を参照していることを確認します

これは Arch Linux、カーネル 4.16.11-1-ARCH です 、重要な場合に備えて。でも、そうすべきではないと思います。


pam_exec.so というのは、実は私がバカなのです。 モジュールは、PAM 条件を作成するのに最適です。

私の /etc/security/deny-ssh-user.sh での両方のテストの評価において、Tim Smith は正しかった スクリプトは変数 SSH_SESSION を決して設定しませんでした 真に。スクリプトは通常のシェルで動作するため、考慮していませんでしたが、pam_exec.so で実行すると環境コンテキストが削除されます。 .

last を使用するようにスクリプトを書き直すことになりました ユーティリティは彼の例と同じですが、 last のスイッチのため、一部を変更する必要がありました Arch Linux と RedHat では異なります。

/etc/security/deny-ssh-user.sh の改訂されたスクリプトは次のとおりです。

#!/bin/bash
# Returns 1 if the user is logged in through SSH
# Returns 0 if the user is not logged in through SSH
SSH_SESSION=false

function isSshSession {
    local terminal="${1}"
    if $(/usr/bin/last -i | 
        /usr/bin/grep "${terminal}" |
        /usr/bin/grep 'still logged in' |
        /usr/bin/awk '{print $3}' |
        /usr/bin/grep -q --invert-match '0\.0\.0\.0'); then
        echo true
    else
        echo false
    fi
}

function stripTerminal {
    local terminal="${1}"

    # PAM_TTY is in the form /dev/pts/X
    # Last utility displays TTY in the form pts/x
    # Returns the first five characters stripped from TTY
    echo "${terminal:5}"
}

lastTerminal=$( stripTerminal "${PAM_TTY}")
SSH_SESSION=$(isSshSession "${lastTerminal}")

if "${SSH_SESSION}"; then
    exit 1
else
    exit 0
fi

/etc/pam.d/sudo の内容

....
auth    [success=ok default=1]    pam_exec.so /etc/security/deny-ssh-user.sh
auth    sufficient    pam_module_to_skip.so
....

Linux
  1. Linuxコマンドのスクリプトを作成する方法

  2. Gitタグを作成する方法

  3. サブドメインを作成する方法

  1. AnsiblePlaybookの作成方法

  2. サブドメインを作成する方法

  3. ディレクトリへのリンクを作成する方法

  1. KubernetesでMongoDBを実行する方法

  2. Linuxでシンボリックリンクを作成する方法

  3. Bashエイリアスを作成する方法