SSD Nodes Learn 🎉 VPS $5.50/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor

Linux umask nedir ve dosya izinlerini nasıl etkiler?

Linux sistemlerde umask değerinin dosya ve dizin izinlerini nasıl kısıtladığını öğrenin. Mevcut maskenizi görüntüleyin ve root ile kullanıcı izin farklarını analiz edin.

Linux sistemlerde umask işlevi

umask, Linux üzerindeki her sürecin taşıdığı bir sayıdır ve bu sürecin oluşturduğu her dosya ile dizinin izin modunu belirler. Bir program, oluşturma anında çekirdekten bir dizi izin talep eder. Çekirdek, maskede belirtilen her biti temizler ve geriye kalanı uygular. umask asla erişim izni vermez; yalnızca oluşturan programın talep ettiği izinlerden bitleri eksiltir.

Bu değer, kullandığınız dağıtımın bir özelliği değildir. Hangi hesapla işlem yaptığınıza ve kabuğun (shell) nasıl başlatıldığına bağlıdır. Aynı makinede, aynı anda, standart bir imaj üzerinde bile bu iki yanıt farklılık gösterebilir. Bu nedenle ilk adım, kılavuza bakmak değil, önünüzdeki makine üzerinde ölçüm yapmaktır.

Bulunduğunuz kabukta umask değerini yazdırma

umask
umask -S

İlk biçim, maskeyi sekizlik (octal) tabanda yazdırır. İkinci biçim ise aynı maskeyi, chmod komutunun kabul ettiği sembolik izinler biçiminde gösterir. Her iki satırı da ekranda tutun. Aşağıdaki tüm içerik, kabuğunuzun az önce yazdırdığı değerlerle bir karşılaştırmadır.

umask bir kabuk yerleşik komutudur (builtin), disk üzerinde bulunan bir program değildir. Bunu type umask ile doğrulayın. Bu durum önemlidir; çünkü bir yerleşik komut, kabuk sürecinin kendisini değiştirir. Ayrı bir program ise yalnızca kendi sürecini değiştirebilir, ardından sonlandığında bu değişikliği de beraberinde götürür.

Bir dosya ve dizin oluşturun, ardından modları okuyun

cd "$(mktemp -d)"
touch probe.file
mkdir probe.dir
stat -c '%a %A %n' probe.file probe.dir

%a, modu sekizlik (octal) biçimde yazdırır; %A ise aynı modu ls -l aracının kullandığı drwxr-xr-x biçiminde görüntüler. Her iki satırı da az önce yazdırdığınız maske ile karşılaştırın. Maskede ayarlı olan her bit, modlarda eksik görünür; çünkü bir maskenin tek işlevi bu bitleri temizlemektir. Eğer %A sütununu okumak henüz netleşmediyse, drwxr-xr-x izin dizgisi öncelikle anlaşılması gereken kısımdır.

Dosya ve dizin birbirinden farklıdır ve bu farkın nedeni maske değildir. touch, çekirdekten sahibi, grubu ve diğerleri için okuma ve yazma izni ister. mkdir ise her üçü için okuma, yazma ve çalıştırma izni talep eder. Aynı maske, iki farklı talepten çıkarılır. Bu nedenle, touch ile oluşturulan bir dosya, maske ne olursa olsun asla çalıştırılabilir değildir: çalıştırma biti hiçbir zaman talep edilmemiştir ve bir maske, eksik olan bir biti geri ekleyemez.

( umask a=rwx; touch open.file; stat -c '%a %A %n' open.file )

Parantezler, komutları bir alt kabukta (subshell) çalıştırır; bu nedenle yapılan değişiklik alt kabuk kapandığında kaybolur. Maske artık hiçbir şeyin temizlenmemesini ister ve stat, dosya üzerinde hala çalıştırma bitinin olmadığını raporlar. Ardından umask komutunu tekrar çalıştırdığınızda orijinal değer geri gelir; bu da ayarın disk üzerinde bir yerde saklanmadığını, bir süreç içinde yaşadığını ve alt süreçlere miras kaldığını gösterir.

Dizinlerde, temizlenmiş bir çalıştırma bitinin etkisi hissedilir.

( umask a=rw; mkdir noexec.dir; cd noexec.dir )

Sıradan bir kullanıcı olarak cd komutu, bash: cd: noexec.dir: Permission denied hatasıyla başarısız olur; çünkü maske, mkdir tarafından talep edilen çalıştırma bitini temizlemiştir ve çalıştırma biti olmayan bir dizine giriş yapılamaz. Root kullanıcısı bu denetimi atlar, bu nedenle bu durum yalnızca normal bir hesapta kendini gösterir.

root kullanıcısı ile kendi kullanıcınızın neden farklı umask değerleri gördüğü

Aynı ölçümü başka bir hesap üzerinden, farklı bir başlatma yöntemiyle çalıştırın ve iki çıktıyı yan yana inceleyin.

umask
sudo -i umask

sudo -i, root kullanıcısının oturum kabuğunu başlatır ve yerleşik komutu bunun içinde çalıştırır; dolayısıyla bu, farklı bir başlatma yoluyla gelen farklı bir hesaptır. Standart Ubuntu ve Debian sunucu imajlarında bu iki satır farklı değerler yazdırabilir. Her iki satır da doğrudur. Her biri kendi başlatma yolunun ürettiği sonucu gösterir; bu yazının geri kalanı, sistemin hangi kısmının bu değeri ürettiği hakkındadır.

İmajınızdaki hangi dosya bu değeri belirledi

grep -nE '^(UMASK|USERGROUPS_ENAB)' /etc/login.defs
grep -rn pam_umask /etc/pam.d/
grep -rn umask /etc/profile /etc/profile.d/ /etc/bash.bashrc ~/.profile ~/.bashrc 2>/dev/null || echo 'no umask line in the shell startup files'

Eğer ilk grep komutu hiçbir sonuç döndürmezse, ^ çapasını kullanmadan tekrar çalıştırın: satır yorum satırı haline getirilmiş olabilir; yorumlanmış bir satır yapılandırma değil, dokümantasyondur. Üçüncü grep komutu genellikle şaşırtıcı sonuçlar verir. Debian ve Ubuntu üzerinde yüklü gelen /etc/profile, maskeyi doğrudan ayarlamak yerine çoğunlukla PAM'e işaret eder; bu nedenle sorumlu olduğunu düşündüğünüz dosya aslında sorumlu olmayabilir. grep, eşleşme bulunamadığında sıfırdan farklı bir çıkış kodu döndürür; bu yüzden ilgili satır || echo ile biter: hiçbir başlangıç dosyasının maskeden bahsetmediği bir imajda sessizlik yerine mesaj alırsınız ve bu mesaj aslında bulgunun kendisidir.

/etc/login.defs bir değer bildirir ve PAM bunu uygular

UMASK dosyasındaki /etc/login.defs satırı, çoğu kılavuzun referans verdiği değerdir. Ne çekirdek ne de kabuk bu dosyayı okur. Dosya, bir oturum oluşturulduğunda çalışan bir PAM (pluggable authentication modules) modülü olan pam_umask tarafından okunur. pam_umask bulduğu ilk değeri alır: kullanıcının GECOS alanındaki bir umask= girdisi, ardından pam_umask.so satırının kendisine yazılmış bir umask= bağımsız değişkeni ve son olarak /etc/login.defs içindeki UMASK. Dağıtımlar bu modüle yama uyguladığından, kendi imajınız üzerinde man pam_umask komutunu çalıştırın ve orada yazdırılan sırayı okuyun.

/etc/login.defs dosyasının bir değer bildirip oturumunuzun başka bir değerle sonuçlanması ve bu durumun hiçbir tarafta uyarı vermemesi bu şekilde gerçekleşir. grep komutları hangi durumda olduğunuzu size söyler. Eğer pam_umask.so satırı kendi umask= bağımsız değişkenini taşıyorsa, login.defs satırı geçersiz kalır.

USERGROUPS_ENAB ve root istisnası

id -un
id -gn

Eğer bu iki komut aynı ismi döndürüyorsa, bir kullanıcı özel grubu (user private group) kullanıyorsunuz demektir: hesap, kendi adını taşıyan bir grupla oluşturulmuştur. pam_umask modülü, /etc/login.defs dosyasındaki USERGROUPS_ENAB parametresi ile kontrol edilen bir usergroups davranışına sahiptir. Bu özellik etkin olduğunda ve hesap root olmadığında, birincil grup ismi kullanıcı ismiyle eşleşiyorsa, modül maskenin sahip (owner) hanesindeki değeri grup (group) hanesine kopyalar. Bu durumda oturum, ilgili hesabın oluşturduğu her dosyada grup izinlerini açık bırakan bir maske ile sonuçlanır. Root kullanıcısı modül tarafından bu kuralın dışında tutulur; aynı sunucudaki iki farklı kabuğun (shell) farklı maskeler yazdırmasının en yaygın nedeni bu istisnadır.

Bu kuralın arkasındaki mantık, özel bir grubun tam olarak tek bir üyeye sahip olmasıdır; dolayısıyla grup tarafından yazılabilir olmak, sahip tarafından yazılabilir olmakla aynı anlama gelir. Bu durum, gruba ikinci bir üye eklenene kadar geçerlidir. O andan itibaren, hesabın geçmişte oluşturduğu tüm dosyalar yeni üye tarafından yazılabilir hale gelir ve bu dosyalar üzerinde izinleri değiştirecek herhangi bir komut çalıştırılmamış olur. Her servise kendi en düşük yetkili kullanıcı hesabını atadığınızda, bu grup kasıtlı olarak tek kişilik bir grup olarak kalmaya devam eder.

Login shell, non-login shell ve non-interactive shell

umask
bash -lc 'umask'
bash -c 'umask'

Bir oturum oluşturulduğunda PAM çalışır: konsolda login, sshd, su, sudo -i. Bir kabuk başka bir kabuğu başlattığında PAM çalışmaz. bash -l bir login shell'dir, bu nedenle /etc/profile ve ~/.profile dosyalarını okur ancak bir oturum oluşturulmadığı için pam_umask'i asla çağırmaz. bash -c bu dosyaların hiçbirini okumaz ve kendisini başlatan sürecin maskesini devralır. Bir cron job, bir git hook ve bir servis yöneticisi tarafından başlatılan bir program bu son duruma girer; dolayısıyla maskeleri, üst süreçlerinin sahip olduğu maskedir.

"/etc/profile içinde ayarladım ancak servis hala yanlış modda yazıyor" şikayetinin bu kadar yaygın olmasının nedeni budur. Servis, ilgili dosyayı hiçbir zaman okumamıştır.

Kalıcı olması için nereye ayarlanmalı

Maske değerini iş yükünün fiilen başladığı yere ayarlayın, çünkü her başlatma yolu farklı bir dosya okur.

  1. Giriş yapan hesaplar için: UMASK, /etc/login.defs içinde yer alır ve makinedeki her oturuma pam_umask tarafından uygulanır. Makine genelinde olduğundan, tüm hesapları aynı anda etkiler.
  2. Tek bir hesap için: pam_umask.so satırındaki umask= argümanı da makine genelindedir; bu nedenle kullanıcıya özel bir değer, o kullanıcının GECOS alanına veya giriş kabukları için ~/.profile, etkileşimli kabuklar için ~/.bashrc dosyasına eklenmelidir.
  3. systemd altındaki bir daemon için: unit dosyasının [Service] bölümündeki UMask= parametresi kullanılır. Bir unit, servis yöneticisi tarafından başlatıldığından /etc/profile asla okunmaz ve pam_umask çalışmaz. Daemon'a ulaşan tek yapılandırma unit dosyasıdır.
  4. cron veya bir kanca (hook) tarafından başlatılan bir betik için: betik herhangi bir dosya oluşturmadan önce, ilk satıra açıkça bir umask komutu eklenmelidir.
[Service]
UMask=<the octal mask you chose>

Ardından, dosyayı düzenlediğiniz kabuktan değil, ilgili yolun yeni bir başlangıcından doğrulama yapın. Mevcut kabuğunuz kendi maskesini zaten tutmaktadır ve bir yapılandırma dosyasını düzenlemek, çalışan bir sürece geriye dönük etki etmez.

bash -lc 'umask'
sudo -i umask

Neden chmod sonrasında aynı düzeltmeyi sağlamaz

chmod mevcut dosyaları onarır. Maske ise henüz var olmayan dosyaların moduna karar verir. Bir dizin üzerinde chmod -R çalıştırdığınızda, servisin oluşturduğu bir sonraki dosya yine eski mod ile gelir; çünkü bu mod oluşturma sürecinden kaynaklanır ve dizin üzerindeki hiçbir ayar bunu değiştirmez.

Ayrıca bir zaman aralığı söz konusudur. Dosyanın oluşturulduğu an ile chmod komutunun çalıştığı an arasında dosya diskte daha geniş bir mod ile durur ve dizini okuyabilen herhangi bir süreç dosyayı açabilir. Özel bir anahtar veya yedekleme arşivi için bu zaman aralığı, ortadan kaldırmaya çalıştığınız riski oluşturur.

Bunun yerine modu oluşturma aşamasında ayarlayın. install -m u=rw,go= newfile /etc/app/newfile hedef dosyayı açık bir mod ile yazar, mkdir -m ise dizin için aynısını yapar. Her ikisi de belirttiğiniz modu alır ve maskeyi yok sayar. ssh-keygen yazdığı özel anahtar üzerinde modu ayarlar; bu yüzden diğer her şeyin hatalı olduğu bir makinede bile bu tek dosya genellikle doğru yapılandırılmıştır.

Genellikle karşılaşılan sorun SSH ile ilgilidir. Düz bir mkdir ile oluşturulan bir ~/.ssh veya cat >> ile eklenen bir authorized_keys, kabuğunuzun maskesini alır. StrictModes etkin olduğunda, sshd grup tarafından yazılabilir bir dizinden anahtar dosyası okumayı reddeder. İstemciye Permission denied (publickey) hatası verilirken, sunucunun /var/log/auth.log kaydı gerçek nedeni belirtir:

Authentication refused: bad ownership or modes for directory /home/deploy/.ssh

Bu denetim kasıtlıdır ve VPS üzerinde SSH güvenliğini sıkılaştırma işlemi bunun korunmasına bağlıdır. Yeni bir sunucuda hesapları oluşturmadan önce maskeyi ölçün; bunu yeni bir VPS üzerindeki ilk on dakika rehberiyle birlikte yapın. Böylece bu hesapların oluşturduğu her dosyanın modu önceden belirlenmiş olur.

Kopyalar ve arşivler maskeyi yoksayar

cp -p ve rsync -a, kaynak dosyada kayıtlı olan modu geri yükler; bu nedenle maskenin sonuç üzerinde bir etkisi olmaz. tar, root kullanıcısı olarak veya -p bayrağına sahip normal bir kullanıcı olarak çıkarma işlemi yaptığında aynı şekilde davranır. Yedekten geri yüklenen bir dosya, yedekleme yapıldığı sırada sahip olduğu modu korur. Doğru bir maskenin yoksayıldığı sonucuna varmadan önce bunu kontrol edin: geri yüklenen veriler için maskeye hiçbir zaman başvurulmamıştır.

FAQ

Cron işim neden SSH oturumumdan farklı izin moduna sahip dosyalar oluşturuyor?

Cron işi bir oturum açma süreci değildir; bu nedenle pam_umask bu süreçte çalışmaz ve /etc/profile veya ~/.profile dosyalarını okumaz. Cron işi, kendisini başlatan sürecin maskesini devralır. Dosya oluşturma işleminden önce betiğin ilk satırına açık bir umask komutu ekleyin. İşin içinden maskeyi bir kez yazdırarak, kendi kabuğunuzun değil, ilgili işin gerçekte hangi maskeye sahip olduğunu görün.

/etc/login.defs neden farklı bir değer gösterirken kabuğum neden başka bir değer yazdırıyor?

/etc/login.defs içindeki UMASK, pam_umask için yalnızca son çare olan bir yedek değerdir. Modül, kullanıcının GECOS alanındaki bir umask= girdisini, ardından /etc/pam.d/ içindeki pam_umask.so satırında yer alan bir umask= argümanını tercih eder. USERGROUPS_ENAB ile etkinleştirilen usergroups davranışı, birincil grubu kendi adıyla aynı olan root dışındaki tüm hesaplar için grup hanesini yeniden yazar. Hesabınız için hangisinin geçerli olduğunu görmek üzere grep -rn pam_umask /etc/pam.d/ ve id -un; id -gn komutlarını çalıştırın.

Umask bir dosyayı çalıştırılabilir yapabilir mi?

Hayır. Bir maske, yalnızca oluşturan programın talep ettiği izinlerden bitleri temizleyebilir. touch hiçbir zaman çalıştırma bitini talep etmez, bu nedenle hiçbir maske çalıştırılabilir bir dosya üretemez. Bunu geçici bir dizinde ( umask a=rwx; touch f; stat -c '%a %A' f ) ile doğrulayın. Çalıştırma biti elde etmek için chmod komutuna veya oluşturma anında bu biti talep eden install -m gibi bir programa ihtiyacınız vardır.

Bir systemd servisi için umask değerini nereden ayarlarım?

Birim dosyasında, [Service] bölümü altında UMask= ile ayarlayın. Bir servis, oturum açma işlemi yerine servis yöneticisi tarafından başlatılır; bu nedenle kabuk başlatma dosyaları okunmaz ve pam_umask bu süreçte çalışmaz. systemctl daemon-reload komutundan ve birimi yeniden başlattıktan sonra, dışarıdan doğrulama yapın: servisin bir dosya oluşturmasını sağlayın ve sonucu stat -c '%a %n' ile okuyun.

Grup tarafından yazılabilir varsayılan bir maske güvenli midir?

Grup tam olarak tek bir üyeye sahip olduğu sürece güvenlidir; kullanıcı özel grubu (user private group) şeması bu varsayıma dayanır. Gruba ikinci bir hesap eklerseniz, ilk hesabın oluşturduğu tüm dosyalar, bu dosyalar üzerinde herhangi bir komut çalıştırılmaksızın yeni üye tarafından anında yazılabilir hale gelir. id -un ve id -gn komutlarını çalıştırın: aynı ismin yazdırılması, özel bir grupta olduğunuz anlamına gelir. Hesaplar arasında bir grubu paylaşıyorsanız, grup yazma bitini temizleyen bir maske ayarlayın, ardından bir dosya oluşturun ve değişikliğin etkili olduğunu kanıtlamak için stat -c '%a %n' ile kontrol edin.

#umask#permissions#pam#login-defs#linux