Bu yazıda anlatacaklarım GNU/Linux için olacak ama hepsi UNIX benzeri işletim sistemleri için geçerli olacaktır. Erişim hakları konusu her ne kadar işletim sistemindeki araçlarla ve çekirdeğin desteğiyle ilgili olsa da kullanılan dosya sisteminin buna izin veriyor olması gerekir. Temel erişim haklarından bahsedince bu konuya geri döneceğiz.
GNU/Linux işletim sistemleri çok kullanıcılı ve çok görevli işletim sistemleridir. Kullanıcı yönetimi ve neden işletim sisteminde bu kadar fazla kullanıcı olduğu başka bir konuşmanın konusu olacak kapsamlı bir konudur. Sistemde bulunan her dosya ve dizinin mutlaka sahibi bir kullanıcı ve ait olduğu bir grup olur. Yani bir dosya olamaz ki sahibi veya ait olduğu grubu belli olmasın.
GNU/Linux için üç temel ve üç de gelişmiş erişim hakkından bahsedebiliriz. Temel erişim hakları okuma (r), yazma (w) ve çalıştırma (x) haklarıdır. Şimdi örnek bir dosya için bu erişim haklarını görelim:
$ ls -l /bin/ls -rwxr-xr-x 1 root root 142144 Eyl 5 2019 /bin/ls
Burada ilk sütunda 10 karakterlik bir bilgi görüyoruz. İlk karakter erişim hakkıyla değil de listelenen şeyin ne olduğuyla ilgili bir bilgi veriyor bize. Bu bilgi şunlar olabilir:
- - Ordinary or Regular File
- d Directory
- c Character special file
- b Block special file
- l Symbolic link
- p Named pipe
- s Socket
ls komutu listelediği şeyin tipini nasıl ayırt ediyor konusu ayrıca öğrenilmeye değer bir konudur.
İlk karakteri böylece geçtiğimize göre kalan 9 karaktere bakalım. Bunları üçerli gruplar halinde inceleyeceğiz.
$ ls -l /bin/ls -rwxr-xr-x 1 root root 142144 Eyl 5 2019 /bin/ls
İlk üç karakter ilgili dosyanın sahibi olan root kullanıcısının haklarını belirler. Bu örnekte dosyanın sahibi (u) dosyayı okuyabilir, dosyaya yazabilir ve dosyayı değiştirebilir. Dosyanın ait olduğu root grubunun (g) üyeleri dosyayı okuyabilir ve çalıştırabilir ama dosyada değişiklik yapamazlar. Dosyanın sahibi olmayan ve dosyanın ait olduğu gruba üye olmayan diğer kullanıcılar (o) ise dosyayı okuyabilir ve çalıştırabilirler ama değişiklik yapamazlar. Demek ki erişim haklarından bir karakter bulunmuyorsa o erişim hakkına sahip olunmadığını anlamamız gerekir.
İşletim sistemi üzerinde ancak sahip olduğumuz hakları değiştirebilir ve paylaşabiliriz. Yani bir dosyanın sahibi biz değilsek onun sahipliğini başka bir kullanıcıya veremeyiz. Benzer şekilde erişimimiz olmayan bir dosyanın erişim haklarını da değiştiremeyiz. Bizim /tmp dizini altında oluşturduğumuz testfile dosyası için şu işlemleri yapalım:
- Dosyanın sahibine çalıştırma izni verelim
chmod u+x /tmp/testfile
- Dosyanın ait olduğu gruptan okuma iznini alalım
chmod g-r /tmp/testfile
- Dosyanın sahibi ve diğerlerinden çalıştırma iznini alalım
chmod uo-x /tmp/testfile
Bu işlemleri şöyle tanımlamak da mümkün:
- Okuma hakkı için 4 (2 üzeri 2)
- Yazma hakkı için 2 (2 üzeri 1)
- Çalıştırma hakkı için 1 (2 üzeri 0)
Bir dosyayı herkes okuyabilsin, sahibi dışında kimse üzerine yazamasın ve çalıştıramasın dediğimizde şu komutu çalıştırmalıyız:
$chmod 744 /tmp/testfile
Eğer bir dosyaya 777 erişim hakkını verirsek herkes o dosyayı okuyabilir, üzerine yazabilir ve çalıştırabilir. Hiçbir dosyaya veya dizine böyle bir erişim hakkını vermememiz gerekir. İleride benzer bir istisnasını görüp onun için ayrı bir erişim hakkı tanımlayacağız ama bir dosya veya dizine 777 erişim hakkını verirsek onu gören ilk kullanıcı onu siler. Bu doğanın kanunlarından biridir.
Peki oluşturduğumuz dosya ve dizinler hangi kurala göre erişim haklarına sahip oluyorlar? Bunu belirleyen şey umask değeridir. Ubuntu 20.04 üzerinde umask komutunu çalıştıralım.
$ umask
0002
Şimdi bir dosya ve dizin oluşturup erişim haklarına bakalım. Dosya için 664, dizin için 775 erişim haklarıyla oluşturulduğunu göreceğiz. Demek ki dosya oluştururken umask değerini 666’dan, dizin oluştururken 777’den çıkartarak erişim hakları belirleniyor.
Yazının başlangıcında dosya sisteminin de bu yeterliliklere sahip olması gerektiğini söylemiştim. Erişebildiğiniz herhangi bir vfat dosya sistemi ile biçimlendirilmiş disk üzerinde dosya oluşturup onun erişim haklarını değiştirmeyi denediğinizde bunu yapamadığınızı göreceksiniz. Bunun nedeni vfat’in erişim haklarını düzenlemeye imkan vermemesidir.
Buraya kadar sanki işletim sisteminde gerek duyulan bütün erişim hakları problemleri çözülmüş gibi gelebilir. Şimdi önce yeni bir ihtiyacı ve onun için üretilmiş yeni çözümü görelim:
/etc/shadow dosyasında her kullanıcı için birer satır bulunur. Bu satırların ikinci sütununda kullanıcıların parolalarının gölgelenmiş halleri bulunur. Bu dosyanın erişim hakları şöyledir:
-rw-r----- 1 root shadow 1,7K Ara 17 20:20 /etc/shadow
Görüyorum ki benim yetkili kullanıcı olmayan bir kullanıcıyla bu dosyada değil değişiklik yapmam, dosyayı okumam bile mümkün değil. Diğer yandan biliyoruz ki her kullanıcı kendi parolasını değiştirebiliyor. Bir kullanıcı kendi parolasını passwd komutuyla değiştirebilir. Bu komutun erişim haklarına bakalım.
-rwsr-xr-x 1 root root 67K May 28 2020 /usr/bin/passwd
Şimdilik dördüncü karakter olarak x yerine s olmasına takılmayalım. Biliyoruz ki süreçler kendilerini çalıştıran kullanıcıların yetkileriyle çalışırlar. Yani bir kullanıcı hangi dosyalara yazabiliyorsa onun çalıştırdığı süreçler de ancak o dosyalara yazabilirler. Peki nasıl oluyor da benim yazamadığım bir dosyaya benim çalıştırdığım bir süreç (/usr/bin/passwd) yazabiliyor? İşte bunu sağlayan erişim hakkına SUID bit deniyor. Bir dosyayı kim çalıştırırsa çalıştırsın sanki onu sahibi çalıştırmış gibi davransın isteniyorsa ona aşağıdaki gibi bir erişim hakkı vermek gerekir.
$ chmod u+s /tmp/testfile
Burada sıkça karıştırılan şey bu erişim hakkının ancak root kullanıcısı tarafından verilebileceği konusudur. Bu komutla her kullanıcı SUID bit erişim yetkisini bir dosyaya verebilir ama böyle yaparak sadece dosya üzerindeki kendi yetkilerini onu çalıştırma hakkı olan diğer kullanıcılara vermiş olacağını aklımızdan çıkarmamak gerekir. Bir dosyayı kim çalıştırırsa çalıştırsın sanki onun ait olduğu grubun bir üyesiymiş gibi çalıştırmasını istersek ona aşağıdaki komutla SGID bit erişim yetkisini vermiş oluruz.
$ chmod g+s /tmp/testfile
Yukarıda bir dosyaya veya dizine 777 erişim haklarını vermemek gerektiğini, böyle bir erişim hakkı verildiğinde onu ilk gören kullanıcının sileceğini söylemiştim. /tmp dizini tam da böyle bir erişim hakkına ihtiyaç duyar; bu dizine bütün kullanıcılar (oturum açma izni olmayan sistem kullanıcılar dahil) yazabilmelidir. Bizim istediğimiz şey bu dizine her kullanıcının yazabilmesi ama kullanıcıların sadece kendi oluşturdukları dosyaları değiştirebilmesidir. Bu erişim hakkı şimdiye kadar bahsettiğimiz erişim haklarıyla düzenlenemez. Bunu sticky bit erişim yetkisiyle aşağıdaki gibi düzenleyebiliriz.
$ chmod o+t /tmp/testdizin
Sticky bit erişim hakkı verilmiş bir dizine bütün kullanıcılar yazabilir ama sadece kendi sahip oldukları dosyaları değiştirebilirler. Bazı kullanıcıların bazı dosyaları sanki root kullanıcısı gibi çalıştırmalarını sağlayan sudo aracı da mevcut olmakla birlikte onu erişim hakları arasında sınıflamamak daha doğru olacaktır. Konunun daha iyi anlaşılabilmesi için aşağıdaki sorulara cevap vermeye çalışmak iyi bir pratik olacaktır.
- Okuyamadığınız bir dosyaya yazmanız nasıl mümkün olabilir? Anlamlı bir örnek verebilir misiniz?
- Biliyoruz ki dizinler değil dosyalar çalıştırılabilir. Bir dizinin çalıştırılması ne anlama gelir?
- umask değeri nasıl değiştiriliyor? Nasıl kalıcı hale getiriliyor?
- Bir dizine SUID bit erişim hakkı verilebilir mi? Verilebilirse bu ne anlama gelir?
- Bir dizine SGID bit erişim hakkı verilebilir mi? Verilebilirse bu ne anlama gelir?
- Sticky bit erişim hakkı bir dosyaya verilebilir mi? Verilebilirse bu ne anlama gelir?
Yazıda bahsedilen konuyu dinlemek isteyen olursa diyerek bağlantısını bırakıyorum.