GNU/Linux >> Belajar Linux >  >> Linux

Cara membuat entri PAM bersyarat

Berikut adalah solusi yang bekerja untuk saya. /etc/pam.d/sudo saya :

#%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

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

Saya mendapatkan perilaku ini:

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

Baris pertama ditambahkan ke pam.d/sudo default memanggil pam_exec dan, jika berhasil, lewati entri berikutnya. Baris kedua hanya menolak akses tanpa syarat.

Di /tmp/test-pam Saya memanggil last untuk mendapatkan alamat IP yang terkait dengan pam TTY yang dipanggil. ${PAM_TTY#/dev/} menghapus /dev/ dari depan nilai, karena last tidak mengenali jalur perangkat lengkap. -i bendera membuat last tampilkan alamat IP atau placeholder 0.0.0.0 jika tidak ada alamat IP; secara default ini menunjukkan string info yang jauh lebih sulit untuk diperiksa. Ini juga mengapa saya menggunakan last bukannya who atau w; mereka tidak memiliki opsi serupa. -p now opsi tidak sepenuhnya diperlukan, seperti yang akan kita lihat awk hanya memeriksa baris keluaran pertama, tetapi membatasi last untuk menampilkan hanya pengguna yang saat ini masuk.

awk perintah hanya memeriksa baris pertama, dan jika kolom ketiga bukan 0.0.0.0 itu keluar dengan kesalahan. Karena ini adalah perintah terakhir di /tmp/test-pam , kode keluar awk menjadi kode keluar untuk skrip.

Di sistem saya, tidak ada tes yang Anda coba di deny-ssh-user.sh Anda akan berhasil. Jika Anda memasukkan env > /tmp/test-pam.log di bagian atas skrip Anda, Anda akan melihat bahwa lingkungan telah dihapus, sehingga tidak ada variabel SSH_FOO Anda yang akan disetel. Dan $PPID dapat menunjuk ke sejumlah proses. Misalnya, jalankan perl -e 'system("sudo cat /etc/passwd")' dan lihat bahwa $PPID merujuk ke perl proses.

Ini adalah Arch Linux, kernel 4.16.11-1-ARCH , jika itu penting. Saya pikir itu tidak seharusnya.


Yah ternyata saya sebenarnya idiot, pam_exec.so modul sangat baik untuk membuat persyaratan PAM.

Tim Smith benar dalam menilai kedua tes di /etc/security/deny-ssh-user.sh saya skrip TIDAK PERNAH menyetel variabel SSH_SESSION untuk benar. Saya tidak mempertimbangkannya karena skrip bekerja di shell normal, tetapi konteks lingkungan dihapus saat dijalankan oleh pam_exec.so .

Saya akhirnya menulis ulang skrip untuk menggunakan last utilitas seperti contohnya, namun saya harus mengubahnya karena beralih ke last berbeda dari Arch Linux ke RedHat.

Ini skrip yang direvisi di /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

Isi dari /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. Cara Membuat Script Perintah Linux

  2. Cara membuat Playbook yang Mungkin

  3. Cara membuat Tag Git

  1. Cara Membuat Subdomain

  2. Cara membuat subdomain

  3. Cara membuat tautan ke direktori

  1. Cara Menjalankan MongoDB di Kubernetes

  2. Cara Membuat Tautan Simbolik di Linux

  3. Cara Membuat Bash Alias ​​​​