sudo का विकास: Unix su से आधुनिक प्रिविलेज तक
Unix के मूल su कमांड से लेकर doas, polkit और run0 तक sudo का सफ़र जानें। सुरक्षा की खामियां और बेहतरीन तरीके।

यह बात ज़्यादातर लोगों को चौंका देती है: जब आप sudo में अपना पासवर्ड टाइप करते हैं, तो कोई फीडबैक नहीं दिखता। न तारे (*), न बिंदियां, कुछ नहीं। कर्सर बस वहीं रुका रहता है। यह डिज़ाइन फैसला 1980 के दशक में लिया गया था और चार दशकों से ज़्यादा समय से यूज़र्स को उलझा रहा है। लोग अक्सर सोचते हैं कि उनका टर्मिनल हैंग हो गया है, वे पासवर्ड कई बार टाइप करते हैं, या मान लेते हैं कि कुछ टूट गया है। आख़िरकार Ubuntu ने डिफ़ॉल्ट रूप से तारे दिखाने का फैसला किया — 46 साल की उस परंपरा का अंत, जिसमें पासवर्ड चुपचाप डाला जाता था।
यह छोटा-सा बदलाव एक बड़ी बात की ओर इशारा करता है: Linux में privilege escalation का तरीका दशकों में लिए गए फैसलों का एक पैचवर्क है। कुछ फैसले शानदार थे, कुछ बेहद सवालिया, और सब पर बैकवर्ड कंपैटिबिलिटी का बोझ है। हम यहां तक कैसे पहुंचे, यह समझने से आज के सुरक्षा फैसले बेहतर होते हैं।
sudo से पहले: su की दुनिया
Unix का पहला privilege escalation टूल su था — “substitute user”। इसका काम बस एक था: आपके पूरे शell सेशन को किसी दूसरे यूज़र में बदल देना, आमतौर पर root में। आप su टाइप करते, root का पासवर्ड डालते, एडमिन का काम करते और फिर अपने सामान्य अकाउंट में लौट आते।
$ su
Password: [type root's password]
# whoami
root
# apt install nginx
# exit
$ whoami
normaluser
su की समस्याएं तब साफ़ दिखने लगीं जब Unix सिस्टम कुछ भरोसेमंद ऑपरेटरों से बड़े होने लगे। जिस किसी को एडमिन एक्सेस चाहिए था, उसे root का पासवर्ड पता होना ज़रूरी था। कोई टीम छोड़ता, तो root का पासवर्ड बदलकर नया पासवर्ड सबको बांटना पड़ता। कोई ऑडिट ट्रेल नहीं था — एक बार कोई root बन जाता, तो उसके सारे काम “root” के नाम से दर्ज होते, और यह पता नहीं चलता कि असल में किसने क्या चलाया। और su पूरा root शell देता था, यानी एक छोटी-सी गलती भी पूरा सिस्टम तबाह कर सकती थी।
एक क्लासिक डरावनी कहानी: एक एडमिन rm -rf /tmp/old_files टाइप करना चाहता था, लेकिन गलती से rm -rf / के बाद एंटर दब गया। पूरे root शell में, उस कमांड को चलने से रोकने वाला कुछ नहीं होता। su इस बात में फर्क नहीं करता था कि “इसे nginx रीस्टार्ट करना है” और “इसे पूरे सिस्टम तक असीमित एक्सेस चाहिए” में क्या अंतर है।
sudo ने root पासवर्ड की समस्या कैसे सुलझाई
sudo (“superuser do”) 1980 में SUNY Buffalo में Bob Coggeshall और Cliff Spencer ने बनाया था। मूल विचार सीधा था, लेकिन इसने सब कुछ बदल दिया: root पासवर्ड बांटने के बजाय, हर यूज़र को अपने खुद के पासवर्ड से कुछ खास कमांड root के रूप में चलाने दें। कौन क्या चला सकता है, यह सिस्टम एडमिन एक कॉन्फ़िगरेशन फ़ाइल से तय करता है।
इससे एक साथ कई समस्याएं हल हो गईं:
- कोई साझा root पासवर्ड नहीं। हर यूज़र अपनी पहचान से प्रमाणित होता है। कोई टीम छोड़े, तो उसका sudo एक्सेस हटा दें। पासवर्ड बदलने की ज़रूरत नहीं।
- बारीक अनुमतियां। आप किसी डेवलपर को एक खास सर्विस रीस्टार्ट करने दे सकते हैं, बिना उसे पूरा root एक्सेस दिए।
- ऑडिट ट्रेल। हर sudo कमांड उस यूज़रनेम, चलाई गई कमांड और समय के साथ लॉग होती है।
- अस्थायी एस्केलेशन। एक खुले root शell के बजाय, sudo एक ही कमांड को बढ़े हुए अधिकारों के साथ चलाता है और फिर सामान्य स्थिति में लौट आता है।
# Run a single command as root
$ sudo apt install nginx
[sudo] password for priya:
# That's YOUR password, not root's
# The audit trail in /var/log/auth.log:
# Mar 20 14:23:01 web-03 sudo: priya : TTY=pts/0 ;
# PWD=/home/priya ; USER=root ; COMMAND=/usr/bin/apt install nginx
sudoers फ़ाइल: शक्तिशाली और खतरनाक
sudo की कॉन्फ़िगरेशन /etc/sudoers में रहती है, और इसका सिंटैक्स Linux एडमिनिस्ट्रेशन की सबसे उलझी हुई चीज़ों में से एक है। एक छोटी-सी सिंटैक्स गलती आपको sudo से पूरी तरह बाहर कर सकती है, इसीलिए visudo कमांड मौजूद है — यह सेव करने से पहले फ़ाइल को वैलिडेट करता है।
# /etc/sudoers syntax:
# WHO WHERE = (AS_WHOM) WHAT
# Let priya run anything as root on any host
priya ALL=(ALL:ALL) ALL
# Let the 'webdev' group restart nginx only
%webdev ALL=(root) /usr/bin/systemctl restart nginx,\
/usr/bin/systemctl reload nginx
# Let deploy user run deploys without a password
deploy ALL=(root) NOPASSWD: /opt/deploy/run.sh
# DANGEROUS: This looks restrictive but isn't
bob ALL=(root) /usr/bin/vim
# Bob can now run: sudo vim, then :!bash to get a root shell
वह आख़िरी उदाहरण — किसी को vim के लिए sudo एक्सेस देना — एक सुरक्षा खामी है जो लोगों को लगातार फंसाती है। Vim (और कई दूसरे प्रोग्राम) शell कमांड स्पॉन कर सकते हैं। अगर कोई यूज़र sudo vim चला सकता है, तो उसके पास व्यावहारिक रूप से असीमित root एक्सेस है। यही बात less, man, awk, find, python और दर्जनों दूसरी कमांड पर भी लागू होती है। GTFOBins प्रोजेक्ट ऐसे बाइनरी की व्यापक सूची रखता है जिनका इस्तेमाल प्रतिबंधित शell से बाहर निकलने के लिए किया जा सकता है।
sudo की अजीब आदतें और सुरक्षा खामियां
40 से ज़्यादा सालों के इतिहास में sudo ने कुछ सचमुच अजीब व्यवहार जमा कर लिए हैं। सुरक्षा के लिए इन्हें समझना ज़रूरी है:
- क्रेडेंशियल कैशिंग। पासवर्ड डालने के बाद sudo उसे डिफ़ॉल्ट रूप से 15 मिनट तक कैश करता है। उस दौरान कोई भी sudo कमांड बिना प्रमाणीकरण के चल जाती है। अगर आप अनलॉक्ड टर्मिनल छोड़कर चले जाते हैं, तो कोई भी 15 मिनट तक sudo कमांड चला सकता है। कैश तुरंत हटाने के लिए
sudo -kचलाएं। - tty_tickets सेटिंग। डिफ़ॉल्ट रूप से sudo का कैश हर टर्मिनल के लिए अलग होता है। लेकिन कुछ सिस्टम पर एक टर्मिनल में प्रमाणीकरण करने से सभी टर्मिनलों में sudo खुल जाता है। अपनी
Defaultsसेटिंग्स जांच लें। - एनवायरनमेंट वेरिएबल। sudo ज़्यादातर एनवायरनमेंट वेरिएबल साफ़ कर देता है, पर सभी नहीं।
LD_PRELOADऔरLD_LIBRARY_PATHहटा दिए जाते हैं, लेकिन अगरenv_keepगलत कॉन्फ़िगर हो, तो हमलावर खतरनाक लाइब्रेरी पाथ डाल सकता है। कई असली privilege escalation exploits इसी पर आधारित रहे हैं। - NOPASSWD का जाल।
NOPASSWDऑटोमेशन के लिए सुविधाजनक है, पर इसे बहुत व्यापक रूप से लगाना खतरनाक है।NOPASSWDsudo एक्सेस वाले यूज़र के रूप में चलने वाला समझौता किया हुआ ऐप्लिकेशन व्यावहारिक रूप से root होता है — तोड़ने के लिए कोई पासवर्ड ही नहीं।
# Security hardening for sudoers:
# Require password every time (disable caching)
Defaults timestamp_timeout=0
# Or reduce cache to 1 minute
Defaults timestamp_timeout=1
# Ensure credential cache is per-terminal
Defaults tty_tickets
# Log all sudo I/O (records full terminal sessions)
Defaults log_input, log_output
Defaults iolog_dir=/var/log/sudo-io
# Require root password instead of user password
# (prevents compromised user accounts from sudo-ing)
Defaults rootpw
# Show asterisks when typing password
Defaults pwfeedback
आधुनिक विकल्प: doas, polkit और run0
sudo की जटिलता ने कई विकल्पों को जन्म दिया है, और हर एक का दर्शन अलग है।
doas: बिना जटिलता का sudo
OpenBSD का doas (“dedicated OpenBSD application subexecutor”) Ted Unangst ने 2015 में बनाया, क्योंकि sudo ऑडिट करने के लिए बहुत जटिल हो गया था। पूरी कॉन्फ़िगरेशन आम तौर पर 2-3 लाइनों की होती है:
# /etc/doas.conf — the entire configuration
permit persist priya
permit nopass deploy as root cmd /opt/deploy/run.sh
# That's it. Compare this to a typical sudoers file.
# 'persist' is like sudo's credential caching
# 'nopass' is like NOPASSWD
doas का सोर्स कोड लगभग 2,500 लाइन C का है। sudo का 150,000 से ज़्यादा है। जिन सिस्टम पर आपको sudo के उन्नत फीचर्स (जैसे प्रति-कमांड आर्गुमेंट मैचिंग या LDAP इंटीग्रेशन) नहीं चाहिए, वहां doas कॉन्फ़िगर, ऑडिट और सुरक्षित करने में कहीं आसान है। मैं इसे अपने निजी सर्वरों पर सालों से इस्तेमाल कर रहा हूं और sudo की कमी एक बार भी नहीं खली।
polkit: बारीक डेस्कटॉप अनुमतियां
PolicyKit (polkit) एक बिल्कुल अलग तरीका अपनाता है। यह व्यक्तिगत कमांड को रैप करने के बजाय actions परिभाषित करता है, जिन्हें ऐप्लिकेशन मांग सकते हैं। जब कोई डेस्कटॉप ऐप नेटवर्क सेटिंग्स बदलना चाहता है, तो वह polkit से अनुमति मांगता है, और polkit अपने नियमों के आधार पर तय करता है कि अनुमति दे, मना करे, या यूज़र से पूछे।
Linux डेस्कटॉप आपको बिना पासवर्ड के USB ड्राइव माउंट करने देता है, पर सॉफ़्टवेयर इंस्टॉल करने के लिए प्रमाणीकरण मांगता है — यह इसी का नतीजा है। ग्रैन्युलैरिटी command स्तर पर नहीं, action स्तर पर है, जो डेस्कटॉप यूज़र्स के अनुमति के बारे में सोचने के तरीके से ज़्यादा मेल खाती है।
run0: systemd की क्रांतिकारी पुनर्कल्पना
systemd का run0 सबसे नई एंट्री है, और यह sudo से मूल रूप से अलग काम करता है। मौजूदा सेशन से root के रूप में कमांड चलाने के बजाय (जिसमें setuid bits चाहिए और सुरक्षा की नई दिक्कतें आती हैं), run0 सर्विस मैनेजर से कहता है कि root के रूप में चलने वाली नई सर्विस स्पॉन करे। आपका यूज़र सेशन कभी elevated privileges नहीं पाता — privileged प्रोसेस पूरी तरह अलग होती है।
इससे sudo की कमज़ोरियों की पूरी श्रेणियां बच जाती हैं। कोई setuid बाइनरी नहीं, कोई क्रेडेंशियल कैशिंग नहीं, एनवायरनमेंट वेरिएबल इंजेक्शन की कोई सतह नहीं। इसकी कीमत यह है कि इसके लिए systemd चाहिए, जिससे यह BSD सिस्टम और न्यूनतम Linux सेटअप के लिए उपयुक्त नहीं। पर systemd-आधारित सर्वरों के लिए यह शायद उपलब्ध सबसे सुरक्षित विकल्प है।
व्यावहारिक सुझाव
Linux सर्वर संभालने और privilege escalation घटनाओं की जांच करने के वर्षों के बाद, मैं असल में यह सुझाऊंगा:
- root लॉगिन पूरी तरह बंद करें। हर काम के लिए
sudoयाdoasइस्तेमाल करें। कोई साझा root पासवर्ड नहीं होना चाहिए। - sudoers में व्यक्तिगत यूज़र के बजाय ग्रुप इस्तेमाल करें। ग्रुप मेंबरशिप से एक्सेस मैनेज करें। कोई छोड़े, तो उसे ग्रुप से हटा दें।
- इंटरप्रेटर या एडिटर को कभी sudo एक्सेस न दें।
sudo vim,sudo python,sudo lessनहीं। अगर root की मालिकाना फ़ाइल एडिट करनी हो, तोsudoeditइस्तेमाल करें। - NOPASSWD नियम कम से कम रखें। इन्हें सिर्फ़ ऑटोमेटेड प्रोसेस के लिए, और सिर्फ़ पूरे पाथ वाली खास कमांड के लिए इस्तेमाल करें।
- sudo लॉगिंग चालू करें। कम से कम सभी sudo कमांड लॉग करें। संवेदनशील सिस्टम पर पूरी I/O लॉगिंग चालू करें।
- सरल सिस्टम के लिए doas पर विचार करें। अगर आपको LDAP इंटीग्रेशन या जटिल मैचिंग नियमों की ज़रूरत नहीं, तो doas सही तरीके से कॉन्फ़िगर करना आसान है।
- क्रेडेंशियल कैश को आक्रामक रूप से रोटेट करें।
timestamp_timeoutको 1-5 मिनट तक घटाएं, या प्रोडक्शन सर्वरों पर कैशिंग पूरी तरह बंद करें।
सबसे अच्छा privilege escalation तंत्र वह है जो ज़रूरी न्यूनतम एक्सेस दे, ज़रूरी न्यूनतम समय के लिए दे, और उसका पूरा ऑडिट ट्रेल हो। बाकी सब समझौता है।
sudo कहीं जाने वाला नहीं है। यह स्क्रिप्ट, ऑटोमेशन, डॉक्यूमेंटेशन और आदतों में इतना गहराई तक बसा है कि गायब नहीं हो सकता। लेकिन विकल्पों का परिदृश्य पहले से कहीं ज़्यादा स्वस्थ है। चाहे आप sudo को ठीक से हार्डन करके इस्तेमाल करें, सादगी के लिए doas अपनाएं, या सुरक्षा-संवेदनशील सिस्टम के लिए run0 चुनें, सबसे ज़रूरी बात यह समझना है कि आपका privilege escalation टूल असल में क्या करता है — क्योंकि जो लोग सोचते हैं कि sudo क्या करता है और वह असल में क्या करता है, उस खाई में ही ज़्यादातर सुरक्षा घटनाएं छिपी होती हैं।


