SSD Nodes Learn 🎉 VPS $5.50/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-13

Ubuntu 26.04-এ sudo-rs: sudoers-এ কী বদলেছে

Ubuntu 26.04-এ sudo-rs ডিফল্ট sudo। sudoers-এর wildcard argument আর মিলবে না। কোন নিয়ম ভাঙে এবং তার বদলে কী লিখবেন, তা উদাহরণসহ দেখুন।

Ubuntu-তে sudo-rs কী পরিবর্তন করে

Ubuntu 26.04 LTS-এ sudo-rs ডিফল্ট sudo হিসেবে অন্তর্ভুক্ত থাকে। তাই নতুন সার্ভারে sudo কমান্ড চালালে মূল C প্রোগ্রামের পরিবর্তে Rust-এ পুনর্লিখিত সংস্করণটি চলে। অধিকাংশ sudoers ফাইল আগের মতোই কাজ করে। যে নিয়মটি সমস্যায় পড়ে, সেটিতে কমান্ডের argument-এর মধ্যে wildcard থাকে। কারণ sudo-rs argument-এর লেখার সঙ্গে glob pattern মিলিয়ে দেখে না।

Ubuntu 25.10-এ প্রথম এই পরিবর্তন করা হয় এবং 26.04 LTS-এও তা রাখা হয়েছে। Ubuntu 24.04 LTS প্রভাবিত নয়। সেখানে হাতে sudo-rs ইনস্টল না করলে এখনও মূল sudo-ই ব্যবহৃত হয়। এই পরিবর্তনটি গুরুত্বপূর্ণ হয় যখন আপনি Ubuntu 24.04 থেকে 26.04-এ upgrade করেন, অথবা নতুন release-এ একটি নতুন server তৈরি করেন। আপনি যদি interim release-ও চালান, server-এ LTS এবং interim Ubuntu release-এর পার্থক্য দেখুন। এতে বোঝা যাবে, এমন পরিবর্তন প্রথমে কোন মেশিনে প্রযোজ্য হবে।

আপনার সার্ভারে আসলে কোন sudo চলছে তা পরীক্ষা করুন

Release number দেখে এটি নির্ধারণ করবেন না। মেশিনকেই জিজ্ঞাসা করুন।

sudo --version
update-alternatives --config sudo
dpkg -l 'sudo*'

Internet-এর যেকোনো version table, এমনকি এই পৃষ্ঠার তথ্যের চেয়েও, নিজের server-এ চালানো sudo --version-কে বেশি বিশ্বাস করুন। update-alternatives --config sudo উত্তরটির অন্য অংশ: এটি /usr/bin/sudo-এর ইনস্টল করা প্রতিটি provider তালিকাভুক্ত করে এবং নির্বাচিত provider-টি চিহ্নিত করে। কোনো package ইনস্টল করা থাকা এবং সেটি নির্বাচিত থাকা এক বিষয় নয়। তাই package list নয়, selection দেখুন।

Transition চলাকালে উভয় implementation-ই package হিসেবে দেওয়া হয়। Rust implementation-টি হলো sudo-rs; August 2026 অনুযায়ী 26.04-এ এর version 0.2.13। Todd C. Miller রক্ষণাবেক্ষণ করা মূল implementation-টি sudo.ws হিসেবে package করা হয়, এবং এর program-গুলোর শেষে .ws suffix থাকে: sudo.ws এবং visudo.ws

Ubuntu কেন sudo-rs ব্যবহার শুরু করেছে

sudo হলো setuid root প্রোগ্রাম। সিস্টেমের যেকোনো user এটি চালাতে পারে, এবং এটি পূর্ণ privilege নিয়ে শুরু হয়। তাই এর ভেতরের memory bug একটি local root exploit-এ পরিণত হতে পারে। CVE-2021-3156 ঠিক এমনই একটি সমস্যা ছিল। যেকোনো local user এটি কাজে লাগাতে পারত, এবং প্রায় দশ বছর ধরে এটি released code-এ ছিল। Rust compile time-এ এই ধরনের bug শনাক্ত করে। rewrite করার মূল যুক্তি এটাই।

দ্বিতীয় কারণ হলো scope। এই কারণটিই আপনার config-এ প্রভাব ফেলে। মূল sudo গত তিন দশকে অনেক feature সংগ্রহ করেছে। প্রতিটি feature root হিসেবে চলা আরও code যোগ করে। sudo-rs ইচ্ছাকৃতভাবে এর একটি subset বাস্তবায়ন করে। নির্মাতারা যেসব feature-কে niche বা সক্রিয়ভাবে ক্ষতিকর মনে করেছেন, সেগুলো বাদ দিয়েছেন। তাই বহু বছর ধরে কাজ করা কোনো sudoers construct সরাসরি অনুপস্থিত থাকতে পারে। আপনার wildcard rule এমনই একটি।

Memory safety একটি শ্রেণির bug দূর করে। এতে কোনো program সম্পূর্ণ bug মুক্ত হয় না। default হওয়ার পর থেকে sudo-rs নিজস্ব security fix-ও প্রকাশ করেছে। অন্য যেকোনো software-এর মতো এটিকেও patch করুন।

কোন sudoers নিয়মগুলো এখনও কাজ করে

ফাইলটি একই। sudo-rs /etc/sudoers এবং /etc/sudoers.d/-এর drop-in ফাইল পড়ে। সার্ভার অপারেটররা সাধারণত যে নিয়মগুলো লেখেন, সেগুলো সমর্থিত:

  • deploy ALL=(ALL:ALL) ALL এবং %sudo ALL=(ALL:ALL) ALL-এর মতো group form
  • NOPASSWD: এবং PASSWD: tag
  • User_Alias, Runas_Alias, Host_Alias এবং Cmnd_Alias
  • নির্দিষ্ট argument list-সহ একটি command, যেমন /usr/bin/systemctl restart app-api
  • ""-এর পরে থাকা একটি command; এতে command-টি কোনো argument ছাড়া চালানো যায়
  • শেষ argument হিসেবে *-সহ একটি command; এতে পরবর্তী যেকোনো argument অনুমোদিত হয়
  • / দিয়ে শেষ হওয়া একটি directory path; এতে ওই directory-র যেকোনো command অনুমোদিত হয়
  • কোনো list থেকে একটি command বাদ দিতে ! ব্যবহার
  • Defaults-এর একটি কার্যকর subset; এর মধ্যে রয়েছে secure_path, env_keep, env_check, timestamp_timeout, passwd_tries, editor, umask, targetpw, rootpw এবং use_pty

দুটি default ভিন্নভাবে কাজ করে এবং অনেককে বিভ্রান্ত করে। sudo-rs-এ env_reset বন্ধ করা যায় না; এটি সবসময় চালু থাকে। use_pty default হিসেবে চালু থাকে, তাই command-টি নিজস্ব pseudo-terminal-এ চলে।

আপনার wildcard sudoers rule কেন আর মেলেনি

Wildcard এখনও একটি জায়গায় অনুমোদিত: command-এর file name-এ। %ops ALL = /sbin/fsck*-এর একটি rule এখনও sudo fsck এবং sudo fsck_exfat অনুমোদন করে, কারণ * filesystem-এর সঙ্গে মিলিয়ে দেখা path-এর অংশ।

Argument list-এর ভিতরে sudo-rs কেবল দুটি বিশেষ form গ্রহণ করে, এবং কোনোটিই pattern নয়। "" মানে কোনো argument নেই। শেষের * যেকোনো পরবর্তী argument বোঝায়। অন্য প্রতিটি 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-টি প্রত্যাখ্যান করে। আপনার নিজের সার্ভারে কোনো rule-এর প্রকৃত আচরণ জানার জন্য দুটি command ব্যবহার করুন: root হিসেবে চালানো sudo -l -U deploy দেখায় ওই account আসলে কোন command চালাতে পারে, আর sudo visudo -c জানায় file-টি আদৌ parse করা যায় কি না। এলোমেলোভাবে editing শুরু করার আগে এগুলো চালান।

ওয়াইল্ডকার্ড নিয়মটি শুরু থেকেই একটি নিরাপত্তা ফাঁক ছিল

মূল sudo-তে আপনি যে argument লেখেন, সেগুলো একত্র করে একটি string বানানো হয়। এরপর সেটি glob ব্যবহার করে নিয়মের argument string-এর সঙ্গে মিলিয়ে দেখা হয়। glob whitespace-ও মেলাতে পারে। প্রায় সবাই এই বিষয়টি উপেক্ষা করে।

sudo-rs-এর documentation-এ এর সবচেয়ে স্পষ্ট উদাহরণ দেওয়া আছে। /bin/rm *.txt-এর নিয়মটি sudo rm -rf /home .txt-কেও অনুমতি দেয়, কারণ একমাত্র *-টি -rf /home গিলে ফেলে এবং যুক্ত করা string-এর শেষ এখনও .txt থাকে। নিয়মটি পড়লে মনে হয়, “শুধু text file”। কিন্তু এর প্রকৃত অর্থ হলো, “যেকোনো argument গ্রহণযোগ্য, যদি পুরো line-এর শেষে .txt থাকে।”

systemctl-এর উদাহরণেও একই বিষয় প্রযোজ্য। argument-গুলো একটি যুক্ত string হিসেবে তুলনা করা হয়। তাই শেষে থাকা pattern-এর পরে আপনি যা-ই যোগ করুন, সেটিও মিলে যায়। ফলে restart app-*, restart app-api এবং caller-এর যোগ করা যেকোনো অতিরিক্ত argument—সবকিছুকেই অনুমতি দেয়। কোনো argument-এর ভেতরে pattern রাখলে তার আশপাশের argument-গুলোর নিয়ন্ত্রণও ছেড়ে দিতে হয়। আর command-এর ক্ষমতা থাকে argument-গুলোর মধ্যেই। নিরাপদ করার চেষ্টা না করে sudo-rs এই গঠনটি প্রত্যাখ্যান করে, কারণ এর কোনো সাধারণ নিরাপদ রূপ নেই।

ওয়াইল্ডকার্ডের পরিবর্তে স্পষ্ট command তালিকা ব্যবহার করুন

বেশিরভাগ wildcard rule রাখা হয় কারণ কেউ চারটি line লিখতে চাননি। চারটি line লিখুন।

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_STATUS

সঠিক path ব্যবহার করুন। যে system-এ binary হলো /usr/bin/systemctl, সেখানে /bin/systemctl উল্লেখ করা rule কখনো match করবে না। এই ব্যর্থতা permissions সমস্যার মতোই দেখায়। command -v systemctl দিয়ে নিশ্চিত করুন এবং এটি যে output দেখায় তা paste করুন।

Rule-টি /etc/sudoers-এ না লিখে আলাদা drop-in file-এ রাখুন। এতে package upgrade আপনার edit-এর সঙ্গে বিরোধ তৈরি করবে না:

sudo visudo -f /etc/sudoers.d/90-deploy
sudo visudo -c
sudo -l -U deploy

File-এর নামের মধ্যে dot বা শেষে tilde ব্যবহার করবেন না। মূল sudo sudoers.d-এর এমন file উপেক্ষা করে, যেগুলোর নামের মধ্যে dot আছে। তাই 90-deploy.conf একটি প্রচলিত নীরব no-op। এই convention মেনে চললে কোনো অতিরিক্ত খরচ নেই।

তালিকা দীর্ঘ হলে root-মালিকানাধীন wrapper ব্যবহার করুন

অনুমোদিত সেটের তালিকা খুব বড় হলে সিদ্ধান্তটি sudoers থেকে সরিয়ে 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 অংশে শুধু একটি command উল্লেখ করুন:

deploy ALL=(root) NOPASSWD: /usr/local/sbin/app-restart *

এখানে শেষের * গ্রহণযোগ্য, কারণ কোন কাজ অনুমোদিত হবে তা sudo নয়, script নির্ধারণ করছে। এটি কেবল তখনই নিরাপদ, যখন script-টির মালিক root এবং অন্য কেউ এতে লিখতে পারে না। deploy যদি file-টিতে লিখতে পারে, তাহলে deploy এর বিষয়বস্তু বদলে root হিসেবে যেকোনো কাজ চালাতে পারবে। এটি আপনি সরিয়ে দেওয়া wildcard rule-এর চেয়েও বেশি ঝুঁকিপূর্ণ। ls -l ব্যবহার করে mode পরীক্ষা করুন। Output আপনার কাছে স্পষ্ট না হলে drwxr-xr-x permission string পড়তে শিখতে পাঁচ মিনিটই যথেষ্ট। একই নিয়ম directory-এর ক্ষেত্রেও প্রযোজ্য: /usr/local/sbin account-টির জন্য writable হওয়া যাবে না, কারণ writable directory থাকলে পুরো file-টি প্রতিস্থাপন করা সম্ভব।

sudo rule-এর পরিবর্তে কাজটির জন্য আলাদা account দিন

অনেক সময় প্রথম প্রশ্ন হওয়া উচিত, command-টির আদৌ root প্রয়োজন কেন। কোনো service যদি নিজের user হিসেবে চলে, তাহলে সেই user দিয়েই এটি পরিচালনা করা যায় এবং কোনো sudoers line-এর প্রয়োজন হয় না। system unit-এর ক্ষেত্রে 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 হিসেবে সংরক্ষণ করুন। এরপর deploy কোনো sudo ছাড়াই systemctl restart app-api চালাতে পারবে। যে সঠিক context থেকে এটি ব্যবহার করা হবে, সেখান থেকেই পরীক্ষা করুন। কারণ আপনার SSH session-এ কাজ করা কোনো rule-এর ওপর নির্ভর করার আগে cron থেকে সেটি নিশ্চিত করা উচিত। যেকোনো ক্ষেত্রেই কাজটি যে account করবে, সেটি শুধু ওই কাজের জন্যই থাকা উচিত। VPS-এ সর্বনিম্ন-সুবিধার user account ব্যবহারের পেছনেও একই কারণ রয়েছে।

sudo-rs-এ আর যা নেই

sudo -E বাস্তবায়িত হয়নি। প্রয়োজনীয় ভেরিয়েবলগুলোর নাম Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY" দিয়ে দিন। মনে রাখবেন, env_reset সবসময় চালু থাকে। তাই সংরক্ষণ না করা যেকোনো কিছু মুছে যায়।

LDAP-এ কেন্দ্রীয় sudoers storage আর নেই। sudoers.ldap এবং cvtsudoers বাস্তবায়িত হয়নি। 26.04-এ sudo-ldap package-টিও সরিয়ে দেওয়া হয়েছে। PAM বা SSSD-এর মাধ্যমে LDAP authentication এখনও কাজ করে। তবে directory-তে policy সংরক্ষণের অংশটি এই scope-এর বাইরে।

অনুমোদিত command থেকে shell escape বন্ধ করার চেষ্টা করা INTERCEPT বাস্তবায়িত হয়নি। অবশ্য দৃঢ়প্রতিজ্ঞ user-এর বিরুদ্ধে এটি কার্যকরও ছিল না। কোনো rule কাউকে root হিসেবে editor বা interpreter চালানোর অনুমতি দিলে তার root access আছে। কোনো sudo option এটি পরিবর্তন করতে পারে না।

Session recording বাস্তবায়িত হয়নি। তাই কোনো I/O log বা sudoreplay নেই। Logging শুধু syslog-এ যায়। এটি অন্য কোথাও পাঠানোর জন্য কোনো logfile option নেই। ফলে sudo message আপনার system যেখানেই syslog পাঠায়, সেখানেই জমা হবে।

sudo.ws-এ কি আবার ফিরে যাবেন?

আপনি তা করতে পারেন। 26.04 cycle-এ এই কারণেই মূল সংস্করণটি packaged অবস্থায় রাখা হয়েছে।

sudo apt install sudo.ws
update-alternatives --config sudo
sudo update-alternatives --set sudo /usr/bin/sudo.ws

এই পৃষ্ঠার পরিবর্তে --config output থেকে exact path কপি করুন, কারণ আপনার নিজের system যে তালিকা গ্রহণ করবে সেটি হলো ওই তালিকা। পরে sudo-rs-এ ফিরে যেতে হলে একই তালিকা থেকে sudo-rs binary path-টি alternative হিসেবে সেট করুন।

sudo-কে প্রভাবিত করে এমন কোনো পরিবর্তন করার আগে একটি দ্বিতীয় SSH session খোলা রাখুন এবং তাতে লগ ইন করে idle অবস্থায় রাখুন। যে sudoers file parse করা যায় না, অথবা যে alternative ইনস্টল করা নেই এমন binary-র দিকে নির্দেশ করে, সেটি remote box-এ আপনাকে root হওয়ার কোনো উপায় ছাড়াই রেখে দিতে পারে। নতুন VPS-এ প্রথম দশ মিনিটে আপনি যা করেন, এই অভ্যাসটিও তার অংশ হওয়া উচিত।

এই switch back-কে fix হিসেবে নয়, একটি deadline হিসেবে দেখুন। এটি আপনাকে rules সঠিকভাবে rewrite করার জন্য এক সপ্তাহ সময় দেয়। Rewrite নিজস্ব কারণেই গুরুত্বপূর্ণ, কারণ আপনি যে প্রতিটি wildcard rule মুছে ফেলবেন, সেটি তার লেখক যতটা বুঝেছিলেন তার চেয়েও বেশি অনুমতি দিচ্ছিল।

FAQ

Ubuntu 26.04-এ আমার sudoers wildcard rule কাজ করা বন্ধ করল কেন?

কারণ Ubuntu 26.04 LTS ডিফল্ট sudo হিসেবে sudo-rs নির্বাচন করে, আর sudo-rs কোনো command-এর argument-এর ভিতরের wildcard pattern মিলিয়ে দেখে না। এটি command-এর file name-এ wildcard, কোনো argument না থাকার অর্থে "", এবং শেষ argument হিসেবে একটি * গ্রহণ করে। /usr/bin/systemctl restart app-*-এর মতো rule কোনো argument-এর মাঝখানে pattern বসায়। তাই এটি কোনো অনুমতি দেয় না এবং command প্রত্যাখ্যাত হয়। Account-এর প্রকৃত অনুমতি দেখতে root হিসেবে sudo -l -U deploy চালান। এরপর rule-টি নির্দিষ্ট command-গুলো দিয়ে অথবা root-owned wrapper script দিয়ে প্রতিস্থাপন করুন।

Ubuntu 26.04-এ কীভাবে মূল sudo-তে ফিরে যাব?

মূল সংস্করণটি sudo.ws নামে package করা হয়েছে। sudo apt install sudo.ws দিয়ে এটি install করুন। এরপর sudo update-alternatives --set sudo /usr/bin/sudo.ws দিয়ে alternative-টি সেট করুন। আপনার সিস্টেমে কোন exact path উপলভ্য, তা আগে দেখতে update-alternatives --config sudo চালান। পরিবর্তন করার সময় দ্বিতীয় একটি SSH session খোলা রাখুন। আপনি কোন implementation নির্বাচন করছেন, তা নির্বিশেষে এতে sudo-ldap ফিরে আসবে না, কারণ এটি 26.04 থেকে সরিয়ে দেওয়া হয়েছে।

sudo-rs কি একই /etc/sudoers file পড়ে?

হ্যাঁ। sudo-rs /etc/sudoers এবং /etc/sudoers.d/-এর অধীন drop-in file-গুলো পড়ে। Users, groups, aliases, run-as specification এবং NOPASSWD tag-এর জন্য একই syntax ব্যবহার করা হয়। এটি sudoers language-এর একটি subset বাস্তবায়ন করে। তাই পার্থক্যগুলো সাধারণত ভিন্ন আচরণ হিসেবে নয়, বরং অনুপস্থিত construct হিসেবে দেখা যায়। sudo visudo দিয়ে edit করুন। Session বন্ধ করার আগে sudo visudo -c দিয়ে যাচাই করুন।

sudo-rs-এ sudo -E-এর পরিবর্তে কী ব্যবহার করা হয়?

sudo -E বাস্তবায়িত হয়নি। মূল sudo-তেও এটি ইতিমধ্যে নিরুৎসাহিত করা হয়েছিল। কারণ caller যে environment নিয়ন্ত্রণ করে, তা root process-কে দিলে process-টির আচরণ পরিবর্তনের একটি সুপরিচিত সুযোগ তৈরি হয়। sudoers-এ আপনার সত্যিই প্রয়োজনীয় variable-গুলো নির্দিষ্ট করুন। যেমন Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY"-এর মতো একটি line ব্যবহার করুন। sudo-rs-এ env_reset সবসময় সক্রিয় থাকে এবং এটি নিষ্ক্রিয় করা যায় না। তাই আপনি যেসব variable রেখে দেবেন না, সেগুলো সব clear হয়ে যাবে।

#sudo#sudo-rs#ubuntu#sudoers#permissions