• Linux Sistem Yönetimi | LKD #5

    Kullanıcı Yönetimi

    Linux sistemlerde yalnızca bizim gibi sisteme giriş yapan kullanıcılar bulunmaz. Sistemde çalışan servisler ve bazı uygulamalar için de ayrı kullanıcı hesapları oluşturulabilir. Sistemde tanımlı kullanıcı hesaplarını /etc/passwd dosyası üzerinden görebiliriz.

    Bu dosyanın her satırında bir kullanıcı hesabına ait bilgiler : ile ayrılırlar.

    Buradaki alanların anlamları şöyledir:

    AlanAnlamı
    mehmetKullanıcı adı
    xParola bilgisinin /etc/shadow dosyasında tutulduğunu belirtir
    1000Kullanıcının UID (user ıd) numarası
    1000Kullanıcının birincil grubunun GID ( grup ıd) numarası
    mehmetKullanıcı hakkında açıklama alanı
    /home/mehmetKullanıcının ev dizini
    /bin/bashKullanıcı giriş yaptığında çalıştırılacak kabuk

    Not: Eskiden parola hash’leri de burada tutulduğu için dosyanın adı passwd idi. Ancak günümüzde /etc/passwd dosyasının sistemdeki kullanıcılar tarafından okunabilmesi gerektiğinden parola hash’lerinin burada tutulması güvenli değil. Bu nedenle parola bilgileri yalnızca yetkili kullanıcıların okuyabildiği /etc/shadow dosyasına taşındı. /etc/passwd içerisindeki x karakteri de geriye dönük uyumluluk için saklanmaya devam ediyor.

    Not: Nginx, PostgreSQL veya SSH gibi servislerin her biri sistemde farklı kullanıcılarla çalışabilir. Bunun sebebi servise yalnızca ihtiyaç duyduğu yetkileri vermek ve servisin sistemin kalanına verebileceği zararı sınırlandırmaktır.

    Örneğin Nginx üzerinde bir güvenlik açığı bulunduğunu düşünelim. Nginx doğrudan root kullanıcısıyla çalışıyorsa açığı kullanan kişi de çok geniş yetkilere sahip olabilir. Servis yalnızca kendisine ait dosyalara erişebilen sınırlı bir kullanıcıyla çalışıyorsa saldırganın erişebileceği alan da sınırlandırılmış olur.

    Linux’ta her kullanıcıya özel bir id tahsis edilir. Linux, kullanıcıları kendi içerisinde kullanıcı adlarıyla değil UID adı verilen sayısal kimliklerle takip eder. Gruplar için de GID adı verilen sayısal kimlikler kullanılır. id kullanici_adi ile bunları görebiliriz.

    Çıktımız şöyle olacaktır:

    uid=1000(mehmet) gid=1000(mehmet) groups=1000(mehmet),4(adm),24(cdrom), 27(sudo),30(dip),46(plugdev),101(lxd)

    burada kullanıcının bulunduğu gruplar yer alır.

    Kullanıcı adları bizim sistemi daha rahat kullanabilmemiz içindir. Dosyanın sahibi gibi bilgiler dosya sisteminde sayısal UID ve GID değerleriyle tutulur. Komutlar bu numaraları /etc/passwd ve /etc/group dosyalarındaki adlarla eşleştirerek bize kullanıcı ve grup adı şeklinde gösterir.

    Bu yüzden bir kullanıcıyı sildiğimizde ona ait dosyalar kendiliğinden silinmez ve sistem artık ilgili UID numarasını bir kullanıcı adıyla eşleştiremediği için dosyanın sahibi kısmında isim yerine doğrudan UID numarasını görürüz. Örneğin, duman kullanıcısının oluşturduğu bir dosya duruyorken duman kullanıcısını sildiğimde,

    duman dizininin sahipliği ve grubunun id şeklinde göründüğü görürüz.

    Not: Daha sonra aynı UID numarası başka bir kullanıcıya verilirse eski dosyalar yeni oluşturulan kullanıcıya aitmiş gibi görünebilir. Çünkü dosya sistemi isme değil id numarasına bakarak hareket eder. Aynı şekilde dosyayı başka bir bilgisayara taşırsak dosya karşı tarafta eşleşen id’nin sahipliğine girer.

    Kullanıcıların UID numaraları olduğu gibi grupların da GID numaraları bulunur. Sistemde tanımlı gruplar /etc/group dosyasında yer alır.

    Bu dosyada da alanlar : ile ayrılırlar. İlk sütun grup adını, ikinci sütun /etc/gshadow dosyasına taşınan parola alanlarını, üçüncü sütun id numaralarını dördüncü sütun ise o gruba sonradan üye olan kişileri gösterir.

    Bir kullanıcının dahil olduğu grupları daha kolay görmek için groups veya id komutunu kullanabiliriz.

    Not: Kullanıcıların ev dizinlerinin illaki /home/kullanici_adi şeklinde olması gerekmez, istersek ev dizinlerinin konumlarını değiştirebiliriz.

    Parolaların hash’li biçimde saklandığı /etc/shadow dosyası,

    Burada bazı kullanıcıların uzun bir parola hash’i varken bazı hesaplarda ! veya * gibi karakterler vardır. Bunun sebebi kullanıcının parola ile oturum açmasının engellenmiş olmasıdır. * hesaba hiçbir zaman parola atanmadığını, ! ise hesabın kilitlendiğini gösterir. Yanlarında uzunca bir hash’e sahip olanlarsa şifre atanılan kullanıcıları gösteriyor.

    mehmet:$y$j9T$ornekSalt$ornekParolaHashi:20691:0:90:7:14:20800:0

    AlanAnlamı
    mehmetKullanıcı adı
    y$j9T$ornekSalt$ornekParolaHashiKullanıcının parola hash’i
    20691Parolanın en son değiştirildiği gün. 1 Ocak 1970’ten itibaren hesaplanır
    0Parola beklemeden tekrar değiştirilebilir
    90Parola en fazla 90 gün kullanılabilir
    7Parolanın süresi dolmadan 7 gün önce kullanıcıya uyarı verilir
    14Parolanın süresi dolduktan 14 gün sonra hesap devre dışı bırakılır
    20800Hesabın tamamen sona ereceği gün. 1 Ocak 1970’ten itibaren hesaplanır
    0Gelecekte kullanılmak üzere ayrılmış alan

    Not2: Bir kullanıcının parolasının hash’ini alalım, ardından parolayı değiştirip tekrar parolamızı girelim. Tekrar hash aldığımızda parolalar birebir aynı olmasına rağmen çıkan hash aldığımız ilk hash’ten farklı olacaktır.

    Basit olarak işlem şu şekilde düşünülebilir:

    Parola + rastgele salt değeri → hash fonksiyonu → parola hash'i

    Aynı parola farklı salt değerleriyle işlendiğinde farklı hash sonuçları ortaya çıkar.

    yeni-kullanici:$y$j9T$NoLPxXWzPciAVN43S07q9/$Y/Q/OawVtSOKPNsO0GkdErN8CL/vENvTxt/LRPzOchD:20693:0:99999:7:::

    şifreyi değiştirip tekrar deneyelim.

    yeni-kullanici:$y$j9T$msqHsK89VsimsncsxRW88/$5mHztvApgr2Y8Llxb/noHwmjCZpzaK9X.nvxTjPkKYB:20693:0:99999:7:::

    Not: Salt gizli olmak zorunda değildir ve genellikle hash bilgisinin içerisinde saklanır. Asıl amacı aynı parolanın her kullanıcıda aynı hash sonucunu oluşturmasını engellemektir.

    Not: Linux’ta kullanıcı doğrulaması yalnızca /etc/shadow dosyasına bakılarak yapılmaz. Arada PAM (Pluggable Authentication Modules) adı verilen bir soyutlama katmanı bulunur. SSH, sudo ve su gibi araçlar parola ve hesap kontrollerini PAM kurallarına göre gerçekleştirir. Bu nedenle /etc/shadow dosyasında parola alanının boş olması, kullanıcının boş parolayla giriş yapabileceği anlamına gelmez. Örneğin Ubuntu’da boş parola tanımlayabildim ancak giriş yapamadım.

    Yeni kullanıcı eklemek için birbirinin yerine geçebilecek iki komudumuz var. Useradd ve adduser. Useradd tek bir satırda tüm işlemi bitirirken adduser, daha insancıl bir deneyim sunuyor. Genellikle programlar useradd kullanırken insanlar adduser kullanırlar.

    Dosya İzinleri

    Bir dosyanın izinlerinde üç kullanıcı sınıfı bulunur:

    • user: Dosyanın sahibi,
    • group: Dosyanın grubu,
    • others: Sahip veya ilgili grup sınıfına girmeyen diğer kullanıcılar.

    Not: others ifadesi “herkes” anlamına gelmez. Dosyanın sahibi ve grup sınıfıyla eşleşmeyen diğer kullanıcıları ifade eder.

    Bir kullanıcı dosyaya erişmeye çalıştığında sistem tüm izinleri üst üste toplamaz. Önce kullanıcının dosyanın sahibi olup olmadığına bakılır. Sahipse yalnızca user alanındaki izinler uygulanır. Sahibi değilse dosyanın grubuyla eşleşip eşleşmediğine bakılır. Bu sınıfa da girmiyorsa others izinleri kullanılır.

    Not: Bir dosya da yazma yetkimizin bulunması o dosyayı silebileceğimiz manasına gelmez. O dosyayı silebilmek için bulunduğu dizinde yazma hakkımız olması gerekir çünkü dosya adı dizin kaydında bulunur. Bizim yapacağımız işlem de dizin kaydından dosyayı kaldırmak olacaktır. (Dizine yazma izninin yanında execute (x) yetkisine de sahip olmamız gerekir)

    Klasik izinlerle dosyanın sahibi, grubu ve diğer kullanıcılar için yetki tanımlayabiliyoruz. Ancak aynı dosyada daha komplike, örneğin aynı grup içerisindeki bir kullanıcıya yazma ve okuma yetkileri verirken başka bir kullanıcıya okuma ve çalıştırma yetkileri vermek gibi, yetkilendirmeler için ACL kullanılır.

    ACL, Access Control List ifadesinin kısaltmasıdır. Bir dosyanın klasik izin alanlarına ek olarak belirli kullanıcı ve gruplara ayrıca yetki tanımlamamızı sağlar.

    Mevcut ACL kurallarını görmek için getfacl kullanabiliriz:

    Belirli bir kullanıcıya okuma ve yazma yetkisi vermek için:

    bash
    mehmet@debian ~$ setfacl -m u:ayse:rw dosya.txt

    Belirli bir gruba yalnızca okuma yetkisi vermek için:

    bash
    mehmet@debian ~$ setfacl -m g:muhasebe:r dosya.txt

    Yaptığımız değişiklikleri tekrar kontrol edebiliriz:

    bash
    mehmet@debian ~$ getfacl dosya.txt

    Not: acl komutlarıyla verdiğimiz yetkileri chmod ile override (ezmek) ettiğimizde #effective satırı açılır. Bu kısım pratikte kişi ya da grupların hangi izinlere sahip olduğunu belirtir.

    Tanımladığımız ACL kuralını kaldırmak için:

    bash
    mehmet@debian ~$ setfacl -x u:ayse dosya.txt

    Not: ACL çıktısındaki mask alanı; dosya sahibi ve others haricinde, tanımlı kullanıcıların ve grupların kullanabileceği en yüksek yetkiyi belirler. Kullanıcının veya grubun etkin yetkisi, kendisine verilen yetkiler ile mask yetkilerinin kesişiminden oluşur.

    Bir dosyaya acl ile müdahale ettiğimizde ls -l çıktısında izinlerin yanında + bulunur, bu dosyaya acl ile kural atandığını gösterir.

    Dosya izinleri ve ACL, sistemdeki erişim kontrolünün tamamı değildir. Dağıtımlar bunlara ek bir katman olarak Debian’da AppArmor, RHEL tabanlı sistemlerde ise SELinux kullanarak ek bir güvenlik katmanı oluşturur.

    Bu nedenle bir dosyanın chmod izinleri uygun görünmesine rağmen erişim engelleniyorsa AppArmor veya SELinux kurallarının da kontrol edilmesi gerekebilir (biz derslerimizde bu konuyla ilgilenmedik)

    Kabukta Komutları Birbirine Bağlamak

    Bir satırda birden fazla komut çalıştırmak, bunu belli durumlara bağlamak için bağlaçlar kullanırız.

    Noktalı virgül, ilk komutun başarılı olup olmadığına bakmadan sıradaki komutu çalıştırır.

    komut1 ; komut2

    Örneğin:

    bash
    mehmet@debian ~$ mkdir deneme ; touch deneme/dosya.txt

    İkinci komutun yalnızca ilk komut başarılı olduğunda çalışmasını istiyorsak bu durumda && kullanırız.

    komut1 && komut2

    Örneğin dizin başarıyla oluşturulursa içine girmek için:

    bash
    mehmet@debian ~$ mkdir yeni-dizin && cd yeni-dizin

    Not: Tek başına kullanılan &, && ile aynı değildir. tek & komutu arka planda çalıştırmak için kullanılır.

    Tam tersi şekilde, ikinci komutun yalnızca ilk komut başarısız olduğunda çalışmasını istiyorsak || kullanırız.

    komut1 || komut2

    Örneğin bir dosya bulunamazsa ekrana hata mesajı yazdırabiliriz:

    bash
    mehmet@debian ~$ ls bulunmayan-dosya || echo "Dosya bulunamadı"

    Not: Noktalı virgül kabukta komutları ayırır. Normal bir karakter olarak kullanmak için önüne ters eğik çizgi konur örneğin, echo \; gibi.

    Dosya Sahipliği ve Yetkileri

    Bir dosyanın sahibini değiştirmek için chown komutu kullanılır.

    bash
    mehmet@debian ~$ sudo chown kullanici:grup dosya.txt

    Bir dosyanın sahibini başka bir kullanıcıya değiştirme işlemini normalde yalnızca root yapabilir.

    Yalnızca grubunu değiştirmek için chgrp kullanılabilir:

    bash
    mehmet@debian ~$ chgrp muhasebe dosya.txt

    Not: Normal bir kullanıcı kendi dosyasının grubunu, üyesi olduğu gruplardan birine değiştirebilir.

    Dosyanın sahibini ve grubunu değiştirebildik. Dosya üzerinde kimin hangi işlemleri yapabileceğini belirleyen izinleri değiştirmek içinse chmod komutunu kullanırız. Sayısal gösterimde yetkilerin değerleri şöyledir:

    YetkiDeğer
    Çalıştırma (x)1
    Yazma (w)2
    Okuma (r)4

    Bu değerleri toplayarak bir kullanıcı sınıfına verilecek yetkiyi belirleyebiliriz. Örneğin rwx değeri 4 + 2 + 1 = 7, rw- değeri ise 4 + 2 = 6 olur.

    bash
    mehmet@debian ~$ chmod 640 dosya.txt

    Bu komut dosyanın sahibine okuma ve yazma, grubuna yalnızca okuma yetkisi verir. Diğer kullanıcıların hiçbir yetkisi olmaz.

    Sembolik kullanımda şu ifadeler bulunur:

    İfadeAnlamı
    uDosyanın sahibi
    gDosyanın grubu
    oDiğer kullanıcılar
    aBütün sınıflar
    +Yetki ekle
    -Yetki kaldır
    =Yetkileri tam olarak belirle

    Örnek kullanımlar:

    chmod u=rw dosya.txt (sahibe read ve write ver)
    chmod u+x dosya.txt (sahibin yetkisine execute ekle)
    chmod g-w dosya.txt (grubun yetkisinden write çıkart)
    chmod o-rwx dosya.txt (others’ın yetkisi tamamen al)

    su ve sudo

    su, başka bir kullanıcı kimliğine geçmek için kullanılır. Kullanıcı adı verilmezse varsayılan olarak root kullanıcısına geçmeye çalışır.

    sudo ise izin verilen tek bir komutu başka bir kullanıcı, varsayılan olarak da root, yetkisiyle çalıştırmamızı sağlar.

    Not: su ve sudo parola konusunda da farklı davranır. su – root komutu hedefteki root kullanıcısının parolasını ister. sudo ise normalde komutu çalıştıran kullanıcının kendi parolasını sorar ve kullanıcının bu işlemi yapmaya yetkili olup olmadığını sudoers kurallarından kontrol eder.

    sudo -i, yetkimiz varsa root kullanıcısının giriş ortamına benzer bir kabuk açar. sudo su komutuyla da root kabuğu açılabilir.

    Bu iki komut arasındaki bir diğer fark çevresel değişkenlerde ortaya çıkar. su ayse ile su – ayse aynı ortamı oluşturmaz. su komutunu – olmadan kullandığımızda mevcut oturumun bazı çevresel değişkenleri korunabilir. su – ayse ise Ayşe sisteme doğrudan giriş yapmış gibi bir login ortamı oluşturmaya çalışır ev dizinine geçer ve hedef kullanıcının giriş dosyalarını kullanır.

    çevresel değişkenlerin değişimi.

    sudo da bütün çevresel değişkenlerimizi olduğu gibi aktarmak zorunda değildir. Hangi değişkenlerin korunacağı sudoers yapılandırmasına bağlıdır. Bu nedenle “sudo her zaman mevcut kullanıcının bütün çevresel değişkenlerini kullanır” şeklinde kesin bir kural söyleyemeyiz.

    su ile başka bir kullanıcının kabuğunda kalmadan tek bir komut çalıştırmak için -c parametresini kullanabiliriz

    bash
    mehmet@debian ~$ su - ayse -c id

    Bu işlem komutu Ayşe kullanıcısıyla çalıştırır ve komut tamamlandığında bizi mevcut kabuğumuza geri döndürür.

    Bir kullanıcıya sudo yetkisi vermemiz, o kullanıcının her komutu root olarak çalıştırabilmesi gerektiği anlamına gelmez. Yetkiyi yalnızca ihtiyaç duyduğu komutla sınırlandırabiliriz.

    Örneğin, ayse kullanıcıs yalnızca rnano ile /etc/wgetrc dosyasını açabilsin.

    which ile rnano’nun binary’sine ait tam yolunu öğreniyorum.

    bash
    mehmet@debian ~$ which rnano

    /usr/bin/rnano çıktısını aldım. Ardından bu kullanıcı için ayrı bir sudoers dosyası açıyorum.

    bash
    mehmet@debian ~$ sudo visudo -f /etc/sudoers.d/ayse

    Burada -f ile ilgili dosyanın yolunu verdim.

    Not: Burada illaki visudo kullanacağız diye bir kural yok, yalnızca visudo’nun bu iş için özelleşmiş olması sebebiyle onu tercih ettik. Başka bir metin editörü de kullansak başarıyla tamamlayabilirdik işlemi.

    ayse ALL=(root) /usr/bin/rnano /etc/wgetrc

    yazıyoruz, kaydedip çıkıyoruz.

    Buradaki parçaların anlamları şöyledir:

    BölümAnlamı
    ayseYetkinin verileceği kullanıcı
    ALLKuralın herhangi bir makine adıyla eşleşmesini sağlar. Sudoers dosyası yalnızca bu bilgisayarda bulunuyorsa kural da yalnızca bu bilgisayarda uygulanır
    (root)Komutun root kullanıcısının yetkileriyle çalıştırılabileceğini belirtir
    /usr/bin/rnanoAyşe’nin sudo ile çalıştırmasına izin verilen program
    /etc/wgetrcrnano programına verilmesine izin verilen tek dosya argümanı

    Dosyayı kaydettikten sonra sözdizimini kontrol ediyoruz:

    bash
    mehmet@debian ~$ sudo visudo -cf /etc/sudoers.d/ayse

    yazıp,

    sıkıntı olmadığı çıktısını aldım.

    Ardından ayse kullanıcısının sudo yetkisiyle kullanabildiği komutları listelemek için,

    bash
    mehmet@debian ~$ sudo -l -U ayse

    yazıp,

    çıktısını alıyorum, en alt satırda wgetrc dosyasını sudo yetkisiyle rnano ile açabileceği yazıyor.

    Kısıtlı kullanıcıya geçerek izin verilen komutu deniyorum:

    bash
    mehmet@debian ~$ su - ayse 
    mehmet@debian ~$ sudo /usr/bin/rnano /etc/wgetrc

    Başka bir dosyayı açmayı denediğimizde sudoers kuralındaki komut satırıyla eşleşmediği için izin verilmemesi gerekir:

    Not: Sudo, /etc/sudoers dosyasını ve /etc/sudoers.d altındaki kuralları uygulamadan önce sahiplik ve izinlerini kontrol eder.

    Bunu denemek için /etc/sudoers.d dizinine ve içindeki ayse dosyasına 777 izni verdik. ayse, nano ile /etc/passwd dosyasını root yetkileriyle açabileceği bir kural ekledi ancak sudo, herkesin yazabildiği dizini ve dosyayı güvenli kabul etmediği için bu kuralı uygulamadı. Daha sonra dizini root:root sahipliğinde 755, ayse dosyasını ise root:root sahipliğinde 440 olarak ayarladığımızda dosyanın içindeki kural geçerli oldu. Bu nedenle sudoers izinlerini düzeltmeden önce dosyanın içeriğini de kontrol etmeliyiz, aksi halde başka bir kullanıcının eklediği zararlı kuralı farkında olmadan etkinleştirebiliriz.

    Burada özellikle nano yerine neden rnano kullandığımızı da açıklamak gerekir. rnano, nano editörünün sınırlandırılmış biçimde çalışan sürümüdür. Temel metin düzenleme işlemleri yapılabilir ancak dosya sisteminde farklı konumlara erişmeye veya dış komut çalıştırmaya yarayan bazı özellikler devre dışı bırakılır.

    Özelliknanornano
    Normal metin düzenlemeYapılabilirYapılabilir
    Farklı bir dosyayı açmaYapılabilirSınırlandırılır
    Dosyayı farklı adla veya konuma yazmaYapılabilirSınırlandırılır
    Dış komut çalıştırmaYapılabilirSınırlandırılır
    Kullanım amacıNormal metin düzenlemeKullanıcının belirli bir dosya üzerinde tutulması

    Not: rnano tek başına eksiksiz bir güvenlik sınırı olarak görülmemelidir. Kullanıcının sahip olduğu diğer komutlar ve dosya izinleri de ayrıca değerlendirilmelidir.

    sudo yetkisi olmayan normal bir kullanıcı da kendi parolasını değiştirebilir. Bunun için passwd komutunu kullanması yeterlidir:

    Başka bir kullanıcının parolasını değiştirmek için root yetkisi gerekir:

    bash
    mehmet@debian ~$ sudo passwd ayse

    Normal kullanıcı /etc/shadow dosyasına doğrudan yazamaz. Buna rağmen passwd komutunun parolayı değiştirebilmesinin sebebi çalıştırılabilir dosya üzerinde SUID bitinin bulunmasıdır.

    SUID sayesinde passwd programı çalışırken dosyanın sahibi olan root kullanıcısının etkili yetkilerini kullanabilir. Ancak bu, kullanıcıya /etc/shadow dosyası üzerinde istediği değişikliği yapma hakkı vermez. Yetki passwd programına verilmiştir, program da kendisini çalıştıran gerçek kullanıcıyı kontrol ederek normal kullanıcının yalnızca kendi parolasını değiştirmesine izin verir.

    suid, sgid ve sticky bit

    Klasik okuma, yazma ve çalıştırma izinlerinin yanında üç özel izin biti bulunur.

    SUID biti çalıştırılabilir bir dosyaya verildiğinde program, onu çalıştıran kullanıcının değil dosya sahibinin izinleriyle çalışır. İzinler kısmında s harfiyle gösterilir.

    Sayısal gösterimde SUID değeri 4 ile ifade edilir:

    bash
    mehmet@debian ~$ chmod 4755 program

    SUID dosyanın sahibinin yetkileri ile çalışırken bunun grup tarafındaki karşılığı SGID bitidir. SGID biti çalıştırılabilir dosyalarda programın dosyanın grup yetkileriyle çalışmasını sağlar. Grup çalıştırma alanında s karakteriyle görünür.

    bash
    mehmet@debian ~$ chmod g+s program
    mehmet@debian ~$ chmod 2755 program

    (ikisi de aynı işe denk gelir)

    SGID bir dizine uygulandığında ise o dizinin altında oluşturulan yeni dosya ve dizinlerin, oluşturan kullanıcının varsayılan grubu yerine üst dizinin grubunu devralmasını sağlar. Ortak çalışma dizinlerinde bu davranış işimize yarar. Sayısal gösterimde SGID biti 2 ile ifade edilir.

    bash
    mehmet@debian ~$ sudo mkdir /srv/ortak
    mehmet@debian ~$ sudo chgrp proje /srv/ortak
    mehmet@debian ~$ sudo chmod 2775 /srv/ortak

    Birden fazla kullanıcının yazabildiği dizinlerde başka bir problem ortaya çıkar: Dizine yazabilen kullanıcılar birbirlerinin dosyalarını silebilirler. Sticky bit, kullanıcıların dizinde dosya oluşturabilmesine rağmen birbirlerinin dosyalarını silmesini engellemek için kullanılır. Bunun en bilinen örneği /tmp dizinidir.

    drwxrwxrwt 10 root root 200 Aug 28 20:54 /tmp

    Çıktıda izinlerin sonunda görülen t karakteri sticky bitin aktif olduğunu gösterir:

    Sticky bit bulunan bir dizinde dosyayı genellikle dosyanın sahibi, dizinin sahibi veya root silebilir. Sayısal gösterimde Sticky bit 1 ile ifade edilir.

    bash
    mehmet@debian ~$ chmod +t ortak-dizin
    mehmet@debian ~$ chmod 1777 ortak-dizin

    Dosya izinlerini öğrendikten sonra yeni oluşturulan dosyaların başlangıç izinlerinin nereden geldiğine de bakabiliriz. Yeni oluşturulan normal dosyaların başlangıç yetkisi en fazla 666, dizinlerin başlangıç yetkisi ise en fazla 777 olabilir. Son yetkiler bu başlangıç değerlerinden umask ile kapatılan bitlerin çıkarılmasıyla belirlenir.

    Yeni dosyaların 666 yetkisiyle oluşmasını istiyorsak hiçbir biti kapatmayan 000 umask değerini kullanabiliriz.

    Normal dosyaların başlangıç değerinde çalıştırma bitleri bulunmadığı için umask 000 kullanıldığında dosya 777 değil 666 olur. Linux, yeni oluşturulan sıradan bir metin dosyasına kendiliğinden çalıştırma yetkisi vermez.

    Aynı umask değeriyle oluşturulan dizin ise 777 olabilir:

    Not: umask 000, sistemdeki diğer kullanıcıların da yeni dosyalara yazabilmesine neden olabilir. Bu nedenle yalnızca ödevi göstermek amacıyla geçici olarak kullanılmalı, kalıcı ve genel bir ayar yapılmadan önce güvenlik etkisi düşünülmelidir. umask değerlerinin kalıcı olmasını istiyorsak home dizininde yer alan .bashrc veya .profile dosyalarına ekleyebiliriz.

    editörler, history ve locate

    nano, dosyayı açtığımız anda direkt yazmaya başlayabildiğimiz daha basit bir metin editörüdür. vi ise farklı çalışma modlarına sahip özelleştirebildiğimiz daha kapsamlı bir editördür.

    vi ile bir dosya açtığımızda başlangıçta komut modunda bulunuruz:

    bash
    mehmet@debian ~$ vi dosya.txt

    Yazı yazabilmek için i veya a tuşuyla insert (edit) moduna geçebiliriz. Tekrar komut moduna dönmek için Esc tuşuna basarız.

    Komut modunda kullanabileceğimiz bazı ifadeler:

    KomutYaptığı işlem
    :wDosyayı kaydeder
    :qEditörden çıkar
    :wqKaydedip çıkar
    :q!Değişiklikleri kaydetmeden çıkar

    less ise bir metin editörü değildir. Dosyayı değiştirmeden görüntülemek için kullanılır:

    bash
    mehmet@debian ~$ less /var/log/syslog

    Dosya içerisinde /aranacak_ifade yazarak ileri yönde arama yapabilir, q tuşuyla çıkabiliriz.

    Dosyaları düzenlerken veya sistem üzerinde işlem yaparken daha önceden yazmış olduğumuz komutlara ulaşmak için history komutunu kullanırız.

    Çıktıda gördüğümüz * işareti, o komutun daha sonrasında ok tuşlarıyla getirilip düzenleme yapıldığını belirtir.

    Bash, komut geçmişini açık terminalin belleğinde tutar ve oturum kapanırken genellikle ~/.bash_history dosyasına kaydeder. Bu nedenle yalnızca dosyayı silmek yeterli olmayabilir; bellekte kalan geçmiş tekrar dosyaya yazılabilir. Hem bellekteki hem de dosyadaki geçmişi temizlemek için şu komut kullanılır:

    bash
    mehmet@debian ~$ history -c && history -w

    Burada history -c bellekteki geçmişi temizler, history -w ise temizlenen listeyi geçmiş dosyasına yazar.

    Geçmişte yazdığımız komutları history ile bulabildiğimiz gibi sistemdeki dosyaları da farklı araçlarla arayabiliriz. find komutu arama sırasında belirttiğimiz dizinleri dolaşırken locate, daha önceden hazırlanmış dosya yolu veritabanı içerisinde arama yapar. Bu nedenle çok hızlı sonuç verir.

    locate paketini indirdiğimizde locate -S ile veritabanı hakkında bilgilere erişebiliriz. Bu komut locate tarafından kullanılan veritabanı hakkında istatistikleri gösterir. Veritabanının konumu, son güncellenme zamanı, boyutu, kayıtlı dosya yolu sayısı ve sıkıştırma oranı gibi bilgiler bu çıktıda görülebilir.

    Ancak bu bilgilere erişmek için ilk önce locate’in kullandığı arama veritabanını güncellemek için,

    bash
    mehmet@debian ~$ sudo updatedb

    komutunu girmemiz gerekir. Bu komutu girmezsek locate -S çıktısı gelmeyecektir.

    Ardından istediğimiz dosya adını girerek sonuca erişebiliriz.

    bash
    mehmet@debian ~$ locate dosya_adi

    locate oldukça hızlıdır. Ancak kullandığı veritabanı güncel değilse yeni oluşturulan dosyaları bulamayabilir veya silinen dosyaların eski yollarını gösterebilir.

    Dosya İndirme ve Karşılaştırma

    curl ve wget, ağ üzerinden veri indirmek için kullanabileceğimiz iki araçtır. Benzer görünseler de kullanım amaçları arasında bazı farklar bulunur.

    wget, özellikle bir dosyayı indirip diske kaydetmek için sade bir kullanıma sahiptir. curl hiçbir parametre verilmediğinde ilgili veriyi doğrudan terminale basar.

    Bir dosyaya kaydetmek için -o, uzak sunucudaki dosya adını korumak için -O kullanabiliriz:

    bash
    mehmet@debian ~$ curl -o dosya.tar.gz https://kamp.com/dosya.tar.gz
    bash
    mehmet@debian ~$ curl -O https://kamp.com/dosya.tar.gz
    Özellikcurlwget
    Varsayılan davranışVeriyi terminale yazarDosyayı diske kaydeder
    API istekleriAyrıntılı şekilde kullanılabilirTemel indirme işlemlerine daha uygundur
    HTTP metodu ve başlık ayarlamaYapılabilirDaha sınırlı

    curl yalnızca dosya indirme ile sınırlayabileceğimiz bir araç değildir, http request düzenlemeleri yapmak, api uç noktalarını kontrol edebilmek gibi çok çeşitli işlevleri bulunur.

    bash
    mehmet@debian ~$ curl -I https://example.com

    İki dosyanın aynı olup olmadığını kontrol etmemiz gerektiği durumlarda diff aracını kullanırız. diff, iki metin dosyasını satır satır karşılaştırarak hangi satırların değiştiğini gösterir.

    bash
    mehmet@debian ~$ diff eski_dosya yeni_dosya

    diff ile kontrol etmek nispeten verimsiz bir yöntemdir. Bu yöntem yerine sadece dosyaların farklı olup olmadığını kontrol etmek istiyorsak hash kontrolü yapmak daha mantıklıdır.

    bash
    mehmet@debian ~$ sha256sum eski.txt yeni.txt

    Hash değerleri aynıysa dosyaların içeriklerinin aynı olduğunu söyleyebiliriz. Farklıysa içeriklerin farklı olduğunu anlarız ancak değişikliğin hangi satırda olduğunu göremeyiz. diff ise bize değişikliğin yerini gösterir. Bu nedenle bu iki araç birbirinin doğrudan alternatifi değildir.

    diff ile yalnızca değişiklikleri ekrana göstermek zorunda değiliz. Bir dosyada yaptığımız değişiklikleri başka bir dosyaya otomatik olarak uygulamak için çıktısını bir yama dosyasına kaydedebiliriz.

    Elimizde eski.txt ve düzenlenmiş yeni.txt dosyaları olsun:

    bash
    mehmet@debian ~$ diff -u eski.txt yeni.txt > degisiklik.patch

    Yamayı eski dosyaya uygulamak için:

    bash
    mehmet@debian ~$ patch eski.txt < degisiklik.patch

    Ardından dosyaları karşılaştırdığımızda aralarında fark kalmadığını görebiliriz:

    bash
    mehmet@debian ~$ diff eski.txt yeni.txt
    mehmet@debian ~$ echo $?

    diff herhangi bir çıktı üretmez ve çıkış kodu 0 olursa iki dosyanın aynı olduğu anlaşılır. Yani kısaca diff ile iki sürüm arasındaki değişiklikleri kaydedebilir, patch ile bu değişiklikleri dosyanın başka bir kopyasına otomatik olarak uygulayabiliriz.

    Devamını okumak için…