sudo-rs di Ubuntu: Perubahan pada sudoers
Ubuntu 26.04 menjadikan sudo-rs sebagai sudo default. Wildcard pada argumen perintah tidak lagi cocok; pelajari aturan sudoers penggantinya.
Perubahan sudo-rs di Ubuntu
Ubuntu 26.04 LTS menyediakan sudo-rs sebagai sudo default, sehingga perintah sudo pada server baru menjalankan implementasi ulang dalam Rust, bukan program C asli. Sebagian besar file sudoers tetap berfungsi seperti sebelumnya. Aturan yang bermasalah adalah aturan yang menggunakan wildcard di dalam argumen perintah, karena sudo-rs tidak mencocokkan pola glob dengan teks argumen.
Ubuntu 25.10 menerapkan perubahan ini lebih dahulu, dan Ubuntu 26.04 LTS tetap menggunakannya. Ubuntu 24.04 LTS tidak terdampak karena masih memilih sudo asli, kecuali Anda memasang sudo-rs secara manual. Perubahan ini menjadi relevan saat Anda melakukan upgrade dari Ubuntu 24.04 ke 26.04, atau saat Anda menyiapkan server baru dengan rilis yang lebih baru. Jika Anda juga menjalankan rilis interim, perbedaan rilis Ubuntu LTS dan interim pada server menjelaskan mesin mana yang akan mengalami perubahan seperti ini lebih dahulu.
Periksa sudo yang benar-benar dijalankan server Anda
Jangan menentukannya dari nomor rilis. Tanyakan langsung kepada mesin.
sudo --version
update-alternatives --config sudo
dpkg -l 'sudo*'Percayai sudo --version pada mesin Anda sendiri, bukan tabel versi mana pun di Internet, termasuk halaman ini. update-alternatives --config sudo adalah bagian lain dari jawabannya: perintah ini mencantumkan setiap provider /usr/bin/sudo yang terpasang dan menandai provider yang dipilih. Paket yang terpasang tidak berarti paket tersebut dipilih. Karena itu, baca pilihan yang aktif, bukan daftar paket.
Kedua implementasi dikemas selama masa transisi. Implementasi Rust adalah sudo-rs, dengan versi 0.2.13 pada 26.04 per Agustus 2026. Implementasi asli, yang dikelola oleh Todd C. Miller, masih berupa paket sudo. Perubahannya adalah program-program tersebut kini memiliki akhiran .ws sehingga keduanya dapat dipasang secara bersamaan: /usr/bin/sudo.ws dan /usr/bin/visudo.ws, bersama cvtsudoers.ws dan sudoreplay.ws. Diverifikasi terhadap arsip 26.04 pada September 2026: dpkg -L sudo mencantumkan binary dengan akhiran tersebut, dan sudo-rs menyediakan /usr/bin/sudo-rs di sampingnya.
Mengapa Ubuntu beralih ke sudo-rs
sudo menggunakan setuid root. Setiap pengguna di server dapat menjalankannya, dan sudo dimulai dengan hak akses penuh. Karena itu, bug memori di dalam sudo dapat menjadi eksploitasi root lokal. CVE-2021-3156 adalah contoh tepat untuk kasus tersebut: heap buffer overflow yang dapat dicapai oleh setiap pengguna lokal. Bug itu berada dalam kode yang dirilis selama sekitar sepuluh tahun. Rust mendeteksi kelas bug tersebut saat kompilasi. Hal itu menjadi alasan utama penulisan ulang ini.
Alasan kedua adalah cakupan fitur. Alasan inilah yang memengaruhi konfigurasi Anda. sudo asli telah mengumpulkan banyak fitur selama tiga dekade. Setiap fitur berarti lebih banyak kode yang berjalan sebagai root. sudo-rs sengaja hanya mengimplementasikan sebagian fitur. Fitur yang dinilai khusus atau berpotensi membahayakan oleh pengembangnya tidak disertakan. Akibatnya, konstruksi sudoers yang telah berfungsi selama bertahun-tahun dapat tidak tersedia sama sekali. Aturan wildcard Anda adalah salah satunya.
Keamanan memori menghilangkan satu kelas bug. Namun, hal itu tidak membuat program bebas bug. sudo-rs sendiri telah menerima perbaikan keamanan sejak menjadi default. Terapkan patch pada sudo-rs seperti pada perangkat lunak lainnya.
Aturan sudoers yang tetap berfungsi
File yang digunakan tetap sama. sudo-rs membaca /etc/sudoers dan file drop-in di /etc/sudoers.d/. Sintaks yang biasa ditulis oleh operator server juga didukung:
deploy ALL=(ALL:ALL) ALL, serta bentuk grup seperti%sudo ALL=(ALL:ALL) ALL- tag
NOPASSWD:danPASSWD: User_Alias,Runas_Alias,Host_Alias, danCmnd_Alias- perintah dengan daftar argumen yang persis, misalnya
/usr/bin/systemctl restart app-api - perintah yang diikuti
"", yang mengizinkan perintah hanya tanpa argumen apa pun - perintah yang diikuti
*sebagai argumen terakhirnya, yang mengizinkan argumen tambahan apa pun - path direktori yang diakhiri
/, yang mengizinkan perintah apa pun di direktori tersebut !untuk mengecualikan perintah dari daftar- subset
Defaultsyang berguna, termasuksecure_path,env_keep,env_check,timestamp_timeout,passwd_tries,editor,umask,targetpw,rootpw, danuse_pty
Dua default berperilaku berbeda dan sering menyebabkan kesalahan. env_reset tidak dapat dinonaktifkan dalam sudo-rs karena selalu aktif. use_pty aktif secara default, sehingga perintah dijalankan dalam pseudo-terminalnya sendiri.
Mengapa aturan wildcard sudoers Anda berhenti cocok
Wildcard masih diizinkan di satu tempat: nama file perintah. Aturan %ops ALL = /sbin/fsck* tetap mengizinkan sudo fsck dan sudo fsck_exfat karena * merupakan bagian dari path yang dicocokkan dengan filesystem.
Di dalam daftar argumen, sudo-rs hanya menerima dua bentuk khusus, dan tidak satu pun merupakan pola. "" berarti tidak ada argumen. * di akhir berarti argumen tambahan apa pun. Setiap argumen lainnya dibandingkan sebagai teks literal. Jadi, %ops ALL = /sbin/service ntp * valid karena ntp bersifat literal dan * berada di posisi terakhir. Namun, aturan berikut tidak memberikan akses yang Anda maksud:
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart app-*app-* merupakan pola di tengah argumen. sudo-rs tidak mengembangkannya, sehingga aturan tersebut tidak mencakup systemctl restart app-api dan sudo menolak perintah itu. Dua perintah berikut menunjukkan kondisi sebenarnya dari aturan apa pun pada server Anda: sudo -l -U deploy, yang dijalankan sebagai root, menampilkan perintah yang benar-benar boleh dijalankan oleh akun tersebut, sedangkan sudo visudo -c memberi tahu Anda apakah file dapat diuraikan. Jalankan keduanya sebelum mulai mengubah konfigurasi secara acak.
Aturan wildcard sejak awal merupakan celah
Pada sudo asli, argumen yang Anda ketik digabungkan menjadi satu string, lalu dicocokkan dengan string argumen pada aturan menggunakan glob. Glob dapat mencocokkan spasi putih. Inilah bagian yang hampir selalu terlewatkan.
Dokumentasi sudo-rs memberikan demonstrasi yang paling jelas. Aturan /bin/rm *.txt juga mengizinkan sudo rm -rf /home .txt, karena satu * mencakup -rf /home dan string yang digabungkan tetap diakhiri dengan .txt. Aturan tersebut terbaca sebagai "hanya file teks". Artinya adalah "argumen apa pun, selama baris diakhiri dengan .txt".
Hal yang sama berlaku untuk contoh systemctl. Karena argumen dibandingkan sebagai satu string yang digabungkan, pola di bagian akhir juga cocok dengan apa pun yang ditambahkan setelahnya. Jadi, restart app-* mencakup restart app-api serta argumen tambahan apa pun yang diberikan pemanggil. Pola di dalam sebuah argumen membuka akses ke argumen di sekitarnya, sedangkan kekuatan sebuah perintah terletak pada argumennya. sudo-rs menolak konstruksi ini, bukan mencoba membuatnya aman, karena tidak ada bentuk umum yang aman untuk konstruksi tersebut.
Ganti wildcard dengan daftar perintah eksplisit
Sebagian besar aturan wildcard ada karena seseorang tidak ingin mengetik empat baris. Ketik keempat 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_STATUSPastikan path-nya benar. Aturan yang menyebut /bin/systemctl pada sistem yang binarinya berada di /usr/bin/systemctl tidak akan pernah cocok, dan kegagalannya terlihat sama seperti masalah izin. Konfirmasikan dengan command -v systemctl, lalu tempelkan hasil yang ditampilkan.
Tempatkan aturan tersebut dalam file drop-in tersendiri, bukan di /etc/sudoers, agar pemutakhiran paket tidak pernah bertentangan dengan perubahan Anda:
sudo visudo -f /etc/sudoers.d/90-deploy
sudo visudo -c
sudo -l -U deployBeri nama file tanpa titik dan tanpa tilde di akhir. sudo asli mengabaikan file di sudoers.d yang namanya mengandung titik, sehingga 90-deploy.conf merupakan kesalahan klasik yang tidak menghasilkan apa pun secara diam-diam. Mengikuti konvensi ini tidak menimbulkan biaya tambahan.
Gunakan wrapper milik root jika daftarnya panjang
Jika daftar yang diizinkan terlalu panjang untuk dicantumkan, pindahkan keputusan tersebut dari sudoers ke 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-restartDi sisi sudoers, cukup cantumkan satu perintah:
deploy ALL=(root) NOPASSWD: /usr/local/sbin/app-restart ** di bagian akhir dapat diterima dalam kasus ini karena skrip, bukan sudo, yang menentukan apa yang diizinkan. Hal ini hanya berlaku selama skrip dimiliki oleh root dan tidak dapat ditulis oleh akun lain. Jika deploy dapat menulis ke file tersebut, deploy dapat mengganti isinya dan menjalankan apa pun sebagai root. Ini lebih berbahaya daripada aturan wildcard yang Anda hapus. Periksa mode file dengan ls -l. Jika outputnya tidak langsung jelas bagi Anda, mempelajari string izin drwxr-xr-x hanya memerlukan waktu lima menit. Aturan yang sama berlaku untuk direktori: /usr/local/sbin juga tidak boleh dapat ditulis oleh akun tersebut, karena direktori yang dapat ditulis memungkinkan file diganti seluruhnya.
Berikan tugas tersebut akun khusus, bukan aturan sudo
Pertanyaan yang lebih tepat sering kali adalah mengapa perintah tersebut memerlukan root. Service yang berjalan sebagai user-nya sendiri dapat dikelola oleh user tersebut, tanpa melibatkan baris sudoers. Untuk unit sistem, systemd sudah mendelegasikan keputusan tersebut ke polkit. Karena itu, aturan dapat menyebutkan satu unit dan satu 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;
}
});Simpan aturan tersebut sebagai /etc/polkit-1/rules.d/50-app-api.rules. Dengan demikian, deploy dapat menjalankan systemctl restart app-api tanpa sudo sama sekali. Uji aturan tersebut dari konteks yang benar-benar akan menggunakannya. Aturan yang berfungsi dalam sesi SSH tetap perlu dikonfirmasi dari cron sebelum diandalkan. Apa pun pendekatannya, akun yang menjalankan tugas tersebut sebaiknya hanya digunakan untuk tugas itu. Ini merupakan prinsip yang sama dengan akun user dengan hak istimewa minimum pada VPS.
Hal lain yang tidak disertakan sudo-rs
sudo -E belum diimplementasikan. Gunakan Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY" untuk menetapkan variabel yang diperlukan. Ingat bahwa env_reset selalu aktif, sehingga apa pun yang tidak dipertahankan akan dihapus.
Penyimpanan sudoers terpusat di LDAP tidak tersedia. sudoers.ldap dan cvtsudoers belum diimplementasikan, dan paket sudo-ldap dihapus pada 26.04. Autentikasi LDAP melalui PAM atau SSSD tetap berfungsi. Bagian yang tidak termasuk dalam cakupan adalah kebijakan yang disimpan di dalam direktori.
INTERCEPT, yang berupaya mencegah shell escape dari perintah yang diizinkan, belum diimplementasikan. Fitur itu juga tidak akan efektif terhadap pengguna yang bertekad menyalahgunakannya. Jika sebuah aturan mengizinkan seseorang menjalankan editor atau interpreter sebagai root, berarti orang tersebut sudah memiliki akses root. Tidak ada opsi sudo yang dapat mengubah hal itu.
Perekaman sesi belum diimplementasikan, sehingga tidak ada log I/O dan tidak ada sudoreplay. Logging hanya dikirim ke syslog. Tidak ada opsi logfile untuk mengalihkannya ke lokasi lain, sehingga pesan sudo masuk ke tujuan yang telah dikonfigurasi sistem untuk syslog.
Haruskah Anda beralih kembali ke sudo.ws?
Anda dapat melakukannya. Selama siklus 26.04, paket original tetap disediakan karena alasan ini.
sudo apt install sudo
update-alternatives --config sudo
sudo update-alternatives --set sudo /usr/bin/sudo.wsSalin path yang persis dari output --config, bukan dari halaman ini, karena daftar tersebut adalah daftar yang dapat diterima oleh sistem Anda sendiri. Jika nanti ingin kembali ke sudo-rs, atur alternative ke path binary sudo-rs dari daftar yang sama.
Sebelum mengubah apa pun yang memengaruhi sudo, buka sesi SSH kedua, login, dan biarkan sesi tersebut idle. File sudoers yang gagal diuraikan, atau alternative yang menunjuk ke binary yang tidak terinstal, dapat membuat Anda tidak memiliki cara untuk menjadi root pada server remote. Kebiasaan ini merupakan bagian dari semua tindakan lain yang Anda lakukan dalam sepuluh menit pertama pada VPS baru.
Anggap perpindahan kembali ini sebagai batas waktu, bukan solusi. Langkah ini memberi Anda waktu satu minggu untuk menulis ulang aturan dengan benar. Penulisan ulang tersebut tetap layak dilakukan karena setiap aturan wildcard yang Anda hapus sebelumnya memberikan izin yang lebih luas daripada yang dipahami pembuatnya.
FAQ
Mengapa aturan wildcard sudoers saya berhenti berfungsi di Ubuntu 26.04?
Karena Ubuntu 26.04 LTS memilih sudo-rs sebagai sudo default, sedangkan sudo-rs tidak mencocokkan pola wildcard di dalam argumen perintah. sudo-rs mengizinkan wildcard pada nama file perintah, "" untuk menyatakan tanpa argumen, dan satu * sebagai argumen terakhir. Aturan seperti /usr/bin/systemctl restart app-* menempatkan pola di tengah argumen, sehingga tidak memberikan hak apa pun dan perintah ditolak. Jalankan sudo -l -U deploy sebagai root untuk melihat hak yang benar-benar dimiliki akun tersebut, lalu ganti aturan itu dengan perintah yang ditulis secara eksplisit atau dengan skrip wrapper yang dimiliki root.
Bagaimana cara kembali menggunakan sudo asli di Ubuntu 26.04?
sudo asli tersedia dalam paket sudo, dengan biner yang memiliki akhiran .ws. Instal paket tersebut dengan sudo apt install sudo, lalu arahkan alternative ke sana dengan sudo update-alternatives --set sudo /usr/bin/sudo.ws. Jalankan update-alternatives --config sudo terlebih dahulu untuk melihat path persis yang tersedia pada sistem Anda, dan biarkan sesi SSH kedua tetap terbuka selama perubahan dilakukan. Tindakan ini tidak mengembalikan sudo-ldap, yang telah dihapus dari 26.04 terlepas dari implementasi yang dipilih.
Apakah sudo-rs membaca file /etc/sudoers yang sama?
Ya. sudo-rs membaca /etc/sudoers dan file drop-in di bawah /etc/sudoers.d/, dengan sintaks yang sama untuk pengguna, grup, alias, spesifikasi run-as, dan tag NOPASSWD. sudo-rs mengimplementasikan sebagian bahasa sudoers, sehingga perbedaannya terlihat pada konstruksi yang tidak tersedia, bukan pada konstruksi yang berperilaku berbeda. Edit dengan sudo visudo, lalu verifikasi dengan sudo visudo -c sebelum menutup sesi Anda.
Apa pengganti sudo -E di sudo-rs?
sudo -E tidak diimplementasikan. Fitur tersebut juga sudah tidak disarankan pada sudo asli karena memberikan environment yang dikendalikan pemanggil kepada proses root merupakan cara yang umum untuk mengubah perilaku proses tersebut. Sebutkan variabel yang benar-benar diperlukan langsung di sudoers, dengan baris seperti Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY". env_reset selalu aktif di sudo-rs dan tidak dapat dinonaktifkan, sehingga setiap variabel yang tidak dipertahankan akan dihapus.