Linux میں umask: default permissions کہاں سے آتی ہیں؟
umask ہر نئی file اور directory کا mode بدلتا ہے۔ اسے print کریں، file اور directory بنائیں، modes پڑھیں، اور سمجھیں کہ root اور آپ کے user کے نتائج کیوں مختلف ہیں۔
Linux میں umask کیا کرتا ہے
umask ایک عدد ہے جو Linux میں ہر process کے ساتھ موجود ہوتا ہے۔ یہ اس process کی بنائی ہوئی ہر file اور directory کا mode متعین کرتا ہے۔ پروگرام file یا directory بناتے وقت kernel سے permissions کا ایک set طلب کرتا ہے۔ kernel mask میں نامزد ہر bit کو clear کر دیتا ہے اور باقی bits لاگو کرتا ہے۔ umask کبھی access فراہم نہیں کرتا۔ یہ صرف وہ bits ہٹاتا ہے جو بنانے والے پروگرام نے طلب کی ہوں۔
یہ value آپ کی distribution کی property نہیں ہے۔ اس کا انحصار اس بات پر ہوتا ہے کہ آپ کس account کے طور پر کام کر رہے ہیں اور shell کس طرح شروع کیا گیا تھا۔ ایک ہی machine پر، ایک ہی وقت میں، stock image کے باوجود ان دونوں کے نتائج مختلف ہو سکتے ہیں۔ اس لیے پہلا قدم manual میں lookup کرنا نہیں ہے۔ پہلے اپنے سامنے موجود box پر اس کی پیمائش کریں۔
آپ جس shell میں موجود ہیں، اس میں umask دکھائیں
umask
umask -Sپہلی صورت mask کو octal میں دکھاتی ہے۔ دوسری صورت اسی mask کو ان permissions کی شکل میں دکھاتی ہے جن کی یہ اجازت دیتا ہے، یعنی وہ symbolic form جسے chmod قبول کرتا ہے۔ دونوں سطریں اسکرین پر رہنے دیں۔ ذیل کی تمام باتیں اسی output کے ساتھ موازنہ ہیں جو آپ کے shell نے ابھی دکھایا ہے۔
umask ایک shell builtin ہے، disk پر موجود program نہیں۔ type umask سے اس کی تصدیق کریں۔ یہ اس لیے اہم ہے کہ builtin خود shell process میں تبدیلی کرتا ہے۔ الگ program صرف اپنے process میں تبدیلی کر سکتا ہے، پھر exit ہو کر وہ تبدیلی اپنے ساتھ ختم کر دیتا ہے۔
ایک فائل اور ایک directory بنائیں، پھر modes دوبارہ پڑھیں
cd "$(mktemp -d)"
touch probe.file
mkdir probe.dir
stat -c '%a %A %n' probe.file probe.dir%a mode کو octal میں دکھاتا ہے، جبکہ %A اسی mode کو drwxr-xr-x فارمیٹ میں دکھاتا ہے جسے ls -l استعمال کرتا ہے۔ دونوں سطروں کا کچھ دیر پہلے دکھائے گئے mask سے موازنہ کریں۔ mask میں set ہر bit modes میں موجود نہیں ہوتی، کیونکہ mask صرف انہی bits کو clear کر سکتا ہے۔ اگر %A column ابھی واضح طور پر پڑھنا مشکل ہو تو پہلے drwxr-xr-x permission string کو سمجھ لیں۔
فائل اور directory ایک دوسرے سے مختلف ہیں، اور mask اس فرق کی وجہ نہیں ہے۔ touch kernel سے owner، group اور other کے لیے read اور write مانگتا ہے۔ mkdir تینوں کے لیے read، write اور execute مانگتا ہے۔ ایک ہی mask دو مختلف درخواستوں سے منہا ہوتا ہے۔ اس لیے touch سے بنائی گئی فائل کبھی executable نہیں ہوتی، mask کی قدر کچھ بھی ہو: execute bit کی درخواست ہی نہیں کی گئی تھی، اور mask کسی bit کو دوبارہ شامل نہیں کر سکتا۔
( umask a=rwx; touch open.file; stat -c '%a %A %n' open.file )قوسین کے اندر موجود commands ایک subshell میں چلتے ہیں، اس لیے تبدیلی اسی کے ختم ہونے کے ساتھ ختم ہو جاتی ہے۔ اب mask میں clear کرنے کے لیے کچھ نہیں ہے، لیکن stat پھر بھی فائل پر execute bit موجود نہ ہونے کی اطلاع دیتا ہے۔ اس کے بعد umask دوبارہ چلائیں تو آپ کی اصل قدر واپس آ جاتی ہے۔ اس سے ظاہر ہوتا ہے کہ یہ setting کسی file system پر محفوظ نہیں ہوتی، بلکہ process کے اندر رہتی ہے اور child processes کو inherit ہوتی ہے۔
Directories میں clear کیا گیا execute bit نمایاں اثر ڈالتا ہے۔
( umask a=rw; mkdir noexec.dir; cd noexec.dir )عام user کے طور پر cd، bash: cd: noexec.dir: Permission denied کے ساتھ ناکام ہو جاتا ہے، کیونکہ mask نے وہ execute bit clear کر دی جس کی درخواست mkdir نے کی تھی، اور execute bit کے بغیر directory میں داخل نہیں ہوا جا سکتا۔ root یہ check نظرانداز کرتا ہے، اس لیے یہ مسئلہ صرف عام account پر ظاہر ہوتا ہے۔
root اور آپ کے اپنے user کو مختلف umask کیوں نظر آتا ہے
اسی measurement کو دوسرے account کے ذریعے چلائیں، اسے مختلف طریقے سے شروع کریں، اور دونوں outputs کو ساتھ ساتھ پڑھیں۔
umask
sudo -i umasksudo -i root کا login shell شروع کرتا ہے اور اسی کے اندر builtin چلاتا ہے، اس لیے یہ مختلف startup path سے آنے والا مختلف account ہے۔ stock Ubuntu اور Debian server images میں دونوں lines مختلف values دکھا سکتی ہیں۔ دونوں lines درست ہیں۔ ہر line دکھاتی ہے کہ اس کے اپنے startup path نے کیا output پیدا کیا، اور اس post کے باقی حصے میں یہی بتایا گیا ہے کہ system کے کس حصے نے وہ output پیدا کیا۔
آپ کی image میں قدر کا تعین کس file نے کیا
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'اگر پہلی grep کوئی output نہ دے تو اسے ^ anchor کے بغیر دوبارہ چلائیں: ممکن ہے یہ line comment کی گئی ہو، اور comment کی گئی line configuration نہیں بلکہ documentation ہوتی ہے۔ تیسری grep وہ ہے جو اکثر لوگوں کو حیران کرتی ہے۔ Debian اور Ubuntu پر shipped /etc/profile عموماً خود mask set کرنے کے بجائے PAM کی طرف اشارہ کرتی ہے، اس لیے جو file آپ کو ذمہ دار معلوم ہو رہی تھی، اکثر وہ ذمہ دار نہیں ہوتی۔ grep کو کچھ match نہ ہونے پر non-zero exit status ملتا ہے، اسی لیے یہ line || echo پر ختم ہوتی ہے: ایسی image میں جہاں کسی startup file میں mask کا ذکر نہ ہو، آپ کو خاموشی کے بجائے message ملتا ہے، اور یہی message finding ہے۔
/etc/login.defs ایک قدر تجویز کرتا ہے، جبکہ PAM دوسری قدر نافذ کرتا ہے
`/etc/login.defs میں موجود UMASK وہ قدر ہے جسے زیادہ تر رہنما دستاویزات نقل کرتی ہیں۔ نہ kernel اور نہ ہی shell اس فائل کو پڑھتا ہے۔ اسے pam_umask پڑھتا ہے، جو PAM (pluggable authentication modules) کا ایک module ہے اور session بننے کے وقت چلتا ہے۔ pam_umask پہلی دستیاب قدر استعمال کرتا ہے: صارف کے GECOS field میں موجود umask= entry، پھر خود pam_umask.so line پر لکھی گئی umask= argument، اور آخر میں /etc/login.defs سے حاصل ہونے والی UMASK قدر۔ Distributions اس module میں تبدیلیاں کرتی ہیں، اس لیے اپنی image پر man pam_umask` چلائیں اور وہاں دکھائی گئی ترتیب پڑھیں۔
اسی وجہ سے `/etc/login.defs ایک قدر تجویز کر سکتا ہے، جبکہ آپ کا session کسی دوسری قدر کے ساتھ شروع ہو سکتا ہے، اور دونوں میں سے کوئی بھی warning نہیں دکھاتا۔ grep commands سے معلوم ہوتا ہے کہ آپ کس صورتِ حال میں ہیں۔ اگر pam_umask.so line میں اپنی umask= argument موجود ہو تو login.defs` والی line مؤثر نہیں رہتی۔
USERGROUPS_ENAB اور root کا استثنا
id -un
id -gnاگر یہ دونوں ایک ہی نام دکھائیں تو آپ کے پاس user private group ہے: اکاؤنٹ کو اسی نام کے group کے ساتھ بنایا گیا تھا۔ pam_umask کا usergroups رویہ /etc/login.defs میں موجود USERGROUPS_ENAB کے ذریعے کنٹرول ہوتا ہے۔ جب یہ فعال ہو، اکاؤنٹ root نہ ہو، اور primary group کا نام user name سے مطابقت رکھتا ہو، تو module mask کے owner digit کو group digit میں نقل کر دیتا ہے۔ اس کے بعد session ایسی mask کے ساتھ ختم ہوتا ہے جو اس اکاؤنٹ کی بنائی ہوئی ہر چیز پر group bits کھلی چھوڑتی ہے۔ module خود root کو خارج کرتا ہے، اور یہی استثنا ایک ہی server پر دو shells کے مختلف masks دکھانے کی سب سے عام واحد وجہ ہے۔
اس rule کی بنیاد یہ ہے کہ private group میں صرف ایک member ہوتا ہے، اس لیے group-writable کا مطلب صرف owner-writable ہوتا ہے۔ یہ صورت اس وقت تک برقرار رہتی ہے جب تک کوئی دوسرا member اس group میں شامل نہ کیا جائے۔ اس لمحے سے اکاؤنٹ کی بنائی ہوئی ہر file نئے member کے لیے writable ہو جاتی ہے، حالانکہ ان files پر ایسا کرنے کے لیے کوئی command نہیں چلائی گئی تھی۔ ہر service کو اپنا least-privilege user account دیں، تاکہ یہ group جان بوجھ کر صرف ایک member کا group رہے۔
لاگ اِن shell، non-login shell اور non-interactive shell
umask
bash -lc 'umask'
bash -c 'umask'PAM اس وقت چلتا ہے جب session بنایا جاتا ہے: login کنسول پر، sshd، su، sudo -i۔ ایک shell کے دوسرے shell کو شروع کرنے پر PAM نہیں چلتا۔ bash -l ایک لاگ اِن shell ہے، اس لیے یہ /etc/profile اور ~/.profile پڑھتا ہے، لیکن یہ کبھی pam_umask کو کال نہیں کرتا، کیونکہ کوئی session نہیں بنایا گیا تھا۔ bash -c دونوں میں سے کوئی فائل نہیں پڑھتا اور اسے شروع کرنے والے process کا mask وراثت میں ملتا ہے۔ cron job، git hook اور service manager کے ذریعے شروع کیا گیا program، سب اسی آخری صورت میں آتے ہیں؛ اس لیے ان کا mask وہی ہوتا ہے جو ان کے parent process کا تھا۔
اسی وجہ سے یہ شکایت عام ہے: "میں نے اسے /etc/profile میں set کیا، لیکن service پھر بھی غلط mode میں لکھتی ہے۔" service نے وہ فائل کبھی پڑھی ہی نہیں۔
جہاں اسے ترتیب دیں تاکہ یہ برقرار رہے
umask کو اسی جگہ ترتیب دیں جہاں workload حقیقت میں شروع ہوتا ہے، کیونکہ ہر start path الگ file پڑھتا ہے۔
- لاگ اِن کرنے والے accounts کے لیے:
UMASKکو/etc/login.defsمیں ترتیب دیں؛ pam_umask اسے machine پر ہر session پر لاگو کرتا ہے۔ یہ machine-wide ترتیب ہے، اس لیے یہ تمام accounts کو بیک وقت متاثر کرتی ہے۔ - ایک account کے لیے:
pam_umask.soline میں موجودumask=argument بھی machine-wide ہے، اس لیے per-user value اس user کے GECOS field میں، یا login shells کے لیے~/.profileاور interactive shells کے لیے~/.bashrcمیں ہونی چاہیے۔ - systemd کے تحت چلنے والے daemon کے لیے: unit کے
[Service]section میںUMask=ترتیب دیں۔ unit کو service manager شروع کرتا ہے، اس لیے/etc/profileکبھی نہیں پڑھی جاتی اور pam_umask بھی نہیں چلتا۔ ان تمام options میں صرف unit file ہی daemon تک پہنچتی ہے۔ - cron یا کسی hook سے چلنے والی script کے لیے: پہلی line پر، script کے کچھ بھی create کرنے سے پہلے، واضح
umaskلکھیں۔
[Service]
UMask=<the octal mask you chose>اس کے بعد اسی path کو fresh start سے verify کریں، اور اس shell سے کبھی verify نہ کریں جس میں آپ نے file edit کی تھی۔ موجودہ shell پہلے ہی اپنا umask برقرار رکھتی ہے، اور config file میں تبدیلی چلتے ہوئے process تک واپس نہیں پہنچتی۔
bash -lc 'umask'
sudo -i umaskchmod کے بعد کیا گیا عمل وہی حل کیوں نہیں ہے
chmod صرف موجودہ فائلوں کی permissions درست کرتا ہے۔ Mask ان فائلوں کا mode طے کرتا ہے جو ابھی موجود نہیں ہیں۔ کسی directory پر chmod -R چلانے کے بعد service کی جانب سے لکھی جانے والی اگلی فائل دوبارہ اسی پرانے mode کے ساتھ بنے گی، کیونکہ یہ mode فائل بنانے والے process سے آیا تھا اور directory میں کوئی تبدیلی اسے متاثر نہیں کرتی۔
اس کے علاوہ درمیان میں ایک وقفہ بھی ہوتا ہے۔ فائل بننے اور chmod چلنے کے درمیان فائل disk پر وسیع mode کے ساتھ موجود رہتی ہے، اور ہر وہ process جو directory پڑھ سکتا ہے، اسے کھول سکتا ہے۔ Private key یا backup archive کے لیے یہی وقفہ وہ خطرہ ہے جسے آپ ختم کرنا چاہتے تھے۔
اس کے بجائے mode کو فائل بناتے وقت مقرر کریں۔ install -m u=rw,go= newfile /etc/app/newfile destination کو واضح mode کے ساتھ لکھتا ہے، اور mkdir -m directory کے لیے یہی کام کرتا ہے۔ دونوں آپ کے بتائے ہوئے mode کو استعمال کرتے ہیں اور mask کو نظرانداز کرتے ہیں۔ ssh-keygen اپنی لکھی ہوئی private key پر mode مقرر کرتا ہے، اسی لیے ایسی machine پر اکثر وہ ایک فائل درست ہوتی ہے جبکہ باقی فائلیں درست نہیں ہوتیں۔
عام طور پر متاثر ہونے والی سروس SSH ہے۔ سادہ mkdir سے بنایا گیا ~/.ssh، یا cat >> کے ذریعے appended کیا گیا authorized_keys، آپ کے shell کا mask اختیار کرتا ہے۔ StrictModes فعال ہونے پر sshd، group-writable directory سے key file پڑھنے سے انکار کرتا ہے۔ Client کو Permission denied (publickey) دکھایا جاتا ہے، جبکہ server کا /var/log/auth.log اصل وجہ درج کرتا ہے:
Authentication refused: bad ownership or modes for directory /home/deploy/.sshیہ check جان بوجھ کر شامل کیا گیا ہے، اور VPS پر SSH کو harden کرنا اسی check کے مؤثر رہنے پر منحصر ہے۔ نئے server پر وہ accounts بنانے سے پہلے mask کی قدر معلوم کریں جو اسے استعمال کریں گے، اور اسے نئے VPS کے پہلے دس منٹ کے ساتھ انجام دیں۔ اس طرح ان accounts کی جانب سے لکھی جانے والی ہر فائل کا mode پہلے ہی طے ہو جاتا ہے۔
کاپیاں اور archive mask کو نظرانداز کرتے ہیں
cp -p اور rsync -a source file پر درج mode بحال کرتے ہیں، اس لیے نتیجے پر mask کا کوئی اثر نہیں ہوتا۔ tar بھی یہی کرتا ہے جب وہ root کے طور پر، یا -p کے ساتھ عام user کے طور پر، files extract کرتا ہے۔ backup سے بحال کی گئی file وہی mode برقرار رکھتی ہے جو backup بناتے وقت اس کی تھی۔ یہ نتیجہ اخذ کرنے سے پہلے اس کی جانچ کریں کہ درست mask کو نظرانداز کیا جا رہا ہے: بحال کیے گئے data کے لیے mask سے کبھی مشورہ ہی نہیں کیا گیا تھا۔
FAQ
میری cron job میرے ssh session سے مختلف mode کے ساتھ فائلیں کیوں بناتی ہے؟
cron job، login session نہیں ہوتی، اس لیے اس کے لیے pam_umask نہیں چلتا، اور یہ نہ /etc/profile پڑھتی ہے نہ ~/.profile۔ یہ اس process کا mask وراثت میں لیتی ہے جس نے اسے شروع کیا تھا۔ script کی پہلی سطر میں، کسی بھی چیز کو create کرنے سے پہلے، واضح umask شامل کریں۔ پھر job کے اندر ایک بار mask print کریں، تاکہ معلوم ہو سکے کہ اس job کے پاس حقیقتاً کون سا mask ہے، نہ کہ آپ کے اپنے shell کے پاس کون سا ہے۔
/etc/login.defs میں ایک قدر کیوں ہے، جبکہ میرا shell دوسری قدر کیوں دکھاتا ہے؟
UMASK in /etc/login.defs، pam_umask کے لیے صرف آخری fallback ہے۔ module پہلے user کے GECOS field میں umask= entry، پھر /etc/pam.d/ میں pam_umask.so line پر umask= argument کو ترجیح دیتا ہے۔ USERGROUPS_ENAB سے فعال ہونے والا usergroups behaviour، اس کے بعد ہر non-root account کے group digit کو تبدیل کرتا ہے، اگر اس کا primary group اسی account کے نام پر ہو۔ اپنے account پر لاگو قدر دیکھنے کے لیے grep -rn pam_umask /etc/pam.d/ اور id -un; id -gn چلائیں۔
کیا umask کسی فائل کو executable بنا سکتا ہے؟
نہیں۔ mask صرف ان bits کو clear کر سکتا ہے جن کے لیے فائل بنانے والے program نے درخواست کی ہو۔ touch execute bit کی درخواست کبھی نہیں کرتا، اس لیے کوئی بھی mask executable file نہیں بنا سکتا۔ عارضی directory میں ( umask a=rwx; touch f; stat -c '%a %A' f ) کے ذریعے اس کی تصدیق کریں۔ execute bit حاصل کرنے کے لیے chmod درکار ہے، یا install -m جیسا کوئی program چاہیے جو creation کے وقت اس کی درخواست کرے۔
systemd service کے لیے umask کہاں set کروں؟
unit میں، [Service] section کے اندر UMask= کے ذریعے۔ service کو login کے بجائے service manager شروع کرتا ہے، اس لیے shell startup files کبھی نہیں پڑھی جاتیں اور pam_umask اس کے لیے نہیں چلتا۔ systemctl daemon-reload اور unit کو restart کرنے کے بعد باہر سے تصدیق کریں: service کو ایک file بنانے دیں، پھر stat -c '%a %n' کے ذریعے نتیجہ پڑھیں۔
کیا group-writable default mask محفوظ ہے؟
یہ اس وقت محفوظ ہے جب group میں بالکل ایک member ہو، کیونکہ user private group scheme اسی مفروضے پر مبنی ہے۔ اس group میں دوسرا account شامل کریں تو پہلے account کی بنائی ہوئی ہر file نئے member کے لیے فوراً writable ہو جاتی ہے، اور ان files پر کوئی command چلانے کی ضرورت نہیں پڑتی۔ id -un اور id -gn چلائیں: اگر دونوں میں ایک ہی name print ہو تو آپ private group استعمال کر رہے ہیں۔ اگر accounts کے درمیان group share کرتے ہیں تو ایسا mask set کریں جو group write bit clear کرے۔ پھر ایک file بنائیں اور stat -c '%a %n' پڑھ کر ثابت کریں کہ تبدیلی مؤثر ہو گئی ہے۔