GNU/Linux >> Tutoriels Linux >  >> Linux

Comment créer une entrée PAM conditionnelle

Voici une solution qui fonctionne pour moi. Mon /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

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

J'obtiens ce comportement :

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

La première ligne ajoutée au pam.d/sudo par défaut appelle le pam_exec et, s'il réussit, saute l'entrée suivante. La deuxième ligne refuse simplement l'accès sans condition.

En /tmp/test-pam J'appelle last pour obtenir l'adresse IP associée au téléimprimeur à partir duquel pam a été appelé. ${PAM_TTY#/dev/} supprime /dev/ du devant de la valeur, car last ne reconnaît pas le chemin complet du périphérique. Le -i le drapeau fait last afficher soit l'adresse IP soit l'espace réservé 0.0.0.0 s'il n'y a pas d'adresse IP ; par défaut, il affiche une chaîne d'informations beaucoup plus difficile à vérifier. C'est aussi pourquoi j'ai utilisé last au lieu de who ou w; ceux-ci n'ont pas une option similaire. Le -p now l'option n'est pas strictement nécessaire, comme nous le verrons awk ne vérifie que la première ligne de sortie, mais il limite last pour afficher uniquement les utilisateurs actuellement connectés.

Le awk commande vérifie simplement la première ligne, et si le troisième champ n'est pas 0.0.0.0 il sort avec une erreur. Puisqu'il s'agit de la dernière commande dans /tmp/test-pam , le code de sortie d'awk devient le code de sortie du script.

Sur mon système, aucun des tests que vous essayiez dans votre deny-ssh-user.sh travaillerait. Si vous mettez env > /tmp/test-pam.log en haut de votre script, vous verrez que l'environnement a été supprimé, donc aucune de vos variables SSH_FOO ne sera définie. Et $PPID pourrait pointer vers n'importe quel nombre de processus. Par exemple, exécutez perl -e 'system("sudo cat /etc/passwd")' et voyez que $PPID fait référence au perl processus.

Ceci est Arch Linux, noyau 4.16.11-1-ARCH , au cas où ça compte. Je ne pense pas que cela devrait, cependant.


Eh bien, il s'avère que je suis en fait un idiot, le pam_exec.so module est parfaitement adapté à la création de conditions PAM.

Tim Smith avait raison d'évaluer que les deux tests dans mon /etc/security/deny-ssh-user.sh le script ne définissait JAMAIS la variable SSH_SESSION à vrai. Je n'ai pas pris cela en considération car le script fonctionne dans un shell normal, mais le contexte de l'environnement est supprimé lorsqu'il est exécuté par pam_exec.so .

J'ai fini par réécrire le script pour utiliser le last utilitaire tout comme son exemple, mais j'ai dû en changer certains car les commutateurs pour last diffèrent d'Arch Linux à RedHat.

Voici le script révisé dans /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

Contenu de /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. Comment créer un script d'une commande Linux

  2. Comment créer un Playbook Ansible

  3. Comment créer des balises Git

  4. Comment créer un sous-domaine

  5. Comment créer un lien vers un répertoire

Comment créer un StatefulSet dans Kubernetes

Comment créer une file d'attente SQS sur AWS

Comment créer une table DynamoDB dans AWS

Comment créer des raccourcis sur le bureau Linux

Comment créer un alias SSH sous Linux

Comment créer un alias sous Linux