Pam Exec Örnekleri

ergün elvan bilsel
4 min readApr 30, 2023

PAM Exec, Linux işletim sistemi tarafından kullanıcı kimlik doğrulama sürecinde kullanılan bir modüldür. Bu modül, kullanıcının belirli işlemlerini gerçekleştirdiğinde bir betik dosyasını otomatik olarak çalıştırır. Genellikle, kullanıcının oturum açması veya oturumu kapatması sırasında bir betik dosyası çalıştırılmak istenir.

Örneğin, aşağıdaki PAM yapılandırma dosyası örneği, bir kullanıcının oturum açtığında /etc/motd dosyasındaki bir metin dosyasını görüntüler:

auth required pam_exec.so /usr/local/bin/motd.sh

Bu örnekte, PAM Exec modülü /usr/local/bin/motd.sh dosyasını çalıştırarak kullanıcının oturum açması sırasında /etc/motd dosyasını görüntüler.

#!/bin/bash

# Giriş mesajını oluşturma
HOSTNAME=`hostname`
DATE=`date +"%A, %d %B %Y"`
MESSAGE="Merhaba, $USER. Bugün $DATE tarihinde $HOSTNAME makinesinde oturum açtınız."

# Mesajı göster
echo "$MESSAGE"

Şimdi gerçek hayatta kullanabileceğimiz 3 örnek ile konuyu biraz daha irdelemek istiyorum;

  1. Kullanıcının oturum açtığında bir uyarı gösterme
  2. Kullanıcının oturum açtığında belirli bir işlemi gerçekleştirme
  3. Kullanıcı oturum süresini kısıtlama

Kullanıcının oturum açtığında bir uyarı gösterme

Bu işlem için bir farklı yöntemler olsa dahi biz konuyu örneğimizi “pam exec” ile gerçekleştireceğiz. Öncelikle biz ssh üzerinden gelen bağlantı isteklerinde pam exec modülünü bir uyarı mesajı göstereceğiz. Bunun için ssh config file içerisinde “UsePAM yes” olarak ayarlanmalıdır.

Kullanıdığım dağıtım Fedora38 ve varsayılan olarak ssh servisi pam modüllerini kullanmamakta.

sed -i 's/#UsePAM no/UsePAM yes/' /etc/ssh/sshd_config
systemctl restart sshd

“/usr/local/bin/login-info.sh” adında bir betik dosyası oluşturmanız gerekiyor. Bu dosya aşağıdaki gibi olabilir:

#!/bin/bash

# Kullanıcı adını ve bağlantı zamanını al
USER=$PAM_USER
LOGIN_TIME=`who -b | awk '{print $3" "$4}'`

# Anlık CPU ve RAM kullanımını al
CPU=`top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}'`
RAM=`free | awk '/Mem/ {printf("%.2f%"), $3/$2*100}'`

# Kullanıcı bilgileri ve sistem durumu mesajı
MESSAGE="Merhaba, $USER. Bu makineye $LOGIN_TIME tarihinde bağlandınız. Anlık CPU kullanımı: $CPU%, RAM kullanımı: $RAM."

# Mesajı göster
echo "$MESSAGE"
chmod +x /usr/local/bin/login-info.sh

Şimdi, “/etc/pam.d/sshd” dosyasını düzenleyerek aşağıdaki satırları eklemeniz gerekiyor:

session optional pam_exec.so seteuid /usr/local/bin/login-info.sh
#%PAM-1.0
auth substack password-auth
auth include postlogin
account required pam_sepermit.so
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session optional pam_exec.so stdout /usr/local/bin/login-info.sh # pam_exec
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session optional pam_motd.so
session include password-auth
session include postlogin
~

Yukarıdaki satır, “session” bölümünde çalışacak olan PAM exec modülünü yapılandırır. Bu modül, “/usr/local/bin/login-info.sh” dosyasını çalıştırır ve kullanıcı bilgilerini ve sistem durumunu mesaj olarak gösterir.

“stdout” akışı, normal çıktı akışıdır ve PAM modülleri tarafından yazılan mesajlar genellikle bu akış aracılığıyla ekrana yazdırılır.

“optional”, PAM modüllerinde bir seçenektir ve belirli bir modülün başarısız olması durumunda oturum açma işlemine devam edilmesine izin verir.

Bu şekilde yapılandırılmış bir sistemde, bir kullanıcı SSH bağlantısı kurduğunda, yukarıdaki betik dosyası çalışacak ve kullanıcı bilgilerini, bağlantı zamanını, anlık CPU ve RAM kullanımını içeren bir mesaj gösterilecektir.

Kullanıcının oturum açtığında belirli bir işlemi gerçekleştirme

Bir kullanıcı sisteme login olduğu zaman bir python betiği çalışacak ve istemciye belirli bilgileri kayıt etmesini istediğimiz bir senaryo ile devam ediyoruz. Bu sefer “/etc/pam.d/login” dosyasında pam_exec modülü çalıştıracak şekilde düzenleme yapıyoruz.

session    optional     pam_exec.so     /usr/local/bin/get-news.py

sisteme login olan kullanıcı get-news.py betiğini çalıştıracak.

#%PAM-1.0
auth substack system-auth
auth include postlogin
account required pam_nologin.so
account include system-auth
password include system-auth
# pam_selinux.so close should be the first session rule
session required pam_env.so # sistemde env tanımlamak isterseniz /etc/security/pam_env.conf
session optional pam_exec.so /usr/local/bin/get-news.py # pam_exec
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include system-auth
session include postlogin
-session optional pam_ck_connector.so
~

Örnek oluşturması için github da kernel versiyonlarını çeken basit bir betik oluşturduk.

#!/usr/bin/env python3
import urllib.request
import os,re

try:
url = 'https://github.com/torvalds/linux/tags'
response = urllib.request.urlopen(url)
html_content = response.read()

# Etiketlerin kalıbını arayın
pattern = r"<a\s.*?\s*href=\"/torvalds/linux/archive/refs/tags/([^\"]*)\""

# Etiketleri çıkarın
tags = re.findall(pattern, str(html_content))

filename = "/root/etiketler.txt"

# Dosyayı yazma modunda açın
with open(filename, "w") as file:
# Etiketleri dosyaya yazdırın
for tag in tags:
file.write(tag + "\n")
except Exception as e:
print(e)

Çalışmada hata alırsanız firewalld ve selinux ayarlarını kontrol etmeyi unutmayın! stdout ile çıktıyı dışarıya aktarabilirsiniz.

Kullanıcı oturum süresini kısıtlama

Büyük sistemlerde tek bir noktadan kontrol eden sunuculara birden fazla sistem yöneticisinin giriş yapması ve işlem yapması bazı durumlarda istenmeyen bir durum oluşturabiliyor. Bu durumu “pam_exec” ile ortadan kaldıracağız.

Öncelikle 10 saniye boyunca true dönecek ve 10 saniye sonunda oturumu kapatacak betik yazalım;

vi /usr/local/bin/timeout.sh
#!/bin/bash
WAIT_TIME=120
user_tty=`last | awk 'NR==1{print $2}'`
wait_and_do_something() {
sleep "$WAIT_TIME"
pkill -9 -t $user_tty
}
wait_and_do_something &
/usr/bin/timeout $WAIT_TIME /bin/true
chmod +x /usr/local/bin/timeout.sh 

ve “/etc/pam.d/sshd” dosyasının içerisine kuralımızı ekleyelim. Önceki kurallardan farklı olarak bu kuralda “ — wait” parametresi görmektesiniz.

session required pam_exec.so /usr/local/bin/timeout.sh --wait

--wait parametresi, timeout.sh betiği tarafından kullanılan bir argümandır. Bu argüman, timeout.sh betiğinde, kullanıcının belirtilen süre boyunca işlem yapmasını beklemek için kullanılır. Bu süre, timeout.sh betiğinde, WAIT_TIME değişkeninde belirtilir. Bu süre, kullanıcının belirtilen süre içinde bir işlem gerçekleştirmezse, kullanıcının oturumu kapatılır. Dolayısıyla --wait parametresi, timeout.sh betiğinde kullanılan bir argümandır ve belirli bir süre kullanıcının işlem yapmasını bekletmek için kullanılır.

“required” kelimesi ise PAM kurallarının bir parçası olarak kullanılan bir parametredir. Bu parametre, belirtilen modülün oturum açma işlemi için zorunlu olduğunu belirtir.

--

--