Debian Gnu/Linux ile Sistem Kullanıcısına Ait Şifreleme İşlemleri

Debian Türkiye sitesinden

Melen (Mesaj | katkılar) tarafından oluşturulmuş 12:18, 14 Mayıs 2008 tarihli sürüm (Yeni sayfa: Özellikle Sistem Yöneticilerinin işine yarayacak perl betikleri ve /etc/shadow dosyasının yapısı hakkında bilgiler içerir. Debian Gnu/Linux ile Sistem Kullanıcısına Ait Şi...)

(fark) ← Önceki hâli | en güncel halini göster (fark) | Sonraki hâli → (fark)
Özellikle Sistem Yöneticilerinin işine yarayacak perl betikleri ve /etc/shadow dosyasının yapısı hakkında bilgiler içerir.

Debian Gnu/Linux ile Sistem Kullanıcısına Ait Şifreleme İşlemleri Yazan : Serdar Aytekin - serdar~aytekin.web.tr Versiyon : 1.0.0 Son Güncellenme Tarihi : 16-01-2005

Giriş :

Belgede yazılanların uygulanıp uygulanmaması tamamen uygulayan kişinin sorumluluğundadır. Belgede bahsedilenlerin uygulanması sonucu ortaya çıkabilecek hertürlü zarardan yazar sorumlu tutulamaz. Belge GNU Özgür Belgeleme Lisansının http://www.gnu.org/copyleft/fdl.html adresinde yer alan -son sürümdeki- lisans içeriğine bağlı kalmak koşulu ile aynen yada kısmen dağıtılabilir, yayınlanabilir.

Bu belgenin son sürümüne;

http://www.serdaraytekin.com/docs/os/debian/debian-shadow-password.html adresinden ulaşabilirsiniz.

Kullanıcı Parolalarının Shadow Dosyasındaki Yapısı

Kullanıcı parolaları crypt(3) olarak bilinen şifreleme yönteminin glibc2 ile birlikte gelen versiyonu ile oluşturulmaktadır. Bu fonksiyon MD5-tabanlı olarak maksimum 34 karakterlik bir şifre üretir. Üretilen karakter katarı $1$ ile başlar ve bundan sonra gelebilecek maksimum 8 karakterlik kısımda da salt değeri yer alır. Salt değeri $ ile son bularak daha sonra gelen 22 karakter ile katar tamamlanır. Biraz daha net ifade etmeye çalışırsak katarın yapısı şu şekildedir;

$1$<maksimum_sekiz_karakterlik_salt_değeri>$<yirmi_iki_karakterlik_kullanıcı_parolası>

Burada salt değeri katar içindeki en can alıcı kısımdır. Debian Gnu/Linux üzerinden adduser ile kullanıcı eklerken veya passwd komutu ile parola belirlerken ilgili kullanıcının parolasının nasıl oluşturulduğuna adım adım bakalım.

   * Kullanıcının belirlemek istediği parolayı al.
   * Salt olarak kullanılmak üzere rastgele sekiz karakterlik bir katar oluştur (Debian Gnu/Linux 'daki şifreleme işlemlerinde öntanımlı olarak 8 karakterlik salt değeri üretilir.).
   *
     Kullanıcıdan aldığın parolayı, yukarıda oluşturulmuş olan salt değeri ile birlikte crypt fonksiyonundan geçir ve sonuçta $1$ ile başlayan 34 karakterlik şifreli katarı oluştur.

"adduser" ve "passwd" komutu ile örnek :

Sistemde "adduser" komutu ile sisteme bir kullanıcı ekleyip parolasını da "serdar" olarak ayarlayalım. /etc/shadow için üretilen şifre aşağıdaki şekilde;

$1$Gc7mWBBa$PYrsBDL3/gFMa3wYtbu6U/

Görüldüğü üzere $1$ ile başlayıp 8 karakterlik salt değerinden (Gc7mWBBa) sonra yine $ ile salt değeri sonlanıp kullanıcısın şifresinin yer aldığı 22 karakterlik katar (PYrsBDL3/gFMa3wYtbu6U/) yer alıyor.

Şimdide aynı kullanıcının parolasını "passwd" komutu ile yine "serdar" olarak ayarlalım.

$1$jx6BHZZi$08n4VS6lVGusgcOIBW26w0

Evet görüldüğü üzere yine yapı olarak yukarıdaki sonucun aynısı ancak dikkat edilmesi gereken nokta "serdar" olarak ayarlanan şifreler için rastgele zamanda oluşturulan salt değerine bağlı olarak farklı katarlar üretilmesi.

Salt Değerinin Uzunluğu Ne Kadar Olmalı?

Salt değeri 1 ile 8 karakter arasında olabilir. Ancak yukarıda da belirttiğimiz gibi Debian/Gnu Linux üzerinde sistem kullanıcısı şifrelerinde öntanımlı olarak 8 karakterlik salt değeri kullanılır. Bu değerinde maksimum olması en iyi durumdur zaten. Kullanıcı şifresi için ayrılan kısımda 22 karakter olarak standart değerdir. Bu durumda katarın uzunluğunu salt değerinin uzunluğu belirlerki maksimum sal değeri ile bu uzunluk en fazla 34 karaktere ulaşabilir.

"useradd" Komutu ile Otomatik Parola Belirleme :

Kullanıcı parolalarının oluşturulumasında "useradd" komutu sistem yöneticileri için çok faydalı bir araçtır. Zira "useradd" komutu komut satırından parametre alıp işletecek şekilde dizayn edilmiş esnek ve kullanışlı bir yapıya sahiptir. Diyelimki sisteme 1000 tane kullanıcı açılacak ve bunlara parola belirlenecek. Bu işi nasıl yapmayı düşünüyorsunuz? desem heralde adduser komutu ile teker teker açarız demezsiniz. İşte özellikle böylesi durumlarda useradd komutunun esnekliği bizim için biçilmiş kaftan olacaktır.

Aşağıda crypt fonksiyonunu kullanarak kullanıcılara otomatik parola belirleyebilen ve kullanıcı isimlerini bir dosyadan okuyup istenilen kullanıcı ismine göre sistemde o kullanıyıcı aktif edebilen perl betiği görüyorsunuz.

Betiği Debian Gnu/Linux üzerinde kullanabilmek için öncelikle;

   * apt-get install libcrypt-passwdmd5-perl

ile libcrypt-passwdmd5-perl paketini yüklememiz gerekli.

Betik içersinde zaten gerekli açıklamalar mevcut. Siz aşağıdaki betiği inceleyip amacınıza daha uygun hale getirebilirsiniz.

#!/usr/bin/perl

# Serdar Aytekin serdar~aytekin.web.tr
# Versiyon 1.0.0
# Son Guncelleme Tarihi 16/01/2005

# Parametre olarak belirtilen dosyadan kullanici isimlerini okuyup yine program
# icerisinde belirtilen $userDir, $userGroup, $userShell ve $userChmod degiskenlerinide
# dikkate alarak kullaniciyi sisteme ekler. Ekleme yaparken kullaniciya rastgele sifre atanir.
# Sifreler yine kullanici ismi ile birlikte ikinci paremetre ile belirtilen dosyaya kaydedilir.
# Kullanici sifresi ile ilgili islemler icin libcrypt-passwdmd5-perl paketine ihtiyac duyar.

# Ornek Kullanimi :
# ./kullaniciEkle.pl userFile.txt userPassFile.txt

# Program ile ilgili degiskenler ($userDir'da sondaki "/" slash onemli)

$userDir = "/home/users/program/";
$userGroup = "users";
$userShell = "/bin/bash";
$userDirChmod = "711";

# Kullanicidan arguman olarak alinacak dosya isimleri

$userFile = $ARGV[0];
$userPassFile = $ARGV[1];

if ($#ARGV != 1) {
print "HATALI KULLANIM :: Kullanimi: ./kullaniciEkle.pl userFile.txt userPassFile.txt\n";
exit;
}

open(F,">>./$userPassFile");

if (open(MYFILE, "$userFile")) {

$user = <MYFILE>;

while ($user ne "") {

chop($user);

$userDir = $userDir.$user;

system("mkdir $userDir");

use Crypt::PasswdMD5;

@chars = ( "A" .. "Z", "a" .. "z", 0 .. 9);

$pass_for_encryption = join("", @chars[ map { rand @chars } ( 1 .. 9 ) ]);
$salt2 = join("", @chars[ map { rand @chars } ( 1 .. 8 ) ]);

$crypted = unix_md5_crypt("$pass_for_encryption",$salt2);
$crypted =~ s/\$/\\\$/g;

system("useradd -g $userGroup -s \"$userShell\" -d \"$userDir\" -m -p \"$crypted\" $user");

system("chown -R $user.$userGroup -R $userDir");
system("chmod $userDirChmod $userDir");

# Kullanici adi ve sifresini ikinci parametre olarak belirtilen dosyaya yazalim

print F "$user";
print F " ==> ";
print F "$pass_for_encryption\n";

$user =<MYFILE>;

}
} else {

if (-e "$userFile"){

die ("HATA :: $userFile dosyasi okumak icin acilamiyor\n");

} else {

die ("HATA :: $userFile dosyasi mevcut degil yada hatali yol belirttiniz\n");

}
}

Parolalar Sistem Tarafından Nasıl Doğrulanıyor?

Hatırlarsanız parola olarak "serdar" girip 34 karakterlik bir katar elde etmiştik. Şimdi passwd komut ile bir kullanıcıya "serdar" parolasını atayayım ve sonucunu birlikte değerlendirelim.

$1$y2eWZ0d9$OJeo9GmgHbj2OoWjr69Kh1

Evet salt değerimiz : y2eWZ0d9

Sistem kullanıcı parolasını doğrularken şu şekilde davranıyor;

   * Kullanıcıdan girdiği parolayı al
   * /etc/shadow içerisinde o kullanıcının şifresindeki salt değerini bul
   * Salt değeri ile kullanıcıdan gelen parolayı alarak crypt fonksiyonundan geçir ve elde ettiğin sonucu /etc/shadow dosyasındaki sonuç ile karşılaştırarak girilen parolanın doğru olup olmadığına karar ver.

Bunuda sınayabileceğimiz bie perl betiği aşağıda verilmiştir. Dilerseniz gerekli yerlerde ekrana gerekli değerleri ($salt, $old_password, $new_password gibi) print ederek yukarıdaki senaryonun gerçekleştirilmesini programsal olarakda görmüş olabilirsiniz.

Parametre olarak <kullanıcı_adı>, <eski_parolası> ve <yeni_parolası> değerlerini alır.

#!/usr/bin/perl

# Serdar Aytekin serdar~aytekin.web.tr
# Versiyon 1.0.0
# Son Guncelleme Tarihi 16/01/2005

# Ornek Kullanimi : (Betik ismi chPass.pl olsun)
# ./chPass.pl kullanici_adi eski_sifresi yeni_sifresi

$input_user = $ARGV[0];
$old_password = $ARGV[1];
$new_password = $ARGV[2];

$kontrol = 0;

if (-e "/etc/shadow.lock") {
sleep(2);
}


if (-e "/etc/shadow.lock") {
print "Sistem Mesgul\n";
exit(1);
}

system("touch /etc/shadow.lock");

if ($input_user eq "root"){
print "Ooppss..!\n";
exit(1);
}


if ($new_password eq "" ) {
print "\nYeni Sifreyi Belirtmediniz\n";
exit(1);
}

$shadow = "/etc/shadow";

$sifre = `/bin/grep "^$input_user:" $shadow | /usr/bin/awk -F ":" {'print \$2'}`;
chomp($sifre);

$salt = substr($sifre,3,8);

use Crypt::PasswdMD5;

$old_password = unix_md5_crypt("$old_password",$salt);

if ($old_password eq $sifre) {

@chars = ( "A" .. "Z", "a" .. "z", 0 .. 9);
$salt = join("", @chars[ map { rand @chars } ( 1 .. 8 ) ]);

$new_password = unix_md5_crypt("$new_password",$salt);

open(F,"$shadow");
@thisfile = <F>;
close (F);

foreach $line (@thisfile) {

chomp($line);
@tmp = split(/\:/,$line);
$user = $tmp[0];

if ($user eq "$input_user") {

$kontrol = 1;

$oldstring = "$old_password";
$newstring = "$new_password";

$oldstring =~ s/\$/\\\$/g;

$line =~ s/$oldstring/$newstring/g;

}

open (FILE, ">$shadow");

foreach $line (@thisfile) {
print FILE "$line\n";
}

close (FILE);

}
}

system("rm /etc/shadow.lock");
system("chmod 600 /etc/shadow*");

if ($kontrol == 0) {
print "\nSifreler Uyusmadi..\n";
}

if ($kontrol == 1) {
print "\nTamam Sifre Degistirildi..\n";
}