SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-09-08

Perubahan sudo-rs pada Ubuntu 26.04 dan fail sudoers

Ubuntu 26.04 kini menggunakan sudo-rs sebagai lalai. Ketahui cara mengemas kini peraturan sudoers anda kerana sokongan wildcard bagi argumen arahan telah berubah sepenuhnya.

Perubahan sudo-rs pada Ubuntu

Ubuntu 26.04 LTS membekalkan sudo-rs sebagai sudo lalai, jadi arahan sudo pada pelayan baharu menjalankan pelaksanaan semula Rust dan bukannya program C asal. Kebanyakan fail sudoers terus berfungsi seperti biasa. Peraturan yang terjejas ialah peraturan yang mengandungi wildcard di dalam argumen arahan, kerana sudo-rs tidak memadankan corak glob dengan teks argumen.

Ubuntu 25.10 membuat pertukaran ini terlebih dahulu dan 26.04 LTS mengekalkannya. Ubuntu 24.04 LTS tidak terjejas, kerana ia masih memilih sudo asal kecuali jika anda memasang sudo-rs secara manual. Perkara ini menjadi penting apabila anda menaik taraf daripada Ubuntu 24.04 ke 26.04, atau apabila anda membina mesin baharu pada keluaran yang lebih baharu. Jika anda juga menjalankan keluaran interim, perbezaan antara keluaran LTS dan interim Ubuntu pada pelayan menjelaskan mesin yang mana akan menerima perubahan seperti ini terlebih dahulu.

Semak sudo yang sebenarnya sedang dijalankan oleh pelayan anda

Jangan tentukan perkara ini berdasarkan nombor keluaran. Tanya mesin tersebut.

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

Percayai sudo --version pada mesin anda sendiri berbanding mana-mana jadual versi di internet, termasuk halaman ini. update-alternatives --config sudo ialah separuh lagi jawapannya: ia menyenaraikan setiap pembekal /usr/bin/sudo yang dipasang dan menandakan yang dipilih. Pakej yang dipasang tidak sama dengan pakej yang dipilih, jadi baca pilihan tersebut, bukan senarai pakej.

Kedua-dua pelaksanaan dipakejkan semasa peralihan. Versi Rust ialah sudo-rs, pada versi 0.2.13 dalam 26.04 setakat Ogos 2026. Versi asal, yang diselenggara oleh Todd C. Miller, masih merupakan pakej sudo; apa yang berubah ialah programnya membawa akhiran .ws supaya kedua-duanya boleh dipasang serentak: /usr/bin/sudo.ws dan /usr/bin/visudo.ws, di samping cvtsudoers.ws dan sudoreplay.ws. Disahkan terhadap arkib 26.04 pada September 2026: dpkg -L sudo menyenaraikan binari yang mempunyai akhiran, dan sudo-rs menghantar /usr/bin/sudo-rs di sampingnya.

Mengapa Ubuntu beralih kepada sudo-rs

sudo menggunakan setuid root. Mana-mana pengguna pada pelayan boleh memulakannya, dan ia bermula dengan keistimewaan penuh, jadi pepijat memori di dalamnya merupakan eksploitasi root tempatan. CVE-2021-3156 adalah contoh tepat bagi perkara ini: limpahan penimbal heap yang boleh dicapai oleh mana-mana pengguna tempatan, dan ia wujud dalam kod yang dikeluarkan selama kira-kira sepuluh tahun. Rust mengesan kelas pepijat tersebut pada masa kompilasi, yang merupakan hujah utama bagi penulisan semula ini.

Sebab kedua ialah skop, dan ini adalah perkara yang menjejaskan konfigurasi anda. sudo yang asal telah mengumpul set ciri yang besar selama tiga dekad, dan setiap ciri bermakna lebih banyak kod yang berjalan sebagai root. sudo-rs melaksanakan subset secara sengaja. Apa-apa sahaja yang dianggap oleh penulisnya sebagai khusus atau berbahaya telah ditinggalkan, jadi binaan sudoers yang berfungsi selama bertahun-tahun mungkin tiada lagi. Peraturan wildcard anda adalah salah satu daripadanya.

Keselamatan memori menghapuskan satu kelas pepijat. Ia tidak menjadikan program bebas daripada pepijat, dan sudo-rs sendiri telah mengeluarkan tampalan keselamatan sejak ia menjadi pilihan lalai. Tampal ia seperti perisian lain.

Peraturan sudoers yang masih berfungsi

Fail tersebut adalah fail yang sama. sudo-rs membaca /etc/sudoers dan fail-fail tambahan dalam /etc/sudoers.d/, dan perkara biasa yang ditulis oleh pengendali pelayan adalah disokong:

  • deploy ALL=(ALL:ALL) ALL, dan bentuk kumpulan seperti %sudo ALL=(ALL:ALL) ALL
  • tag NOPASSWD: dan PASSWD:
  • User_Alias, Runas_Alias, Host_Alias dan Cmnd_Alias
  • arahan dengan senarai argumen yang tepat, contohnya /usr/bin/systemctl restart app-api
  • arahan yang diikuti oleh "", yang membenarkan arahan tersebut hanya jika tiada argumen langsung
  • arahan yang diikuti oleh * sebagai argumen terakhirnya, yang membenarkan sebarang argumen tambahan
  • laluan direktori yang berakhir dengan /, yang membenarkan sebarang arahan dalam direktori tersebut
  • ! untuk menolak arahan daripada senarai
  • subset Defaults yang berguna, termasuk secure_path, env_keep, env_check, timestamp_timeout, passwd_tries, editor, umask, targetpw, rootpw dan use_pty

Dua tetapan lalai berkelakuan berbeza dan sering memeranjatkan pengguna. env_reset tidak boleh dimatikan dalam sudo-rs: ia sentiasa aktif. use_pty diaktifkan secara lalai, jadi arahan tersebut berjalan dalam pseudo-terminalnya sendiri.

Mengapa peraturan wildcard sudoers anda tidak lagi sepadan

Wildcard masih dibenarkan di satu tempat: nama fail bagi arahan tersebut. Peraturan %ops ALL = /sbin/fsck* masih membenarkan sudo fsck dan sudo fsck_exfat, kerana * adalah sebahagian daripada laluan yang dipadankan dengan sistem fail.

Di dalam senarai argumen, sudo-rs hanya menerima dua bentuk khas, dan tiada satu pun daripadanya merupakan corak (pattern). "" bermaksud tiada argumen. * di hujung bermaksud sebarang argumen tambahan. Setiap argumen lain dibandingkan sebagai teks literal. Jadi %ops ALL = /sbin/service ntp * adalah betul, kerana ntp adalah literal dan * berada di kedudukan terakhir. Walau bagaimanapun, peraturan seperti ini tidak memberikan apa yang anda inginkan:

deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart app-*

app-* ialah corak di tengah-tengah argumen. sudo-rs tidak mengembangkannya, jadi peraturan tersebut tidak meliputi systemctl restart app-api dan sudo menolak arahan tersebut. Dua arahan memberitahu anda perkara sebenar tentang sebarang peraturan pada pelayan anda sendiri: sudo -l -U deploy, yang dijalankan sebagai root, mencetak apa yang akaun tersebut sebenarnya boleh jalankan, dan sudo visudo -c memberitahu anda sama ada fail tersebut dapat dihuraikan (parse) atau tidak. Jalankan arahan ini sebelum anda mula menyunting secara rawak.

Peraturan wildcard sentiasa menjadi kelemahan

Di bawah sudo asal, argumen yang anda taip digabungkan menjadi satu rentetan dan dipadankan dengan rentetan argumen peraturan menggunakan glob. Glob memadankan ruang putih (whitespace). Inilah bahagian yang hampir semua orang terlepas pandang.

Dokumentasi sudo-rs memberikan demonstrasi yang paling jelas. Peraturan /bin/rm *.txt juga membenarkan sudo rm -rf /home .txt, kerana satu * menelan -rf /home dan rentetan yang digabungkan itu masih berakhir dengan .txt. Peraturan itu dibaca sebagai "fail teks sahaja". Ia sebenarnya bermaksud "sebarang argumen, asalkan baris tersebut berakhir dengan .txt".

Perkara yang sama terpakai pada contoh systemctl. Oleh kerana argumen dibandingkan sebagai satu rentetan yang digabungkan, corak yang diletakkan di hujung juga memadankan apa sahaja yang anda tambah selepasnya, jadi restart app-* merangkumi restart app-api serta sebarang argumen tambahan yang dimasukkan oleh pemanggil. Corak di dalam sesuatu argumen mendedahkan argumen di sekelilingnya, dan argumen adalah tempat terletaknya kuasa sesuatu arahan. sudo-rs menolak binaan tersebut daripada cuba menjadikannya selamat, kerana tiada bentuk umum yang selamat untuknya.

Gantikan wildcard dengan senarai arahan yang eksplisit

Kebanyakan peraturan wildcard wujud kerana seseorang tidak mahu menaip empat baris. Taipkan empat baris tersebut.

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

Pastikan path adalah betul. Peraturan yang menamakan /bin/systemctl pada sistem di mana binari berada di /usr/bin/systemctl tidak akan sepadan, dan kegagalan tersebut kelihatan sama seperti masalah kebenaran (permissions). Sahkan dengan command -v systemctl dan tampal apa yang dicetaknya.

Letakkan peraturan tersebut dalam fail drop-in sendiri dan bukannya di dalam /etc/sudoers, supaya naik taraf pakej tidak akan bercanggah dengan suntingan anda:

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

Namakan fail tanpa titik dan tanpa tilde di hujung. sudo asal mengabaikan fail dalam sudoers.d yang namanya mengandungi titik, jadi 90-deploy.conf adalah contoh klasik no-op senyap, dan mengikut konvensyen ini tidak merugikan apa-apa.

Gunakan wrapper milik root apabila senarai menjadi panjang

Apabila set yang dibenarkan terlalu besar untuk disenaraikan, pindahkan keputusan tersebut keluar daripada sudoers ke dalam program kecil yang dimiliki oleh 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

Bahagian sudoers kemudiannya menamakan satu arahan:

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

Penggunaan * di hujung adalah boleh diterima di sini kerana skrip tersebut, bukan sudo, yang menentukan perkara yang dibenarkan. Perkara ini hanya terpakai selagi skrip tersebut dimiliki oleh root dan tidak boleh ditulis oleh orang lain. Jika deploy boleh menulis pada fail tersebut, deploy boleh menggantikan kandungannya dan menjalankan apa sahaja sebagai root, yang mana lebih buruk daripada peraturan wildcard yang anda alihkan. Semak mod dengan ls -l, dan jika outputnya tidak jelas kepada anda, membaca rentetan kebenaran drwxr-xr-x hanya mengambil masa lima minit untuk dipelajari. Peraturan yang sama meliputi direktori: /usr/local/sbin juga tidak boleh ditulis oleh akaun tersebut, kerana direktori yang boleh ditulis bermakna fail tersebut boleh digantikan sepenuhnya.

Berikan tugasan tersebut akaunnya sendiri dan bukannya peraturan sudo

Soalan yang lebih tepat selalunya adalah mengapa arahan tersebut memerlukan root sama sekali. Servis yang berjalan sebagai penggunanya sendiri boleh diuruskan oleh pengguna tersebut, dan tiada baris sudoers yang terlibat. Bagi unit sistem, systemd sudah menyerahkan keputusan itu kepada polkit, jadi satu peraturan boleh menamakan satu unit dan satu pengendali:

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;
    }
});

Simpan perkara itu sebagai /etc/polkit-1/rules.d/50-app-api.rules dan deploy boleh menjalankan systemctl restart app-api tanpa sebarang sudo. Uji perkara ini daripada konteks tepat yang akan menggunakannya, kerana peraturan yang berfungsi dalam sesi SSH anda perlu disahkan daripada cron sebelum anda bergantung kepadanya. Walau apa pun, akaun yang melakukan kerja tersebut harus wujud untuk kerja itu sahaja, yang merupakan hujah yang sama di sebalik akaun pengguna dengan keistimewaan minimum pada VPS.

Perkara lain yang tidak disertakan dalam sudo-rs

sudo -E tidak dilaksanakan. Namakan pemboleh ubah yang anda perlukan dengan Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY" sebaliknya, dan ingat bahawa env_reset sentiasa aktif, jadi apa-apa yang tidak disimpan akan dibersihkan.

Storan sudoers berpusat dalam LDAP telah dibuang. sudoers.ldap dan cvtsudoers tidak dilaksanakan, dan pakej sudo-ldap telah dikeluarkan dalam 26.04. Pengesahan LDAP melalui PAM atau SSSD masih berfungsi. Bahagian dasar-dalam-direktori adalah di luar skop.

INTERCEPT, yang cuba menghalang shell escape daripada arahan yang dibenarkan, tidak dilaksanakan. Ia tidak pernah berkesan terhadap pengguna yang bertekad. Jika sesuatu peraturan membenarkan seseorang menjalankan editor atau penterjemah sebagai root, mereka mempunyai akses root, dan tiada pilihan sudo yang boleh mengubah perkara itu.

Rakaman sesi tidak dilaksanakan, jadi tiada log I/O dan tiada sudoreplay. Pembalakan hanya pergi ke syslog, dan tiada pilihan logfile untuk mengubah halanya ke tempat lain, jadi mesej sudo akan dihantar ke mana sahaja sistem anda menghantar syslog pada masa ini.

Patutkah anda kembali kepada sudo.ws?

Anda boleh berbuat demikian, dan sepanjang kitaran 26.04 versi asal kekal dipakejkan atas sebab ini.

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

Salin laluan tepat daripada output --config dan bukannya daripada halaman ini, kerana itulah senarai yang akan diterima oleh sistem anda sendiri. Kembali kepada sudo-rs kemudian bermakna menetapkan alternatif kepada laluan binari sudo-rs daripada senarai yang sama.

Pastikan sesi SSH kedua dibuka, dilog masuk dan melahu, sebelum anda menyentuh apa-apa yang menjejaskan sudo. Fail sudoers yang gagal dihuraikan, atau alternatif yang menghala ke binari yang tidak dipasang, boleh menyebabkan anda tiada cara untuk menjadi root pada kotak jauh. Tabiat itu perlu diamalkan bersama semua perkara lain yang anda lakukan dalam sepuluh minit pertama pada VPS baharu.

Anggap penukaran kembali sebagai tarikh akhir dan bukannya pembaikan. Ia memberi anda masa seminggu untuk menulis semula peraturan dengan betul, dan penulisan semula itu berbaloi dilakukan atas meritnya sendiri, kerana setiap peraturan wildcard yang anda padamkan telah memberikan lebih banyak akses daripada yang difahami oleh penulisnya.

FAQ

Mengapa peraturan wildcard sudoers saya tidak lagi berfungsi pada Ubuntu 26.04?

Ini kerana Ubuntu 26.04 LTS memilih sudo-rs sebagai sudo lalai, dan sudo-rs tidak memadankan corak wildcard di dalam argumen sesuatu arahan. Ia membenarkan wildcard pada nama fail arahan, "" untuk bermaksud tiada argumen, dan satu * sebagai argumen terakhir. Peraturan seperti /usr/bin/systemctl restart app-* meletakkan corak di tengah-tengah argumen, jadi ia tidak memberikan sebarang kebenaran dan arahan tersebut ditolak. Jalankan sudo -l -U deploy sebagai root untuk melihat apa yang sebenarnya dimiliki oleh akaun tersebut, kemudian gantikan peraturan itu dengan arahan yang tepat atau dengan skrip pembungkus (wrapper script) milik root.

Bagaimanakah cara untuk kembali kepada sudo asal pada Ubuntu 26.04?

Versi asal disertakan dalam pakej sudo, yang binarinya membawa akhiran .ws. Pasang ia dengan sudo apt install sudo, kemudian halakan alternatif kepadanya dengan sudo update-alternatives --set sudo /usr/bin/sudo.ws. Jalankan update-alternatives --config sudo terlebih dahulu untuk membaca laluan tepat yang ditawarkan oleh sistem anda, dan pastikan sesi SSH kedua dibuka semasa anda melakukan perubahan tersebut. Ini tidak akan mengembalikan sudo-ldap, yang telah dibuang daripada 26.04 tanpa mengira pelaksanaan yang anda pilih.

Adakah sudo-rs membaca fail /etc/sudoers yang sama?

Ya. sudo-rs membaca /etc/sudoers dan fail-fail tambahan di bawah /etc/sudoers.d/, dengan sintaks yang sama untuk pengguna, kumpulan, alias, spesifikasi run-as dan tag NOPASSWD. Ia melaksanakan subset bahasa sudoers, jadi perbezaannya muncul sebagai binaan yang tiada dan bukannya binaan yang berkelakuan berbeza. Sunting dengan sudo visudo, kemudian sahkan dengan sudo visudo -c sebelum anda menutup sesi anda.

Apakah yang menggantikan sudo -E dalam sudo-rs?

sudo -E tidak dilaksanakan, dan ia sudah pun tidak digalakkan dalam sudo asal, kerana memberikan proses root persekitaran yang dikawal oleh pemanggil adalah cara yang diketahui umum untuk mengubah kelakuan proses tersebut. Namakan pemboleh ubah yang anda perlukan dalam sudoers sebaliknya, dengan baris seperti Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY". env_reset sentiasa aktif dalam sudo-rs dan tidak boleh dinyahaktifkan, jadi setiap pemboleh ubah yang tidak anda kekalkan akan dibersihkan.

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