/etc/passwd ve /etc/shadow Dosyalarını Anlama

Linux sistemlerde kullanıcı yönetimi denildiğinde akla ilk gelen iki dosya vardır: /etc/passwd ve /etc/shadow. Bu iki dosya, sistemdeki tüm kullanıcı hesaplarının temel taşını oluşturur ve bir sysadmin olarak bu dosyaları iyi anlamak, hem güvenlik hem de sorun giderme açısından kritik önem taşır. Yıllar içinde pek çok sistem yöneticisinin bu dosyaları yanlış anladığını veya hiç incelemediğini gördüm. Bu yazıda her iki dosyayı da en ince ayrıntısına kadar ele alacağız.

/etc/passwd Dosyası Nedir?

/etc/passwd dosyası, Linux sistemindeki tüm kullanıcı hesaplarının bilgilerini barındıran düz metin dosyasıdır. “Passwd” adına bakıp burada şifrelerin saklandığını düşünebilirsiniz, ama aslında bu dosya günümüzde artık şifre barındırmaz. Tarihsel olarak şifreler burada tutulurdu, ancak güvenlik nedeniyle şifreler /etc/shadow dosyasına taşındı.

Bu dosyayı okumak için herhangi bir özel yetkiye ihtiyacınız yoktur, sisteme erişimi olan herkes okuyabilir:

cat /etc/passwd

Tipik bir çıktı şöyle görünür:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
ahmet:x:1000:1000:Ahmet Yilmaz,,,:/home/ahmet:/bin/bash
mysql:x:112:118:MySQL Server,,,:/nonexistent:/bin/false

Dosya Yapısı ve Alanlar

Her satır bir kullanıcıyı temsil eder ve alanlar iki nokta üst üste : ile birbirinden ayrılır. Toplam 7 alan bulunur:

1. Kullanıcı adı (username): Sisteme giriş yaparken kullandığınız isim. Genellikle 32 karakteri geçmez ve büyük/küçük harf duyarlıdır.

2. Şifre alanı (password): Burada artık gerçek şifre yoktur. x değeri görürseniz, bu şifrenin /etc/shadow dosyasında saklandığı anlamına gelir. Eğer bu alan boşsa, kullanıcının şifresi yoktur ve herkes o kullanıcı olarak oturum açabilir. Bu ciddi bir güvenlik açığıdır.

3. UID (User ID): Kullanıcının sayısal kimliği. root her zaman 0 UID’ye sahiptir. 1-999 arası genellikle sistem kullanıcıları için ayrılmıştır. Normal kullanıcılar genellikle 1000’den başlar.

4. GID (Group ID): Kullanıcının birincil grubunun sayısal kimliği. Bu değer /etc/group dosyasındaki bir gruba karşılık gelir.

5. GECOS alanı: Kullanıcı hakkında ek bilgiler. Genellikle tam ad, telefon numarası gibi bilgiler içerir. Virgülle ayrılmış birden fazla değer olabilir.

6. Home dizini: Kullanıcının ev dizini. Oturum açıldığında bu dizine gidilir.

7. Shell: Kullanıcının varsayılan kabuğu. /bin/bash, /bin/zsh gibi değerler gerçek oturumlar için kullanılır. /usr/sbin/nologin veya /bin/false değerleri, kullanıcının sisteme interaktif olarak giriş yapamaması gerektiği anlamına gelir.

# Belirli bir kullanıcının bilgilerini görmek için:
grep "ahmet" /etc/passwd

# UID'ye göre kullanıcı bulmak:
awk -F: '$3 >= 1000 && $3 != 65534 {print $1, $3}' /etc/passwd

# Shell olarak nologin kullanan sistem kullanıcılarını listele:
grep "nologin|/bin/false" /etc/passwd | cut -d: -f1

/etc/shadow Dosyası Nedir?

/etc/shadow dosyası, kullanıcı şifrelerinin hash’lenmiş hallerini ve şifre politikası bilgilerini barındırır. Bu dosya güvenlik nedeniyle kısıtlı erişime sahiptir:

# Dosya izinlerini kontrol et:
ls -la /etc/shadow
# Çıktı: -rw-r----- 1 root shadow 1234 ...

Yalnızca root ve shadow grubunun üyeleri bu dosyayı okuyabilir. Normal bir kullanıcı olarak bu dosyayı okumaya çalışırsanız “Permission denied” hatası alırsınız.

Shadow Dosyasının Yapısı

sudo cat /etc/shadow

Örnek bir çıktı:

root:$6$xyz123$hashedpassword...:19000:0:99999:7:::
ahmet:$6$abc456$anotherhash...:19500:0:90:14:30:20000:
daemon:*:18000:0:99999:7:::
mysql:!:19200:0:99999:7:::

Bu dosyada da 9 alan bulunur ve iki nokta üst üste ile ayrılır:

1. Kullanıcı adı: /etc/passwd ile eşleşmeli.

2. Şifre hash’i: Birkaç farklı değer alabilir:

  • $id$salt$hash formatında gerçek hash
  • * veya ! karakteri, hesabın kilitli olduğunu gösterir
  • Boş değer, şifresiz giriş anlamına gelir (tehlikeli!)

Hash tipini belirleyen $id$ kısmı:

  • $1$ MD5 (eski, güvensiz)
  • $5$ SHA-256
  • $6$ SHA-512 (modern sistemlerde yaygın)
  • $y$ yescrypt (modern Ubuntu/Debian’larda)

3. Son şifre değişiklik tarihi: 1 Ocak 1970’ten bu yana geçen gün sayısı. 19500 değeri, 1 Ocak 1970’ten 19500 gün sonrasına karşılık gelir.

4. Minimum şifre yaşı: Şifre değiştirildikten sonra en az kaç gün beklenilmesi gerektiği. 0 değeri, hemen değiştirilebileceği anlamına gelir.

5. Maksimum şifre yaşı: Şifrenin kaç günde bir yenilenmesi gerektiği. 99999 pratikte sonsuz demektir.

6. Uyarı süresi: Şifrenin sona ermesinden kaç gün önce kullanıcının uyarılacağı.

7. Hesap devre dışı bırakma süresi: Şifre süresi dolduktan kaç gün sonra hesabın kilitleneleceği.

8. Hesap sona erme tarihi: 1 Ocak 1970’ten bu yana geçen gün olarak hesap sona erme tarihi. Boşsa hesap sona ermez.

9. Rezerve alan: Gelecekte kullanım için ayrılmış, şu an boş.

Gerçek Dünya Senaryoları

Senaryo 1: Yeni Kullanıcı Oluşturma ve Kontrol

Bir şirkette yeni bir developer geldi ve ona sistem erişimi vermeniz gerekiyor:

# Kullanıcı oluştur
sudo useradd -m -s /bin/bash -c "Mehmet Demir, Backend Dev" mehmet

# Şifre belirle
sudo passwd mehmet

# Oluşturulan kullanıcıyı passwd dosyasında kontrol et
grep "mehmet" /etc/passwd
# Çıktı: mehmet:x:1001:1001:Mehmet Demir, Backend Dev:/home/mehmet:/bin/bash

# Shadow dosyasındaki durumu kontrol et
sudo grep "mehmet" /etc/shadow
# Çıktı: mehmet:$6$...:19500:0:99999:7:::

Senaryo 2: Şifre Politikası Uygulama

Güvenlik politikası gereği kullanıcıların şifrelerini 90 günde bir değiştirmesini ve değiştirmeden 14 gün önce uyarı almasını istiyorsunuz:

# Belirli bir kullanıcı için şifre politikası ayarla
sudo chage -M 90 -W 14 -m 1 mehmet

# Ayarları kontrol et
sudo chage -l mehmet

chage komutunun parametreleri:

  • -M: Maksimum şifre yaşı (gün)
  • -m: Minimum şifre yaşı (gün)
  • -W: Sona ermeden önce uyarı başlangıcı (gün)
  • -I: Sona ermeden sonra hesap kilitleme süresi (gün)
  • -E: Hesap sona erme tarihi (YYYY-MM-DD formatında)
  • -l: Mevcut ayarları listele

Senaryo 3: Hesap Kilitleme ve Açma

Bir çalışan uzun süre izne çıkıyor ve hesabını geçici olarak kapatmanız gerekiyor:

# Hesabı kilitle (shadow dosyasındaki hash'in önüne ! ekler)
sudo usermod -L mehmet
# veya
sudo passwd -l mehmet

# Kilitli hesabı kontrol et
sudo grep "mehmet" /etc/shadow
# Çıktı: mehmet:!$6$...:19500:...

# Hesabı tekrar aç
sudo usermod -U mehmet
# veya
sudo passwd -u mehmet

Senaryo 4: Servis Hesabı Oluşturma

Bir uygulama için sistem hesabı oluşturmanız gerekiyor, ancak bu hesabın interaktif oturum açamaması lazım:

# Sistem kullanıcısı oluştur (UID 999 ve altında)
sudo useradd -r -s /usr/sbin/nologin -d /opt/myapp -c "MyApp Service User" myapp

# Kontrol et
grep "myapp" /etc/passwd
# Çıktı: myapp:x:998:998:MyApp Service User:/opt/myapp:/usr/sbin/nologin

# Bu kullanıcıya sudo ile geçmeye çalışalım (başarısız olmalı)
sudo -u myapp bash
# Hata: This account is currently not available.

Dosya Bütünlüğü ve Güvenlik Kontrolleri

Bir sysadmin olarak bu dosyaları düzenli olarak kontrol etmek güvenlik açısından önemlidir. İşte dikkat etmeniz gereken noktalar:

UID 0 Olan Kullanıcıları Kontrol Etme

Sistemde root dışında UID 0 olan bir kullanıcı varsa bu ciddi bir güvenlik sorunudur:

# UID 0 olan tüm kullanıcıları listele
awk -F: '($3 == "0") {print $1}' /etc/passwd

# Yalnızca "root" çıktısını görmelisiniz.
# Başka bir kullanıcı görürseniz hemen araştırın!

Şifresiz Hesapları Bulma

# Passwd alanı boş olan hesapları bul (shadow kullanılıyorsa)
sudo awk -F: '($2 == "") {print $1}' /etc/shadow

# Passwd dosyasında x yerine başka değer olan hesapları bul
awk -F: '($2 != "x" && $2 != "") {print $1}' /etc/passwd

Geçersiz Shell Tanımlamalarını Kontrol Etme

# /etc/shells dosyasında olmayan shell'lere sahip kullanıcıları bul
while IFS=: read -r user pass uid gid gecos home shell; do
    if [ -n "$shell" ] && [ "$shell" != "/usr/sbin/nologin" ] && [ "$shell" != "/bin/false" ]; then
        if ! grep -qx "$shell" /etc/shells 2>/dev/null; then
            echo "Geçersiz shell: $user -> $shell"
        fi
    fi
done < /etc/passwd

Süresi Geçmiş Hesapları Bulma

# Şifresi süresi dolmuş hesapları listele
sudo awk -F: '{
    if ($5 != "" && $5 != "99999" && $5 != "0") {
        today = int(systime()/86400)
        last_change = $3
        max_age = $5
        if (today > last_change + max_age) {
            print $1, "- Şifre süresi dolmuş!"
        }
    }
}' /etc/shadow

Manuel Düzenleme: vipw Komutu

/etc/passwd dosyasını doğrudan vi veya nano ile açıp düzenlememek gerekir. Bunun yerine vipw komutunu kullanın. Bu komut dosyayı kilitleyerek eş zamanlı düzenlemeleri engeller ve sözdizimi kontrolü yapar:

# passwd dosyasını güvenli şekilde düzenle
sudo vipw

# shadow dosyasını güvenli şekilde düzenle
sudo vipw -s

# group dosyasını güvenli şekilde düzenle
sudo vigr

Eğer vipw kullanmadan doğrudan dosyayı bozarsanız ve sisteme giriş yapamaz hale gelirseniz, recovery mode’a geçip onarım yapmanız gerekebilir. Bu yüzden değişiklik yapmadan önce mutlaka yedek alın:

# Değişiklik yapmadan önce yedek al
sudo cp /etc/passwd /etc/passwd.bak.$(date +%Y%m%d)
sudo cp /etc/shadow /etc/shadow.bak.$(date +%Y%m%d)

getent Komutu ile Kullanıcı Sorgulama

/etc/passwd dosyasını doğrudan okumak yerine getent komutunu kullanmak daha iyi bir pratiktir. Bu komut hem yerel dosyaları hem de LDAP, NIS gibi uzak dizin servislerini sorgular:

# Tüm kullanıcıları listele
getent passwd

# Belirli kullanıcıyı sorgula
getent passwd ahmet

# Belirli UID'yi sorgula
getent passwd 1000

# Sadece kullanıcı adlarını listele
getent passwd | cut -d: -f1 | sort

pwck ve grpck ile Dosya Doğrulama

pwck komutu /etc/passwd ve /etc/shadow dosyalarının tutarlılığını kontrol eder:

# Passwd ve shadow dosyalarını doğrula
sudo pwck

# Salt okunur modda kontrol (değişiklik yapmadan)
sudo pwck -r

pwck şunları kontrol eder:

  • Her girişin doğru sayıda alan içerip içermediği
  • UID ve GID değerlerinin geçerliliği
  • Home dizinlerinin var olup olmadığı
  • Shell’lerin geçerli olup olmadığı
  • passwd ve shadow dosyaları arasındaki tutarlılık

Yaygın Sorunlar ve Çözümleri

Sorun: Kullanıcı oturum açamıyor ama şifre doğru

# Hesabın kilitli olup olmadığını kontrol et
sudo passwd -S ahmet
# L: Locked, P: Password set, NP: No Password

# Shadow dosyasında ! işareti var mı?
sudo grep "ahmet" /etc/shadow | cut -d: -f2 | head -c1

Sorun: “This account is currently not available” hatası

Bu hata, kullanıcının shell’i /usr/sbin/nologin olarak ayarlandığında çıkar. Eğer servis hesabı değilse düzeltin:

sudo usermod -s /bin/bash ahmet

Sorun: Home dizini yok

# Home dizinini oluştur ve izinleri ayarla
sudo mkhomedir_helper ahmet
# veya
sudo mkdir -p /home/ahmet && sudo chown ahmet:ahmet /home/ahmet && sudo chmod 700 /home/ahmet

Toplu İşlemler İçin Pratik Script

Sistemdeki tüm normal kullanıcıları ve hesap durumlarını özetleyen bir script:

#!/bin/bash
echo "=== Kullanıcı Hesap Özeti ==="
echo ""
awk -F: '$3 >= 1000 && $3 != 65534 {print $1}' /etc/passwd | while read user; do
    status=$(sudo passwd -S "$user" 2>/dev/null | awk '{print $2}')
    home=$(grep "^$user:" /etc/passwd | cut -d: -f6)
    shell=$(grep "^$user:" /etc/passwd | cut -d: -f7)
    echo "Kullanici: $user | Durum: $status | Home: $home | Shell: $shell"
done

Sonuç

/etc/passwd ve /etc/shadow dosyaları, Linux kullanıcı yönetiminin temelini oluşturan iki kritik bileşendir. Bir sysadmin olarak bu dosyaların yapısını ve birbirleriyle ilişkisini anlamak, hem günlük operasyonlarda hem de güvenlik denetimlerinde size büyük avantaj sağlar.

Özetlemek gerekirse, /etc/passwd tüm kullanıcı hesaplarının meta bilgilerini tutar ve herkes tarafından okunabilir. /etc/shadow ise hassas şifre hash bilgilerini ve politika ayarlarını barındırır, kısıtlı erişimlidir. Bu dosyaları hiçbir zaman doğrudan text editörle düzenlemeyin, bunun yerine vipw, usermod, chage gibi araçları tercih edin.

Düzenli güvenlik denetimleri kapsamında UID 0 olan yetkisiz kullanıcıları, şifresiz hesapları ve süresi dolmuş hesapları periyodik olarak kontrol etmek iyi bir alışkanlıktır. Bu dosyaları anlamak, ilerleyen konularda PAM (Pluggable Authentication Modules), LDAP entegrasyonu ve sudo yönetimi gibi konuları kavramanızı da kolaylaştıracaktır.

Yorum yapın