SSD Nodes Learn 🎉 VPS mulai $5.50/bln
Panduan Matt ConnorOleh Matt Connor

umask Linux: Awal Izin Bawaan File dan Direktori

Pelajari umask Linux dengan mencetak nilainya, membuat file dan direktori, lalu membaca modenya untuk memahami perbedaan izin root dan pengguna biasa.

Fungsi umask di Linux

umask adalah angka yang dibawa oleh setiap proses di Linux. Nilai ini menentukan mode setiap file dan direktori yang dibuat oleh proses tersebut. Program meminta sekumpulan izin kepada kernel saat membuat file atau direktori. Kernel menghapus setiap bit yang ditentukan oleh mask, lalu menerapkan bit yang tersisa. umask tidak pernah memberikan akses. umask hanya menghapus bit dari izin yang diminta oleh program pembuat.

Nilainya bukan properti distribusi Anda. Nilai ini bergantung pada akun yang Anda gunakan dan cara shell dijalankan. Kedua hal tersebut dapat menghasilkan nilai yang berbeda pada satu mesin, pada waktu yang sama, bahkan pada image bawaan. Karena itu, langkah pertama bukan mencari jawabannya di manual. Ukur nilainya langsung pada mesin yang sedang Anda gunakan.

Cetak umask pada shell yang sedang Anda gunakan

umask
umask -S

Bentuk pertama mencetak mask dalam format oktal. Bentuk kedua mencetak mask yang sama sebagai permission yang diizinkannya, dalam bentuk simbolis yang diterima oleh chmod. Biarkan kedua baris tetap terlihat. Semua bagian di bawah ini membandingkan hasilnya dengan output yang baru saja dicetak oleh shell Anda.

umask adalah shell builtin, bukan program pada disk. Konfirmasikan hal tersebut dengan type umask. Hal ini penting karena builtin mengubah proses shell itu sendiri. Program terpisah hanya dapat mengubah prosesnya sendiri, lalu keluar dan membawa perubahan tersebut bersamanya.

Buat file dan direktori, lalu baca kembali modenya

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

%a mencetak mode dalam oktal, sedangkan %A mencetak mode yang sama dalam bentuk drwxr-xr-x yang digunakan oleh ls -l. Bandingkan kedua baris tersebut dengan mask yang baru saja Anda cetak. Setiap bit yang diaktifkan dalam mask tidak ada pada mode karena menghapus bit tersebut adalah satu-satunya fungsi mask. Jika kolom %A belum mudah dibaca, string izin drwxr-xr-x adalah bagian yang harus dipahami terlebih dahulu.

File dan direktori memiliki mode yang berbeda, dan mask bukan penyebab perbedaan tersebut. touch meminta izin baca dan tulis untuk owner, group, dan other. mkdir meminta izin baca, tulis, dan execute untuk ketiganya. Mask yang sama diterapkan pada dua permintaan yang berbeda. Jadi, file yang dibuat oleh touch tidak akan pernah memiliki izin execute, berapa pun isi mask: bit execute tidak pernah diminta, dan mask tidak dapat menambahkan kembali bit tersebut.

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

Tanda kurung tersebut menjalankan perintah di dalam subshell, sehingga perubahan hanya berlaku di dalam subshell itu. Mask sekarang tidak meminta bit apa pun untuk dihapus, tetapi stat tetap melaporkan bahwa file tidak memiliki bit execute. Jalankan kembali umask setelahnya dan nilai awal Anda akan kembali. Ini menunjukkan bahwa pengaturan tersebut berada di dalam proses dan diwariskan ke proses anak, bukan disimpan di disk.

Direktori adalah tempat bit execute yang dihapus paling terasa.

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

Sebagai user biasa, cd gagal dengan bash: cd: noexec.dir: Permission denied karena mask menghapus bit execute yang diminta oleh mkdir, dan direktori tanpa bit execute tidak dapat dimasuki. Root melewati pemeriksaan tersebut, sehingga masalah ini hanya terlihat pada account biasa.

Mengapa root dan akun Anda sendiri memiliki umask yang berbeda

Jalankan pengukuran yang sama melalui akun lain dengan cara memulainya yang berbeda, lalu baca kedua output secara berdampingan.

umask
sudo -i umask

sudo -i memulai login shell milik root dan menjalankan builtin di dalamnya. Jadi, ini adalah akun yang berbeda melalui jalur startup yang berbeda. Pada image server Ubuntu dan Debian standar, kedua baris tersebut dapat mencetak nilai yang berbeda. Kedua baris tersebut benar. Masing-masing menunjukkan hasil dari jalur startup-nya sendiri. Bagian selanjutnya membahas komponen sistem yang menghasilkan hasil tersebut.

File mana pada image Anda yang menentukan nilainya

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'

Jika perintah grep pertama tidak menampilkan apa pun, jalankan lagi tanpa anchor ^. Baris tersebut mungkin dikomentari, dan baris yang dikomentari adalah dokumentasi, bukan konfigurasi. Perintah grep ketiga sering mengejutkan pengguna. Pada Debian dan Ubuntu, /etc/profile yang disertakan umumnya hanya mengarah ke PAM, bukan menetapkan mask itu sendiri. Jadi, file yang Anda kira bertanggung jawab sering kali bukan file yang menentukan nilai tersebut. grep keluar dengan status nonzero jika tidak menemukan kecocokan. Karena itu, baris tersebut diakhiri dengan || echo. Pada image yang tidak memiliki file startup yang menyebutkan mask, Anda akan mendapatkan pesan, bukan keluaran kosong. Pesan itulah temuannya.

/etc/login.defs menetapkan satu nilai dan PAM menerapkan nilai lain

Baris UMASK dalam /etc/login.defs adalah nilai yang dikutip oleh sebagian besar panduan. Kernel dan shell tidak membaca file tersebut. File itu dibaca oleh pam_umask, yaitu modul PAM (pluggable authentication modules) yang berjalan saat sesi dibuat. pam_umask mengambil nilai pertama yang ditemukan: entri umask= dalam field GECOS pengguna, lalu argumen umask= yang ditulis langsung pada baris pam_umask.so, kemudian UMASK dari /etc/login.defs. Distribusi dapat memodifikasi modul ini. Karena itu, jalankan man pam_umask pada image Anda sendiri dan periksa urutan yang ditampilkan.

Dengan demikian, /etc/login.defs dapat menetapkan satu nilai, sedangkan sesi Anda berakhir dengan nilai lain tanpa menampilkan peringatan apa pun. Perintah grep tersebut menunjukkan kondisi yang berlaku. Jika baris pam_umask.so memiliki argumen umask= sendiri, nilai pada baris login.defs tidak berlaku.

USERGROUPS_ENAB dan pengecualian untuk root

id -un
id -gn

Jika kedua perintah tersebut menampilkan nama yang sama, berarti Anda menggunakan user private group: akun dibuat dengan group miliknya sendiri yang namanya sama dengan nama akun. pam_umask memiliki perilaku usergroups yang dikendalikan oleh USERGROUPS_ENAB di /etc/login.defs. Jika opsi tersebut aktif, akun bukan root, dan nama primary group sama dengan nama user, modul menyalin digit owner dari mask ke digit group. Dengan demikian, session berakhir dengan mask yang membiarkan bit group tetap terbuka pada semua objek yang dibuat akun tersebut. root dikecualikan oleh modul itu sendiri, dan pengecualian ini merupakan alasan tunggal yang paling umum mengapa dua shell pada satu server menampilkan mask yang berbeda.

Aturan ini didasarkan pada bahwa private group hanya memiliki satu anggota. Jadi, izin group-writable sama dengan izin owner-writable dan tidak lebih dari itu. Kondisi tersebut berlaku sampai seseorang menambahkan anggota kedua ke group. Sejak saat itu, setiap file yang pernah dibuat akun tersebut dapat ditulis oleh anggota baru. Tidak ada perintah yang perlu dijalankan pada file tersebut agar kondisi itu terjadi. Berikan setiap service akun user dengan hak akses minimum miliknya sendiri, sehingga group tersebut sengaja tetap hanya memiliki satu anggota.

Shell login, shell non-login, dan shell non-interaktif

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

PAM berjalan ketika sesi dibuat: login pada konsol, sshd, su, sudo -i. PAM tidak berjalan ketika satu shell memulai shell lain. bash -l adalah shell login, sehingga membaca /etc/profile dan ~/.profile, tetapi tidak pernah memanggil pam_umask karena tidak ada sesi yang dibuat. bash -c tidak membaca kedua file tersebut dan mewarisi mask dari proses yang memulainya. Pekerjaan cron, git hook, dan program yang dimulai oleh service manager semuanya termasuk kasus terakhir. Karena itu, mask-nya mengikuti mask proses induknya.

Inilah alasan laporan “Saya sudah mengaturnya di /etc/profile, tetapi service masih menulis dengan mode yang salah” sangat umum. Service tersebut tidak pernah membaca file itu.

Tempat menetapkannya agar tetap berlaku

Tetapkan mask pada jalur tempat workload benar-benar dimulai, karena setiap jalur startup membaca file yang berbeda.

  1. Untuk akun yang login: UMASK di /etc/login.defs, yang diterapkan oleh pam_umask ke setiap sesi pada mesin. Pengaturan ini berlaku untuk seluruh mesin, sehingga mengubah semua akun sekaligus.
  2. Untuk satu akun: argumen umask= pada baris pam_umask.so juga berlaku untuk seluruh mesin. Karena itu, nilai khusus per pengguna harus ditempatkan di kolom GECOS pengguna tersebut, atau di ~/.profile untuk login shell dan ~/.bashrc untuk shell interaktif.
  3. Untuk daemon yang dikelola oleh systemd: UMask= pada bagian [Service] unit. Unit dijalankan oleh service manager, sehingga /etc/profile tidak pernah dibaca dan pam_umask tidak pernah berjalan. Dari semua opsi ini, hanya file unit yang dapat menjangkau daemon.
  4. Untuk skrip yang dijalankan oleh cron atau hook: umask secara eksplisit pada baris pertama, sebelum skrip membuat apa pun.
[Service]
UMask=<the octal mask you chose>

Kemudian lakukan verifikasi dari startup baru pada jalur yang sama. Jangan melakukan verifikasi dari shell tempat Anda mengedit file. Shell saat ini sudah menyimpan mask-nya, dan pengeditan file konfigurasi tidak memengaruhi proses yang sedang berjalan.

bash -lc 'umask'
sudo -i umask

Mengapa menjalankan chmod setelahnya bukan perbaikan yang sama

chmod memperbaiki file yang sudah ada. Mask menentukan mode file yang belum ada. Jalankan chmod -R pada sebuah direktori, lalu file berikutnya yang ditulis oleh service akan kembali menggunakan mode lama, karena mode tersebut berasal dari proses yang membuat file dan tidak ada perubahan pada direktori yang dapat mengubahnya.

Ada juga jeda waktu. Antara saat file dibuat dan saat chmod dijalankan, file berada di disk dengan mode yang lebih terbuka. Setiap proses yang dapat membaca direktori tersebut dapat membukanya. Untuk private key atau arsip cadangan, jeda waktu tersebut merupakan risiko yang ingin Anda hilangkan.

Tetapkan mode saat file dibuat. install -m u=rw,go= newfile /etc/app/newfile menulis tujuan dengan mode eksplisit, dan mkdir -m melakukan hal yang sama untuk direktori. Keduanya menggunakan mode yang Anda tentukan dan mengabaikan mask. ssh-keygen menetapkan mode pada private key yang ditulisnya. Karena itu, file tersebut sering memiliki mode yang benar pada mesin yang mode file lainnya tidak benar.

SSH biasanya menjadi masalah. ~/.ssh yang dibuat dengan mkdir biasa, atau authorized_keys yang ditambahkan dengan cat >>, menggunakan mask dari shell Anda. Jika StrictModes aktif, sshd menolak membaca file key dari direktori yang dapat ditulis oleh group. Client menerima pesan Permission denied (publickey), sedangkan /var/log/auth.log pada server mencatat penyebab sebenarnya:

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

Pemeriksaan tersebut memang disengaja, dan penguatan keamanan SSH pada VPS bergantung pada pemeriksaan ini. Ukur mask pada server baru sebelum membuat akun yang akan menggunakannya, bersama dengan sepuluh menit pertama pada VPS baru, agar mode setiap file yang ditulis akun tersebut sudah ditentukan sejak awal.

Salinan dan arsip mengabaikan mask

cp -p dan rsync -a memulihkan mode yang tercatat pada file sumber, sehingga mask tidak memengaruhi hasilnya. tar melakukan hal yang sama saat mengekstrak sebagai root atau sebagai pengguna biasa dengan -p. File yang dipulihkan dari cadangan mempertahankan mode yang dimilikinya saat cadangan dibuat. Periksa hal ini sebelum menyimpulkan bahwa mask yang benar diabaikan: untuk data yang dipulihkan, mask memang tidak pernah digunakan.

FAQ

Mengapa cron job saya membuat file dengan mode yang berbeda dari sesi ssh saya?

Cron job bukan sesi login, sehingga pam_umask tidak pernah berjalan untuk cron job tersebut dan tidak membaca /etc/profile maupun ~/.profile. Cron job mewarisi mask dari proses yang menjalankannya. Tambahkan umask secara eksplisit pada baris pertama script, sebelum script membuat file atau direktori apa pun. Cetak mask satu kali dari dalam job agar Anda dapat melihat mask yang benar-benar digunakan job tersebut, bukan mask shell Anda sendiri.

Mengapa /etc/login.defs menetapkan satu nilai, tetapi shell saya menampilkan nilai lain?

UMASK dalam /etc/login.defs hanya menjadi fallback terakhir untuk pam_umask. Modul tersebut memprioritaskan entri umask= dalam field GECOS pengguna, lalu argumen umask= pada baris pam_umask.so dalam /etc/pam.d/. Perilaku usergroups, yang diaktifkan oleh USERGROUPS_ENAB, kemudian mengubah digit group untuk setiap akun non-root yang primary group-nya memiliki nama yang sama dengan akun tersebut. Jalankan grep -rn pam_umask /etc/pam.d/ dan id -un; id -gn untuk melihat aturan mana yang berlaku pada akun Anda.

Apakah umask dapat membuat file menjadi executable?

Tidak. Mask hanya dapat menghapus bit dari permission yang diminta oleh program pembuat file. touch tidak pernah meminta execute bit, sehingga tidak ada mask yang dapat menghasilkan file executable. Pastikan hal ini di direktori sementara dengan ( umask a=rwx; touch f; stat -c '%a %A' f ). Untuk mendapatkan execute bit, Anda memerlukan chmod, atau program seperti install -m yang memintanya saat membuat file.

Di mana saya menetapkan umask untuk service systemd?

Pada unit, gunakan UMask= dalam section [Service]. Service dijalankan oleh service manager, bukan melalui login. Karena itu, file startup shell tidak pernah dibaca dan pam_umask tidak pernah berjalan untuk service tersebut. Setelah systemctl daemon-reload dan unit di-restart, lakukan konfirmasi dari luar: biarkan service membuat file, lalu baca hasilnya dengan stat -c '%a %n'.

Apakah default mask yang mengizinkan group write aman?

Mask tersebut aman selama group hanya memiliki satu anggota. Inilah asumsi di balik skema user private group. Jika Anda menambahkan akun kedua ke group tersebut, setiap file yang dibuat akun pertama langsung dapat ditulis oleh anggota baru itu, tanpa perlu menjalankan command apa pun pada file tersebut. Jalankan id -un dan id -gn: jika keduanya menampilkan nama yang sama, berarti Anda menggunakan private group. Jika satu group digunakan bersama oleh beberapa akun, tetapkan mask yang menghapus group write bit. Setelah itu, buat sebuah file dan baca stat -c '%a %n' untuk memastikan perubahan diterapkan.

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