GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So erstellen Sie einen bedingten PAM-Eintrag

Hier ist eine Lösung, die für mich funktioniert. Mein /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

Und /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; }'

Ich bekomme dieses Verhalten:

$ 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$

Die erste Zeile, die dem Standardwert pam.d/sudo hinzugefügt wird ruft pam_exec auf und überspringt bei Erfolg den nächsten Eintrag. Die zweite Zeile verweigert den Zugriff einfach bedingungslos.

In /tmp/test-pam Ich rufe last an um die IP-Adresse zu erhalten, die dem TTY zugeordnet ist, von dem aus pam aufgerufen wurde. ${PAM_TTY#/dev/} entfernt /dev/ vom Anfang des Werts, weil last erkennt nicht den vollständigen Gerätepfad. Die -i Flag macht last entweder die IP-Adresse oder den Platzhalter 0.0.0.0 anzeigen wenn es keine IP-Adresse gibt; standardmäßig zeigt es einen Info-String, der viel schwieriger zu überprüfen ist. Aus diesem Grund habe ich auch last verwendet statt who oder w; diese haben keine ähnliche Option. Die -p now Option ist nicht unbedingt erforderlich, da wir awk sehen werden prüft nur die erste Ausgabezeile, schränkt aber last ein um nur Benutzer anzuzeigen, die derzeit angemeldet sind.

Die awk Der Befehl prüft nur die erste Zeile und ob das dritte Feld nicht 0.0.0.0 ist es wird mit einem Fehler beendet. Da dies der letzte Befehl in /tmp/test-pam ist , wird der Exit-Code von awk zum Exit-Code für das Skript.

Auf meinem System ist keiner der Tests, die Sie versucht haben, in Ihrem deny-ssh-user.sh würde funktionieren. Wenn Sie env > /tmp/test-pam.log eingeben Oben in Ihrem Skript sehen Sie, dass die Umgebung entfernt wurde, sodass keine Ihrer SSH_FOO-Variablen festgelegt wird. Und $PPID könnte auf eine beliebige Anzahl von Prozessen zeigen. Führen Sie beispielsweise perl -e 'system("sudo cat /etc/passwd")' aus und sehen Sie, dass sich $PPID auf perl bezieht verarbeiten.

Dies ist Arch Linux, Kernel 4.16.11-1-ARCH , falls es darauf ankommt. Ich glaube aber nicht, dass es so sein sollte.


Nun, es stellt sich heraus, dass ich eigentlich ein Idiot bin, der pam_exec.so -Modul ist vollkommen in Ordnung, um PAM-Bedingungen zu erstellen.

Tim Smith hat richtig eingeschätzt, dass beide Tests in meinem /etc/security/deny-ssh-user.sh liegen -Skript haben die Variable SSH_SESSION NIE gesetzt zu wahr. Ich habe das nicht berücksichtigt, weil das Skript in einer normalen Shell funktioniert, aber der Umgebungskontext entfernt wird, wenn es von pam_exec.so ausgeführt wird .

Am Ende habe ich das Skript umgeschrieben, um den last zu verwenden Dienstprogramm genau wie sein Beispiel, aber ich musste einiges davon ändern, weil die Schalter für last unterscheiden sich von Arch Linux zu RedHat.

Hier ist das überarbeitete Skript unter /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

Inhalt von /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. So erstellen Sie ein Skript eines Linux-Befehls

  2. So erstellen Sie ein Ansible-Playbook

  3. So erstellen Sie Git-Tags

  4. So erstellen Sie eine Subdomain

  5. So erstellen Sie eine Subdomain

So erstellen Sie ein StatefulSet in Kubernetes

So erstellen Sie eine SQS-Warteschlange auf AWS

So erstellen Sie eine DynamoDB-Tabelle in AWS

So erstellen Sie Verknüpfungen auf dem Linux-Desktop

So erstellen Sie einen SSH-Alias ​​unter Linux

So erstellen Sie einen Alias ​​unter Linux