Linuxta Dosya ve Klasor Izinleri


The File Mode

Dosya modu, uc farkli izin barindiri. User, group ve others. Her biri icin de uc farkli moda sahiptir: Read, Write ve Execute. Ornek olarak sistemdeki hosts dosyasinin izinlerini inceleyelim:

:~/lnx$ ls -l /etc/hosts
-rw-r--r-- 1 root root 539 Jan 16 05:39 /etc/hosts

Ilk karakter listelenen ogenin tipini belirtir. Bunlar:

- : dosya
d : directory
p : named pipe
l : symlink
b : block device
c : character device
s : socket

Bu karakterden sonra 3 karakterden olusan 3 obek bulunur. Her bir obek aslinda read, write ve execute yetkilerini temsil eder. Eger yetki var ise karakteri gosterilir, yetki yok ise (-) yani dash gosterilir. Okuma yazma yetkisi olan ama execute yetkisi olmayan bir obek su sekilde gorunecektir:

rw-

Bu sekilde 3 karakterle gostermek yerine bir sayi ile de gosterilebilir. Her bir yertkiyi bir bit olarak dusunursek, yukaridaki obek su sekle donusur:

110

Bu da sayi olarak 0 + 1*2 + 1*2^2 = 6 olur. 

Bu sekilde 3 farkli obek var demistirk. Birincisi, bu dosyanin sahibinin (owner) sahip oldugu yetkileri tanimliyor. Ikincisi bu dosyanin ait oldugu gruba dahil kullanicilarin yetkileri. Ucuncusu ise diger herkes, yani dosya sahibi ve dosya grubuna dahil olan kullanicilar disinda kalanlarin sahip oldugu yetkiler. Her bir obegi bir sayi ile temsil edebildigimize gore, tum yetki semasini 3 haneli bir sayi ile gosterbiliriz. Kullanici, grup ve digerlerinin ayni yetkilere sahip oldugunu varsayalim. Bu durumda her uc obek de 6 degerine sahip olur ve sonuc olarak dosya yetki semasi:

666

seklinde ifade edilebilir. Suradan da bunu gorebiliriz

Bu sayede meshur 777 (herkese tum yetkiler) ve 770 (sadece dosyas sahibi ve gruba tum yetkiler digerlerine hicbir yetki) chmod degerlerinin de anlamlari daha belirginlesmis oluyor. Izin semasini ifade ettigimiz bu sayiya octal sayi diyorlar. Cunku her obek 3 farkli izin icerdigi icin 3 bitten olusuyor. Bu da toplamda en fazla 7 yapiyor. Yani ortaya cikan 770 sayisi 8'lik sistemde gibi dusunulebilir. 

Bu octal degeri linux bize stat komutu ile gosterebilir:

$ stat /etc/hosts
  File: /etc/hosts
  Size: 539             Blocks: 2          IO Block: 512    regular file
Device: 2h/2d   Inode: 281474977035151  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-08-04 23:38:16.000000000 +0200
Modify: 2021-01-16 05:39:15.283311000 +0100
Change: 2021-01-16 05:39:15.283311000 +0100
 Birth: -

Izin degistirme
Izinleri degistirmek icin chmod komtunu kullaniyoruz. Ornegimize bir dosya olusturark basyalayim. 

$ touch deneme-dosya

Simdi bunun izinlerine ls -la ile bakacak olursak, kullanicinin execute yetkisi olmadini goruruz. Sadece kullaniciya execute yetkisi verelim:

$ chmod u+x deneme-dosya

Tekrar izinleri kontrol edersek, yetkinin geldigini goruyoruz. Eger u ile sadece user belirtmezsek tum herese execute yetkisi verecektir. Peki dosyanin sadece kullaniciya ozel olmasini istersek:

$ chmod 700 deneme-dosya

seklinde sadece kullaniciya read,write execute yetkileri verip diger herekese hicbir yetki vermedik. 

Umask ile varsayilan dosya izinleri
Bir dosya olusturdugumuz zaman sahip olacagi default yetkileri umask degeri belirler. Ama tersten. Yani default olarak bir dosyanin yetkisi 666 ve bir klasorun ise 777'dir. Ama umask degeri bu default yetki degerinden cikartilir. 

Benim sistemimde umask deferi 0022 degerine sahip suanda. Bunu umask komutu ile gorebiliriz. Ve ben bir dosya olsutrudugum zaman, izin degeri 0644 oluyor. Bu da demek oluyor ki sistem 0666 degerinden 0022 degerini cikartarak, default dosya izni olarak 0644 degerini atiyor.

umask degerini degistirmek de mumkun:

$ umask 000
$ touch deli-fisek
$ stat -c %a deli-fisek
666

Bu sefer dosyanin 644 ile degil de 666 (default) izinler ile olusturuldugunu goruyoruz. Benzer sekilde bir klasor olusturursak da 777 ile olusturuldugunu gorecegiz. Ayni sekilde, umask degerini 077 atayarak olusturdugumuz tum dosyalarin default olarak kullaniciya ozel olmasini saglayabiliriz. 

Ozel izinler

Sticky bit
Bir kullanicinin bir klasorden dosya silebilmesi icin o klasor uzerinde yazma (write) hakkinin olmasi yeterli. Ama bu klasor uzerinde stick bit set edilmis ise, kullanicilar sadece kendi sahip olduklari dosyalari silebilirler.  

Default olarak /tmp ve /var/tmp klasorlerine kullanilmaktadir. Genel olarak paylasilan klasorlerde uygulanmasi mantikli olacaktir. Sticky bit set etmek icin:

$ chmod o+t /paylasilan-klasor-cok-da-ellesme

veya, 

$ chmod 1777 /paylasilan-klasor-cok-da-ellesme

Bu sayede, stat komutunun bize gosterdigi octal degerlerin basinda neden hep bir sifir fazla oldugunu da anlamis oluyoruz. Bu bastaki sifir stickbit'i temsil ediyor. Bunu dogrulamak icin, stick bit'e sahip oldugu iddia edilen /tmp klasorunu inceleyelim:

$ stat -c %a /tmp
1777

Mukemmel bir tespit. 

SGID bit (Set groupId bit)
Hem klasorlere hem de dosyalara uygulanabilir. 

Bir klasor uzerinde tanimlandigi zaman, yeni olusturulan tum doslarin grubu, bu klasorun grubu olacaktir. Normalde bu bit set edilmemis olsa, her olusturulan yeni dosya, dosyayi olusturan kullanicinin primary grubuna sahip olacakti. Bu ozellik sayesinde kullanicilar arasinda dosya paylasimi saglanabilir. Ornek olarak bir apache web serverin rook klasorunu uzerinde olusturulan tum dosyalarin apache isimli grup tarafindan own edilmesini istiyoruz:

Bende apache kurulu degil ama kolpadan bir root klasoru olsuturuyorum,

$ sudo mkdir -p /var/www/html

Icerisinde deneme olarak bir dosya olusturuyorum. 

$ touch index.html

Simdi bu dosyayi incelersek group owener olarak root gozukuyor. Ancak bu klasorun group owneri olarak apache (boyle bir grup da yoktu, sudo groupadd apache komutu ile olsuturulabilir) atayip, daha sonra set group id'yi set edince,

$  sudo chgrp apache /var/www/html/
$ sudo chmod g+s /var/www/html/
$ sudo touch index.js

Bu sefer gidip index.js'yi incelersek, group owener olarak apache goruyoruz. Peki bu bize ne saglayacak? Mesela sadece apache grubu icin bu klasore okuma yetkisi verebiliriz. 

Eger bir executable uzerinde tanimlanirsa, bu executable dosyanin grubunun security contextinde calisacaktir. Yani bu executable'i calistiran kullanicinin grubunun yetkileri yerine dosyanin grubunun yetkileri kullanilir.

SetgroupId, executable uzerinde de tanimlanabilir demistirk. Halihazirda sistemde tanimli olan bir ornek ise, bsd-write uygulamasidir. 

$ ls -la $(which bsd-write)
-rwxr-sr-x 1 root tty 14488 Mar 30  2020 /usr/bin/bsd-write

Burada grup yetki obeginde bir s harfi ile temsil edilmistir. Yani bu uygulamayi kim calistirirsa calistirsin, tty group yetkileri ile calisacaktir. 

SUID bit (Set userId bit)
Bir executable uzerinde tanimlandiginda, executable her zaman dosyanin sahibi olan kullanicini security contextinde calistirilir. Ornegin bir executable'i root kullanicisi olsuturmus ise ve de suid set edilmis ise, kim calistirirsa calistirsin, bu executable root yetkileri ile calisacaktir. 

Buna ornek olarak da passwd programi verilebilir. Programin yetki semasini goruntuleyelim:

$ ls -la /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 May 28  2020 /usr/bin/passwd

Bu programi kim calistirirsa calistirsin, root kullanicisi permisionlari ile calisacaktir. 

Dosya tiplerini ve yetkileri test etme
Simdiye kadar hep manuel olarak elle ve gozle kontrol ettik. Bunu programsal olarak da test programi ile yapabiliriz. Oncelikle oge tipini kontrol edelim.

$ test -f /etc/hosts && echo "bu bir dosya"
bu bir dosya

-f parametresi ile dosya olup olmadigini test ediyoruz. Benzer sekilde -d ile directory olup olmadigini veya postun en basinda verdigimiz diger oge tiplerini de kullanabiliriz. Eger test basarili olamazsa, program devam etmeyecegi icin pipeline'daki ikinci kisma gecmez ve ekrana `bu bir dosya` yazmaz. 

$ test -f /etc && echo "bu bir dosya"
$

birsey yazilmadigini goruyoruz.

SGID bit'inin set olup olmadigini ise -g ile test ediyoruz. 

$ test -g /usr/bin/bsd-write && echo "SGID Bit set edilmis"
$ SGIB Bit set edilmis

SUID ise -u ile test edilebiliyor. Bir diger kullanim sekli ise test komutunu kullanmadan, koseli parantezler ile ayni sonuca ulasabiliriz. 

$ [ -g /usr/bin/bsd-write ] && echo "sgid var dewam"
$ sgid var dewam

seklinde. man test ile daha fazla bilgi alabilirsiniz.

Ozet
- basic mode USER / GROUP / OTHERS   wrx
- stat  ile yetki semasini goruntuleme stat -c %a /etc/hosts (kucuk a octal form, buyuk a sembolik form)
- ozel izinler Stickbit . sgid, suid 
- dosya tipi ve izinleri test programi ile test etme 

Yorumlar

Bu blogdaki popüler yayınlar

Python'da Multithreading ve Multiprocessing

Threat Modeling 1

Encoding / Decoding