Ubuntu 26.04 पर sudo-rs के कारण sudoers में क्या बदलें
Ubuntu 26.04 में sudo-rs डिफ़ॉल्ट है। यदि आपकी sudoers फ़ाइल में वाइल्डकार्ड आर्गुमेंट हैं तो वे काम नहीं करेंगे। जानें कि नए नियमों के लिए अपनी कॉन्फ़िगरेशन को कैसे अपडेट करें।
Ubuntu पर sudo-rs क्या बदलाव लाता है
Ubuntu 26.04 LTS में sudo-rs को डिफ़ॉल्ट sudo के रूप में शामिल किया गया है, इसलिए एक नए सर्वर पर sudo कमांड चलाने पर मूल C प्रोग्राम के बजाय Rust में फिर से लिखा गया (reimplementation) संस्करण चलता है। अधिकांश sudoers फाइलें पहले की तरह ही काम करती रहती हैं। जो नियम काम करना बंद कर देता है, वह वह है जिसमें कमांड के तर्कों (arguments) के भीतर वाइल्डकार्ड का उपयोग किया गया हो, क्योंकि sudo-rs तर्क टेक्स्ट के विरुद्ध ग्लोब पैटर्न (glob patterns) का मिलान नहीं करता है।
Ubuntu 25.10 ने सबसे पहले यह बदलाव किया था और 26.04 LTS ने इसे बरकरार रखा है। Ubuntu 24.04 LTS इससे प्रभावित नहीं है, क्योंकि यह अभी भी मूल sudo का ही उपयोग करता है, जब तक कि आप स्वयं sudo-rs इंस्टॉल न करें। यह स्थिति तब महत्वपूर्ण हो जाती है जब आप Ubuntu 24.04 से 26.04 पर अपग्रेड करते हैं, या जब आप नए रिलीज़ पर एक नया सर्वर तैयार करते हैं। यदि आप बीच के रिलीज़ (interim releases) का भी उपयोग करते हैं, तो सर्वर पर LTS और अंतरिम Ubuntu रिलीज़ कैसे भिन्न होते हैं यह स्पष्ट करता है कि कौन सी मशीन इस तरह के बदलाव का सामना सबसे पहले करती है।
जांचें कि आपका सर्वर वास्तव में कौन सा sudo चला रहा है
इसे release number से निर्धारित न करें। मशीन से पूछें।
sudo --version
update-alternatives --config sudo
dpkg -l 'sudo*'इंटरनेट पर मौजूद किसी भी version table के बजाय, अपने बॉक्स पर sudo --version पर भरोसा करें। update-alternatives --config sudo उत्तर का दूसरा हिस्सा है: यह /usr/bin/sudo के सभी installed providers को सूचीबद्ध करता है और चुने गए provider को चिह्नित करता है। किसी package का installed होना और उसका selected होना एक समान नहीं है, इसलिए package list के बजाय selection को पढ़ें।
transition के दौरान दोनों implementations को package किया गया है। Rust वाला implementation sudo-rs है, जो अगस्त 2026 तक 26.04 में version 0.2.13 पर है। मूल implementation, जिसे Todd C. Miller द्वारा maintain किया जाता है, उसे sudo.ws के रूप में package किया गया है, और इसके programs में .ws suffix होता है: sudo.ws और visudo.ws।
Ubuntu ने sudo-rs पर स्विच क्यों किया
sudo एक setuid root प्रोग्राम है। इसे सिस्टम का कोई भी user शुरू कर सकता है और यह पूर्ण विशेषाधिकारों (full privileges) के साथ चलता है, इसलिए इसके भीतर मौजूद कोई भी memory bug एक local root exploit बन सकता है। CVE-2021-3156 बिल्कुल ऐसा ही एक मामला था: यह एक heap buffer overflow था जिसे कोई भी local user trigger कर सकता था, और यह लगभग दस वर्षों तक released code में मौजूद रहा। Rust इस प्रकार के बग्स को compile time पर ही पकड़ लेता है, और यही इस rewrite का मुख्य आधार है।
दूसरा कारण scope है, और यही वह बिंदु है जो आपके configuration को प्रभावित करता है। मूल sudo ने तीन दशकों में बहुत सारे features एकत्र कर लिए हैं, और हर feature का मतलब है root के रूप में चलने वाला अधिक code। sudo-rs जानबूझकर केवल एक subset को implement करता है। जिन features को इसके लेखकों ने niche या हानिकारक माना, उन्हें हटा दिया गया है, इसलिए sudoers का जो नियम वर्षों से काम कर रहा था, वह अब मौजूद नहीं हो सकता है। आपका wildcard rule उन्हीं में से एक है।
Memory safety बग्स की एक श्रेणी को खत्म करती है। यह किसी प्रोग्राम को पूरी तरह से बग-मुक्त नहीं बनाती है, और sudo-rs के default बनने के बाद से इसमें भी security fixes जारी किए गए हैं। इसे किसी भी अन्य software की तरह ही patch करते रहें।
कौन से sudoers नियम अभी भी काम करते हैं
यह फाइल वही फाइल है। sudo-rs, /etc/sudoers और /etc/sudoers.d/ में मौजूद drop-in फाइलों को पढ़ता है, और एक सर्वर ऑपरेटर द्वारा लिखी जाने वाली सामान्य चीजें समर्थित हैं:
deploy ALL=(ALL:ALL) ALL, और समूह के रूप जैसे%sudo ALL=(ALL:ALL) ALLNOPASSWD:औरPASSWD:टैगUser_Alias,Runas_Alias,Host_AliasऔरCmnd_Alias- सटीक तर्क सूची (argument list) वाला कमांड, उदाहरण के लिए
/usr/bin/systemctl restart app-api ""के बाद आने वाला कमांड, जो कमांड को बिना किसी तर्क के चलाने की अनुमति देता है- अंतिम तर्क के रूप में
*के साथ आने वाला कमांड, जो किसी भी बाद के तर्कों की अनुमति देता है /पर समाप्त होने वाला डायरेक्टरी पाथ, जो उस डायरेक्टरी में किसी भी कमांड की अनुमति देता है- सूची से किसी कमांड को हटाने के लिए
! Defaultsका एक उपयोगी सबसेट, जिसमेंsecure_path,env_keep,env_check,timestamp_timeout,passwd_tries,editor,umask,targetpw,rootpwऔरuse_ptyशामिल हैं
दो defaults अलग तरह से व्यवहार करते हैं और लोगों को भ्रमित करते हैं। env_reset को sudo-rs में बंद नहीं किया जा सकता: यह हमेशा चालू रहता है। use_pty डिफ़ॉल्ट रूप से चालू रहता है, इसलिए कमांड अपने स्वयं के pseudo-terminal में चलता है।
आपका wildcard sudoers rule मैच करना क्यों बंद हो गया
Wildcards अभी भी एक जगह मान्य हैं: command का file name। %ops ALL = /sbin/fsck* का rule अभी भी sudo fsck और sudo fsck_exfat की अनुमति देता है, क्योंकि * उस path का हिस्सा है जिसे filesystem के विरुद्ध मैच किया जा रहा है।
Argument list के अंदर, sudo-rs केवल दो विशेष रूपों को स्वीकार करता है, और उनमें से कोई भी pattern नहीं है। "" का अर्थ है कोई arguments नहीं। अंत में लगा * किसी भी trailing arguments को दर्शाता है। हर दूसरे argument की तुलना literal text के रूप में की जाती है। इसलिए %ops ALL = /sbin/service ntp * ठीक है, क्योंकि ntp literal है और * अंत में है। हालाँकि, इस तरह का rule आपको वह नहीं देता जो आप चाहते थे:
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart app-*app-* एक argument के बीच में एक pattern है। sudo-rs इसे expand नहीं करता है, इसलिए यह rule systemctl restart app-api को कवर नहीं करता है और sudo command को अस्वीकार कर देता है। दो commands आपको अपने सर्वर पर किसी भी rule के बारे में सही जानकारी देती हैं: root के रूप में चलाई गई sudo -l -U deploy यह प्रिंट करती है कि वह account वास्तव में क्या चला सकता है, और sudo visudo -c यह बताता है कि क्या file सही ढंग से parse हो रही है। बिना सोचे-समझे editing शुरू करने से पहले इन्हें चलाएँ।
Wildcard नियम हमेशा से एक खामी रहा है
मूल sudo के अंतर्गत, आपके द्वारा टाइप किए गए arguments को एक स्ट्रिंग में जोड़ दिया जाता है और नियम की argument स्ट्रिंग के साथ glob का उपयोग करके मिलान किया जाता है। एक glob whitespace से मेल खाता है। यह वह हिस्सा है जिसे लगभग हर कोई नजरअंदाज कर देता है।
sudo-rs documentation सबसे स्पष्ट उदाहरण देता है। /bin/rm *.txt का नियम sudo rm -rf /home .txt की भी अनुमति देता है, क्योंकि एक *, -rf /home को समाहित कर लेता है और जुड़ी हुई स्ट्रिंग का अंत अभी भी .txt पर होता है। नियम का अर्थ "केवल text files" के रूप में पढ़ा जाता है। इसका वास्तविक अर्थ है "कोई भी arguments, बशर्ते लाइन का अंत .txt पर हो"।
यही बात systemctl उदाहरण पर भी लागू होती है। चूंकि arguments की तुलना एक जुड़ी हुई स्ट्रिंग के रूप में की जाती है, इसलिए एक trailing pattern उसके बाद जोड़ी गई किसी भी चीज़ से मेल खाता है, इसलिए restart app-* में restart app-api और caller द्वारा जोड़े गए कोई भी अतिरिक्त arguments शामिल हो जाते हैं। एक argument के भीतर का pattern उसके आसपास के arguments को उजागर कर देता है, और arguments ही वे स्थान हैं जहाँ किसी command की शक्ति निहित होती है। sudo-rs इस construct को सुरक्षित बनाने का प्रयास करने के बजाय इसे अस्वीकार कर देता है, क्योंकि इसका कोई भी सामान्य रूप सुरक्षित नहीं है।
Wildcard को एक स्पष्ट कमांड सूची से बदलें
अधिकांश wildcard नियम इसलिए मौजूद होते हैं क्योंकि कोई चार लाइनें टाइप नहीं करना चाहता था। वे चार लाइनें टाइप करें।
Cmnd_Alias APP_RESTART = /usr/bin/systemctl restart app-api, /usr/bin/systemctl restart app-worker
Cmnd_Alias APP_STATUS = /usr/bin/systemctl status app-api, /usr/bin/systemctl status app-worker
deploy ALL=(root) NOPASSWD: APP_RESTART, APP_STATUSPath को सही रखें। जिस सिस्टम पर बाइनरी /usr/bin/systemctl है, वहां /bin/systemctl नाम का नियम कभी मैच नहीं होगा, और इसकी विफलता बिल्कुल permissions की समस्या जैसी दिखेगी। command -v systemctl के साथ पुष्टि करें और जो यह प्रिंट करता है उसे पेस्ट करें।
नियम को /etc/sudoers के बजाय अपनी खुद की drop-in फाइल में रखें, ताकि पैकेज अपग्रेड के दौरान आपके संपादन में कोई बाधा न आए:
sudo visudo -f /etc/sudoers.d/90-deploy
sudo visudo -c
sudo -l -U deployफाइल का नाम बिना dot और बिना trailing tilde के रखें। मूल sudo उन फाइलों को अनदेखा कर देता है जिनके नाम में dot हो, इसलिए sudoers.d में 90-deploy.conf एक क्लासिक silent no-op है, और इस परंपरा का पालन करने में कोई अतिरिक्त मेहनत नहीं लगती।
जब सूची लंबी हो जाए तो root-owned wrapper का उपयोग करें
जब allowed set इतना बड़ा हो कि उसे सूचीबद्ध करना कठिन हो, तो निर्णय लेने की प्रक्रिया को sudoers से हटाकर एक छोटे प्रोग्राम में ले जाएं जिसका स्वामी (owner) root हो।
sudo tee /usr/local/sbin/app-restart >/dev/null <<'EOF'
#!/bin/sh
set -eu
case "${1:-}" in
app-api|app-worker) ;;
*) echo "app-restart: not allowed: ${1:-}" >&2; exit 1 ;;
esac
exec /usr/bin/systemctl restart "$1"
EOF
sudo chown root:root /usr/local/sbin/app-restart
sudo chmod 0755 /usr/local/sbin/app-restart
ls -l /usr/local/sbin/app-restartइसके बाद sudoers फ़ाइल में केवल एक कमांड का नाम दें:
deploy ALL=(root) NOPASSWD: /usr/local/sbin/app-restart *यहाँ अंत में * का उपयोग स्वीकार्य है क्योंकि sudo के बजाय स्क्रिप्ट यह तय करती है कि क्या अनुमति दी जानी है। यह केवल तभी सुरक्षित है जब स्क्रिप्ट का स्वामी root हो और कोई अन्य उसे लिख (write) न सके। यदि deploy फ़ाइल में लिख सकता है, तो deploy इसकी सामग्री को बदलकर root के रूप में कुछ भी चला सकता है, जो आपके द्वारा हटाए गए wildcard नियम से भी अधिक खतरनाक है। ls -l के साथ mode की जाँच करें, और यदि आउटपुट स्पष्ट न हो, तो drwxr-xr-x अनुमति स्ट्रिंग को पढ़ना सीखने में केवल पाँच मिनट लगते हैं। यही नियम निर्देशिका (directory) पर भी लागू होता है: /usr/local/sbin भी उस खाते (account) द्वारा writable नहीं होनी चाहिए, क्योंकि एक writable निर्देशिका का अर्थ है कि फ़ाइल को पूरी तरह से बदला जा सकता है।
sudo rule के बजाय job को अपना स्वयं का account दें
बेहतर सवाल अक्सर यह होता है कि command को root की आवश्यकता ही क्यों है। जो service अपने स्वयं के user के रूप में चलती है, उसे वही user manage कर सकता है और इसमें किसी sudoers line की आवश्यकता नहीं होती। system units के लिए, systemd पहले से ही उस निर्णय को polkit को सौंप देता है, इसलिए एक rule एक unit और एक operator का नाम निर्दिष्ट कर सकती है:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
action.lookup("unit") == "app-api.service" &&
subject.user == "deploy") {
return polkit.Result.YES;
}
});इसे /etc/polkit-1/rules.d/50-app-api.rules के रूप में save करें और deploy बिना किसी sudo के systemctl restart app-api चला पाएगा। इसका परीक्षण उसी context से करें जो इसका उपयोग करेगा, क्योंकि जो rule आपके SSH session में काम करती है, उस पर भरोसा करने से पहले उसे cron से confirm करना उचित है। किसी भी स्थिति में, जो account काम कर रहा है, उसे केवल उसी काम के लिए अस्तित्व में होना चाहिए, जो VPS पर least-privilege user accounts के पीछे का मुख्य तर्क है।
sudo-rs में और क्या शामिल नहीं है
sudo -E लागू नहीं किया गया है। इसके बजाय आपको जिन variables की आवश्यकता है उन्हें Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY" के साथ नाम दें, और याद रखें कि env_reset हमेशा चालू रहता है, इसलिए जो कुछ भी सुरक्षित नहीं रखा जाता है उसे हटा दिया जाता है।
LDAP में central sudoers storage की सुविधा हटा दी गई है। sudoers.ldap और cvtsudoers लागू नहीं किए गए हैं, और sudo-ldap पैकेज को 26.04 में हटा दिया गया था। PAM या SSSD के माध्यम से LDAP authentication अभी भी काम करता है। केवल policy-in-a-directory वाला हिस्सा दायरे से बाहर है।
INTERCEPT, जो किसी अनुमत command से shell escapes को रोकने का प्रयास करता था, लागू नहीं किया गया है। यह वैसे भी किसी दृढ़निश्चयी user के खिलाफ प्रभावी नहीं था। यदि कोई rule किसी को root के रूप में editor या interpreter चलाने की अनुमति देता है, तो उनके पास root access है, और कोई भी sudo option इसे बदल नहीं सकता है।
Session recording लागू नहीं की गई है, इसलिए कोई I/O log नहीं है और न ही कोई sudoreplay है। Logging केवल syslog में जाती है, और इसे कहीं और redirect करने के लिए कोई logfile option नहीं है, इसलिए sudo संदेश वहीं जाते हैं जहाँ आपका system पहले से ही syslog भेजता है।
क्या आपको sudo.ws पर वापस जाना चाहिए?
आप ऐसा कर सकते हैं, और 26.04 cycle के दौरान मूल पैकेज इसी कारण से उपलब्ध रहता है।
sudo apt install sudo.ws
update-alternatives --config sudo
sudo update-alternatives --set sudo /usr/bin/sudo.wsइस पृष्ठ के बजाय --config output से सटीक paths को copy करें, क्योंकि वही वह सूची है जिसे आपका सिस्टम स्वीकार करेगा। बाद में sudo-rs पर वापस जाने का अर्थ है कि उसी सूची से sudo-rs binary path को alternative के रूप में सेट करना।
sudo को प्रभावित करने वाली किसी भी चीज़ को बदलने से पहले, एक दूसरा SSH session खुला रखें, जिसमें आप logged in हों और जो idle हो। यदि sudoers file parse होने में विफल रहती है, या कोई alternative ऐसी binary की ओर इशारा करता है जो installed नहीं है, तो आप remote box पर root access खो सकते हैं। यह आदत उन सभी कार्यों के साथ अपनाई जानी चाहिए जो आप नए VPS पर पहले दस मिनट में करते हैं।
वापस जाने को एक समाधान के बजाय एक समय-सीमा (deadline) के रूप में देखें। यह आपको नियमों को सही ढंग से फिर से लिखने के लिए एक सप्ताह का समय देता है, और यह rewrite अपने आप में महत्वपूर्ण है, क्योंकि आपके द्वारा हटाया गया प्रत्येक wildcard rule उससे कहीं अधिक अधिकार दे रहा था जितना उसके लेखक ने समझा था।
FAQ
Ubuntu 26.04 पर मेरा sudoers वाइल्डकार्ड नियम काम करना क्यों बंद हो गया?
क्योंकि Ubuntu 26.04 LTS डिफ़ॉल्ट sudo के रूप में sudo-rs का चयन करता है, और sudo-rs कमांड के तर्कों (arguments) के भीतर वाइल्डकार्ड पैटर्न का मिलान नहीं करता है। यह कमांड के फ़ाइल नाम में वाइल्डकार्ड की अनुमति देता है, "" का अर्थ है कोई तर्क नहीं, और अंतिम तर्क के रूप में एक एकल *। /usr/bin/systemctl restart app-* जैसा नियम तर्क के बीच में एक पैटर्न डालता है, इसलिए यह कुछ भी प्रदान नहीं करता है और कमांड को अस्वीकार कर दिया जाता है। यह देखने के लिए कि खाते के पास वास्तव में क्या अधिकार हैं, root के रूप में sudo -l -U deploy चलाएँ, फिर नियम को सटीक कमांड या root-owned रैपर स्क्रिप्ट से बदलें।
मैं Ubuntu 26.04 पर मूल sudo पर वापस कैसे स्विच करूँ?
मूल sudo को sudo.ws के रूप में पैक किया गया है। इसे sudo apt install sudo.ws के साथ इंस्टॉल करें, फिर sudo update-alternatives --set sudo /usr/bin/sudo.ws के साथ alternative को उस पर पॉइंट करें। आपका सिस्टम जो सटीक पथ प्रदान करता है उसे पढ़ने के लिए पहले update-alternatives --config sudo चलाएँ, और इसे बदलते समय दूसरा SSH सत्र खुला रखें। यह sudo-ldap को वापस नहीं लाता है, जिसे आप कोई भी कार्यान्वयन चुनें, 26.04 से हटा दिया गया था।
क्या sudo-rs वही /etc/sudoers फ़ाइल पढ़ता है?
हाँ। sudo-rs /etc/sudoers और /etc/sudoers.d/ के अंतर्गत ड्रॉप-इन फ़ाइलों को पढ़ता है, जिसमें उपयोगकर्ताओं, समूहों, उपनामों, run-as विनिर्देशों और NOPASSWD टैग के लिए समान सिंटैक्स है। यह sudoers भाषा के एक सबसेट को लागू करता है, इसलिए अंतर उन संरचनाओं के रूप में दिखाई देते हैं जो गायब हैं, न कि उन संरचनाओं के रूप में जो अलग तरह से व्यवहार करती हैं। sudo visudo के साथ संपादित करें, फिर अपना सत्र बंद करने से पहले sudo visudo -c के साथ सत्यापित करें।
sudo-rs में sudo -E की जगह क्या लेता है?
sudo -E लागू नहीं है, और मूल sudo में इसे पहले ही हतोत्साहित किया गया था, क्योंकि कॉलर द्वारा नियंत्रित वातावरण को root प्रक्रिया को सौंपना उस प्रक्रिया के व्यवहार को बदलने का एक प्रसिद्ध तरीका है। इसके बजाय sudoers में उन वेरिएबल्स का नाम दें जिनकी आपको वास्तव में आवश्यकता है, Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY" जैसी लाइन के साथ। env_reset sudo-rs में हमेशा चालू रहता है और इसे अक्षम नहीं किया जा सकता है, इसलिए आपके द्वारा न रखा गया प्रत्येक वेरिएबल साफ़ कर दिया जाता है।