Koşullu bir PAM girişi nasıl oluşturulur?


7

PAM senaryolarını RedHat 7.5'te test ediyorum

Pam_succeed_if.so pam modülü, PAM'ın sunduğu en temel koşullu test seviyesi gibi gözüküyor ve benim ihtiyaçlarımı karşılamıyor. Sadece kullanıcı, kullanıcı adı, gid, kabuk, ev, ruser, rhost, tty ve servis alanlarında testler oluşturabilirsiniz.

Benim durumumda 'rhost' alanını temel alarak test etmek istiyorum, ancak modülü hata ayıklama işlemine yerleştirdikten sonra, rhost alanının ayarlanmadığını gördüm.

Amacım , kullanıcı makineye yerel olarak giriş yaptıysa, yalnızca /etc/pam.d/sudo içindeki PAM modülünü çalıştırmaktır . Kullanıcının SSH üzerinden giriş yaptığını tespit edersek, o zaman modülü atlamak istiyorum. Aslında işe yarayacağını düşündüğüm 3 farklı fikir bulmuştum ama hepsi başarısız oldu.

Başarısız olan birkaç çözümü paylaşacağım.

Pam_exec.so kullanarak koşullu giriş

Aşağıdaki pam girişini koşullu olarak atlamak istediğim pam modülünün üstüne eklemek istedim:

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

/Etc/security/deny-ssh-user.sh içeriği

#!/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
if [ -n "${SSH_CLIENT}" ] || [ -n "${SSH_TTY}" ] || [ -n "${SSH_CONNECTION}" ]; then
    SSH_SESSION=true
else
    case $(ps -o comm= -p $PPID) in
        sshd|*/sshd) SSH_SESSION=true;;
    esac
fi

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

Pam_exec.so kaynak kodunu https://github.com/linux-pam/linux-pam/blob/master/modules/pam_exec/pam_exec.c adresinde okudum ve şaşırtıcı bir şekilde, HER ZAMAN PAM_SUCCESS döndürür Komut dosyasının çıkış kodunun açıklaması. Ve betiğin pam_exec modülünün PAM_SERVICE_ERR, PAM_SYSTEM_ERR veya PAM_IGNORE döndürmesine neden olmasını sağlayamıyorum.

Pam_access.so kullanarak koşullu giriş

Yine, koşullu olarak atlamak istediğim pam modülünün üstüne aşağıdaki pam girişini ekliyorum

auth    [success=ok perm_denied=1]    pam_access.so    accessfile=/etc/security/ssh-sudo-access.conf noaudit

/Etc/security/ssh-sudo-access.conf içeriği

+:ALL:localhost 127.0.0.1 
-:ALL:ALL

Vay, süper temiz değil mi? Yerel olarak giriş yaptıysanız ve geri kalan her şeyi reddederseniz başarıya ulaşırsınız. Peki hayır. Pam_access.so modülü hata ayıklama işlemine sokulduğunda ortaya çıkıyor, uzak ana bilgisayarlara, yalnızca kullanılan uçbirime sahip olduğunu bilmiyor. Böylece pam_access uzaktaki ana bilgisayarlar tarafından erişimi engelleyemiyor.

Sadece PAM modülünü atlayabilmem için hangi kara büyüyü kullanmam gerektiğine karar vermek için kelimenin tam anlamıyla kaynak kodu okuduğu çılgınca bir gündü.


1
Pam_exec.c Benim okuma tam o olacak dönmekPAM_SYSTEM_ERR komut zaman sıfırdan farklı bir değer döndürür . Belki bu yöntemi tekrar kontrol edebilirsin.
Tim Smith,

Bu tam olarak benim de yorumum. Ne yazık ki, durum böyle değil. Hatta pam_exec'in döndürdüğü iddia edilen tüm çıkış kodlarını döndürmeye çalıştım: betiğimde 4 (PAM_SYSTEM_ERR), 3 (PAM_SERVICE_ERR) ve 25 (PAM_IGNORE). Pam modülünde, 30 farklı PAM durum kodunun tümünü yakalamaya çalıştım ve davranışı etkileyen tek durum kodu PAM_SUCCESS idi. pam_exec.soModül gerçekten açıklamaya yazılmalıdır ateşler bir komut dosyası kapalı ve bağımsız olarak her zaman komut dosyası döndürür ne olursa olsun çıkış kodu başarısını dönecektir
Luke Pafford

Bunun auth [success=1] pam_debug.so auth=auth_erryerine kullanmak yardımcı olabilir ... pam_exec.so .... Ve olması gerektiği gibi başarısız olduğunu doğrulayın, böylece yığının doğru yapılandırıldığını bilirsiniz.
Tim Smith,

Yanıtlar:


5

İşte benim için işe yarayan bir çözüm. Benim /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

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

Bu davranışı alıyorum:

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

Varsayılan pam.d/sudoaramalara eklenen ilk satır pam_execve başarılı olursa bir sonraki girişi atlar. İkinci satır sadece koşulsuz erişime izin vermez.

Gelen /tmp/test-pamAramaya lastTTY Pam ile ilişkili IP adresini almak için gelen çağrıldı. tam aygıt yolunu tanımadığından, değerin önünden ${PAM_TTY#/dev/}kaldırır . Bayrak yapan IP adresini veya yer tutucu ya göstermek hiçbir IP adresi varsa; Varsayılan olarak, kontrol edilmesi daha zor olan bir bilgi dizesini gösterir. Bu yüzden ya da yerine kullandım ; Bunların benzer bir seçeneği yok. Bu seçenek kesinlikle gerekli değildir, çünkü göreceğimiz gibi yalnızca ilk çıktı satırını kontrol etmekle kalmayıp, yalnızca oturum açmış olan kullanıcıları göstermeyi kısıtlar ./dev/last-ilast0.0.0.0lastwhow-p nowawklast

awkKomut sadece ilk satırı denetler ve üçüncü alan değilse 0.0.0.0bir hata ile çıkar. Bu /tmp/test-pam, komuttaki son komut olduğundan , awk çıkış kodu, betiğin çıkış kodu olur.

Benim sistemimde, denediğin testlerin hiçbiri deny-ssh-user.shişe yaramadı. env > /tmp/test-pam.logKomut dosyanızın en üstüne koyarsanız , ortamın çıkarıldığını görürsünüz, böylece SSH_FOO değişkenlerinizden hiçbiri ayarlanmaz. Ve $ PPID herhangi bir sayıda işleme işaret edebilir. Örneğin, çalıştırın perl -e 'system("sudo cat /etc/passwd")'ve $ PPID'in işleme atıfta bulunduğunu görün perl.

Bu, 4.16.11-1-ARCHönemli olması durumunda , çekirdek Linux . Olması gerektiğini sanmıyorum.


3

Görünüşe göre aslında ben bir aptalım, pam_exec.somodül PAM koşullamaları oluşturmak için gayet iyi.

Tim Smith, betiğimdeki her iki testin /etc/security/deny-ssh-user.shde ASLA değişkeni SSH_SESSIONtrue olarak ayarlayamadığını doğruladı. Senaryo normal bir kabukta çalıştığı için bunu dikkate almadım, ancak ortam bağlamı tarafından çalıştırıldığı zaman çıkarıldı pam_exec.so.

lastYardımcı programı kullanmak için senaryoyu tekrar yazdım, ancak bazılarını değiştirmek zorunda kaldım, çünkü anahtarlar lastArch Linux'tan RedHat'a değişiyordu .

İşte /etc/security/deny-ssh-user.sh adresindeki revize edilmiş script:

#!/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 içeriği

....
auth    [success=ok default=1]    pam_exec.so /etc/security/deny-ssh-user.sh
auth    sufficient    pam_module_to_skip.so
....
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.