Bagaimana mencegah pengguna sudo menjalankan perintah tertentu?

29

Saya memiliki pengaturan jaringan yang sangat sensitif dan saya benar-benar tidak ingin mengacaukannya. Jaringan saya terdiri dari sekelompok pengguna yang memiliki hak istimewa sudo.

Saya ingin menghentikan mereka dari berlari

service NetworkManager restart
service network restart

perintah.

Apakah ada cara saya bisa mencapai ini?

shekhar
sumber
Distribusi mana yang Anda gunakan? Nama layanannya khusus untuk distro dan saya tidak tahu ada distro yang menggunakan nama yang ada di sana. Apakah maksud Anda networkingdan network-manager? Juga, mengapa pengguna Anda memiliki sudoakses? Mereka seharusnya tidak kecuali Anda ingin mereka memiliki hak root penuh.
terdon
@terdon saya telah menyelesaikannya. Terima kasih. Saya tidak dapat mempostingnya sebagai jawaban karena saya adalah pengguna baru
shekhar
Ya Anda bisa, silakan lakukan. Saya juga ingin tahu jawaban yang Anda temukan.
terdon
@terdon yakin tapi itu mengatakan saya harus menunggu 8 jam untuk mengirim jawaban saya sendiri karena saya bahkan tidak punya 10 reputasi
shekhar
1
Ah, ya, maaf, Anda memang perlu menunggu. Saya baru saja di-upgrade, Anda memiliki perwakilannya sekarang :)
terdon

Jawaban:

47

Menggunakan CmndAlias ALLtidak akan pernah aman

Ada 1000 cara untuk berlari service network restarttanpa melakukan sudo service network restart. Berikut adalah contoh yang mungkin dicoba oleh pengguna yang nakal:

$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax

Jika Anda memberi pengguna ALLalias perintah, dan kemudian mencoba membuat daftar hitam, mereka akan selalu dapat menemukan jalan keluarnya. Bash daftar hitam, dan mereka akan menggunakan python. Blacklist python, dan mereka akan menggunakan Perl. Perl Daftar Hitam, dan mereka akan menggunakan PHP. Tidak ada yang menginginkan itu!

Jika Anda benar-benar tidak ingin seseorang melakukan sesuatu, Anda harus melakukan seperti yang dikatakan Thomas, dan membuat daftar putih hal-hal yang boleh mereka lakukan.


Menyiapkan daftar putih dengan pengecualian

Contoh daftar putih kecil dengan pengecualian dapat ditemukan di dekat bagian bawah man sudoers:

 pete           HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root

The user pete is allowed to change anyone's password except for root on the HPPA
machines.  Note that this assumes passwd(1) does not take multiple user names
on the command line.

(Sebenarnya contoh dari halaman manual ini tidak aman dan dapat dieksploitasi untuk mengubah kata sandi root! Lihat komentar di bawah ini untuk caranya.)

Kita dapat mencoba untuk beradaptasi bahwa untuk kasus Anda, untuk menawarkan semua serviceperintah ke kelompok staf, tapi mengecualikan para service networkperintah yang perhatian Anda:

%staff ALL =   /usr/sbin/service *,                            \
             ! /usr/sbin/service *network*,                    \
             ! /usr/sbin/service *NetworkManager*

( ALLPosisi itu mengacu pada Host_Alias, bukan Cmnd_Alias ​​- membingungkan bukan?)

Pengguna tidak akan dapat menjalankan sudo bashatau sudo teeatau sudo wgetatau sudo /path/to/malicious_script. Anda dapat membuat daftar putih lebih banyak perintah admin untuk pengguna Anda jika Anda berhati-hati. Lebih spesifik!

Catatan: Saya menambahkan *sebelum kata di networkatas, kalau-kalau bendera yang tidak berbahaya pernah ditambahkan ke servicealat di masa depan. Mari kita bayangkan sebuah --verbosebendera ditambahkan di masa depan, maka pengguna akan dapat menjalankan yang berikut:

$ sudo service --verbose network restart

Jadi kita perlu *mengkonsumsi setiap flag sebelum nama layanan. Satu-satunya kelemahan adalah bahwa hal ini dapat memblokir layanan lain yang sebenarnya Anda tidak keberatan dijalankan oleh pengguna, misalnya layanan yang dipanggil safe-networkatau network-monitorjuga akan ditolak.


Bolehkan pengguna mengedit file menggunakan izin grup

Di bawah ini Anda dapat menemukan berbagai upaya menggunakan rnanomelalui sudountuk membiarkan pengguna mengedit file atau file. Tapi sebenarnya mereka lebih kompleks dan lebih berbahaya dari yang seharusnya.

Solusi yang jauh lebih sederhana dan aman adalah mengubah izin grup pada file tertentu yang ingin Anda buka hak suntingnya. Berikut adalah beberapa contoh:

### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project

### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website

Jika Anda membutuhkan lebih banyak kontrol berbutir halus (misalnya: akses hanya untuk 3 pengguna, tetapi tidak semua anggota staf) Anda dapat membuat grup baru menggunakan addgroupperintah, dan menambahkan hanya beberapa pengguna ke dalamnya.


Biarkan pengguna mengedit file melalui sudo

Sisa dari jawaban ini menjadi penyelidikan tentang betapa mudahnya meninggalkan lubang di sudokonfigurasi Anda ketika mencoba menawarkan fleksibilitas kepada pengguna Anda. Saya tidak akan merekomendasikan melakukan hal-hal berikut!

Jika Anda ingin memberi pengguna Anda akses untuk mengedit file tertentu, Anda dapat mencoba menggunakan rnano:

%staff ALL = /bin/rnano /etc/nginx/sites-available/host

rnanohanya akan membiarkan mereka mengedit file yang ditentukan. Itu penting untuk mencegah pengguna jahat mengedit layanan pemula yang berbeda (misalnya /etc/init.d/urandom), dan menambahkan baris yang akan dijalankan service network restart.

Sayangnya saya tidak menemukan cara untuk membatasi secara rvimmemadai (pengguna masih dapat membuka file apa pun menggunakan :e), jadi kami terjebak dengan nano.

Sayangnya memungkinkan pengguna untuk mengedit banyak file jauh lebih sulit ...


Biarkan pengguna mengedit banyak file (jauh lebih sulit dari yang seharusnya)

1. Pendekatan yang tidak aman

Hati-hati dengan wildcard! Jika Anda menawarkan terlalu banyak fleksibilitas (atau fleksibilitas apa pun), itu dapat dieksploitasi:

%staff ALL = /bin/rnano /etc/nginx/sites-available/*                # UNSAFE!

Dalam hal ini, pengguna jahat akan dapat mengedit skrip layanan pemula lainnya, dan kemudian menjalankannya:

$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system

(Sudo sebenarnya mencegah .dan ..memperluas perintah, tapi sayangnya tidak pada argumen.)

Saya berharap sesuatu seperti ini bisa berhasil, tetapi masih tidak aman:

%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]*   # UNSAFE!

Karena sudosaat ini hanya menawarkan pola gumpal , itu *akan cocok dengan apa pun - itu bukan regexp!

(Sunting: Saya memang mempertimbangkan jika Anda mungkin lolos dengan hal di atas dalam situasi Anda, karena tidak ada sub-folder di bawah sites-available. Kami memang meminta satu char dicocokkan setelah folder, dan /..akan gagal setelah nama file. Namun ini bukan solusi yang bisa diterapkan, karena rnanomenerima beberapa argumen. Lagi pula secara umum ini masih tidak aman pada folder yang memiliki subfolder!)

Bahkan jika kita tidak memiliki subfolder, dan kita mengecualikan setiap baris yang mengandung /../, aturan yang menawarkan *bola dunia masih bisa dieksploitasi, karena rnanomenerima banyak argumen (beralih melalui mereka <C-X>, dan ruang diterima dengan senang hati oleh *bola.

$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system

2. Mendorong amplop (juga akhirnya tidak aman)

Jadi bagaimana jika kita menolak garis yang berisi spasi, atau berusaha menjangkau /..? Maka solusi akhir yang bisa diterapkan adalah:

# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.

%staff ALL =   /bin/rnano /etc/nginx/sites-available/*,    \
             ! /bin/rnano */..*,                           \
             ! /bin/rnano /etc/nginx/sites-available/,     \
             ! /bin/rnano */.,                             \
             ! /bin/rnano * *

# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.

Kami menerima apa pun "di bawah" folder tetapi kami juga menolak panggilan apa pun rnanojika /..atau /.atau diteruskan, atau jika folder ditargetkan secara langsung. (Secara teknis /.eksklusi membuat eksklusi menjadi /..berlebihan, tetapi saya telah meninggalkan keduanya untuk kejelasan.)

Saya menemukan folder dan /.pengecualian diperlukan karena jika tidak pengguna dapat menargetkan folder itu sendiri. Sekarang Anda mungkin berpikir rnanoakan memblokir jika menunjuk ke folder, tetapi Anda akan salah. Sebenarnya versi saya (2.2.6-1ubuntu1) dimulai dengan peringatan ringan dan file kosong, lalu <C-X>meminta saya untuk memasukkan nama file yang ingin saya simpan, membuka vektor serangan baru! Yah setidaknya itu menolak untuk menimpa file yang sudah ada (dalam satu tes yang saya lakukan). Bagaimanapun, karena tidak ada cara untuk memasukkan subfolder dengan sudo ke daftar hitam, kita harus menyimpulkan bahwa pendekatan ini sekali lagi tidak aman. Pengguna maaf!

Penemuan ini membuat saya meragukan ketelitian nanomode "terbatas". Mereka mengatakan rantai hanya sekuat tautan terlemahnya. Saya mulai merasakan kombinasi sudoblack-magic hitam dan rnanomungkin tidak lebih aman dari rantai aster.

3. Pendekatan yang aman tetapi terbatas

Glob sangat terbatas - mereka tidak membiarkan kami mencocokkan kelas karakter beberapa kali. Anda dapat menawarkan beberapa pengeditan file, jika semua nama file Anda memiliki panjang yang sama (dalam hal ini hostdiikuti oleh satu digit):

%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9]       # SAFE

Tetapi jika Anda ingin memberikan akses kepada pengguna untuk mengedit berbagai file, Anda mungkin perlu menentukan setiap file secara eksplisit:

%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost    \
             /bin/rnano /etc/nginx/sites-available/coldhost   \    # SAFE
             /bin/rnano /etc/nginx/sites-available/wethost    \
             /bin/rnano /etc/nginx/sites-available/steves_dodgy_project

Jangan tergoda untuk menggunakan suatu*titik. Lihat bagian 1. dan 2. di atas untuk alasannya! Ingat: satu slip kecil dapat membahayakan seluruh akun pengguna super, dan seluruh sistem.

4. Tulis pemeriksa argumen Anda sendiri (keselamatan menjadi tanggung jawab Anda)

Saya berharap mereka akan menambahkan dukungan regexp sudodi masa depan; itu bisa menyelesaikan banyak masalah jika digunakan dengan benar. Tetapi kita mungkin juga perlu kemampuan untuk memeriksa properti argumen (untuk mengizinkan hanya file, hanya folder, atau hanya flag tertentu).

Tetapi ada satu alternatif untuk menciptakan fleksibilitas dalam sudo. Lewati tanggung jawab:

%staff ALL = /root/bin/staffedit *

Kemudian tulis staffeditskrip Anda sendiri atau dapat dieksekusi untuk memeriksa apakah argumen yang diberikan oleh pengguna adalah sah, dan hanya menjalankan permintaan mereka jika ada.

joeytwiddle
sumber
5
Jawaban ini butuh waktu lama, tetapi akhirnya saya pikir saya mengerti cara kerja sudo. Saya menyerah pada berbagai kesempatan di masa lalu, menemukan ALL=(ALL:ALL) ALLterlalu kurang dalam semantik, tetapi saya selalu berasumsi di suatu tempat itu akan memiliki pemeriksa argumen yang layak ... Saya salah. Ini benar-benar sangat terbatas. Bahkan pengecualian root passwd yang ditawarkan di halaman manual dapat dipecah dengan argumen baris perintah sederhana sudo passwd -q root,. Ya penulis sudo mendaftar [beberapa alternatif] (sudo.ws/sudo/other.html) di situs web mereka. Saya berharap mereka akan menambah dukungan regexp di masa depan.
joeytwiddle
Apakah Anda secara khusus menggunakan rnanodeskripsi Anda di sini karena ini adalah versi nano yang tidak memiliki fungsi 'save as'? Saya tidak terbiasa dengan program ini.
Shadur
Iya nih. Jika kita peduli dengan keamanan, editor seharusnya hanya mengedit satu file yang ditentukan, dan seharusnya tidak dapat membuka shell. Untuk info, $ man nanolalu/-R<Enter>
joeytwiddle
Koreksi: Untuk memecahkan contoh pete, yang -qharus datang sesudahnya: sudo passwd root -q. Contoh pete dapat dikeraskan dengan mengecualikan *root*.
joeytwiddle
Pertimbangkan menggunakan sudoedituntuk mengaktifkan modifikasi file dengan aman sudo.
Totor
5

Pertama, buka file sudoers dengan sudo visudo. Menambahkan user ALL=!/usr/sbin/servicewill, IIRC, melarang serviceperintah untuk pengguna user.

Sumber: http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell

Zeb McCorkle
sumber
Ini akan berhenti menjalankan layanan lain juga dan saya tidak menginginkannya. Terima kasih atas jawabannya. :)
shekhar
sementara jawaban Anda tidak membantu saya dengan tepat tetapi itu membantu menggali solusi terima kasih. tetapi Anda tahu memberi Anda suara positif atau mengirim jawaban kerja saya, saya tidak memiliki reputasi yang cukup. Saya pasti akan memberikan terima kasih saya begitu saya. Terima kasih.
shekhar
2
Ya, tapi tetap saja, seperti yang dikatakan orang lain, Anda harus sangat berhati-hati dengan itu. Ada banyak cara tentang cara mendapatkan akses. Perintah apa saja yang bisa menelurkan shell dan sebagainya. Caranya lebih mudah untuk mencari tahu perintah apa yang benar-benar mereka butuhkan dan mengizinkannya, daripada mencoba untuk mengecualikan semua perintah "terlarang".
Bonsi Scott
3
Daftar putih tidak dapat dipelihara dalam banyak skenario. Tujuan sebenarnya mungkin bukan untuk mencegah mereka melakukan sesuatu, melainkan untuk mencegah mereka melakukan sesuatu yang buruk secara tidak sengaja tanpa membatasi mereka. Daftar hitam bagus dalam kasus ini. Anda daftar hitam cara pengguna yang masuk akal akan melakukan tugas. Tapi daftar hitam melalui sudo mungkin tidak cukup - orang bisa dan memang menggunakan 'sudo bash'. Salah satu pendekatan adalah dengan membungkus perintah 'layanan', dan dalam kasus yang Anda tidak ingin mereka gunakan, beri tahu mereka. Tetapi Anda tidak akan pernah mencantumkan semua tindakan baik dalam daftar putih, atau semua tindakan buruk dalam daftar hitam.
Bob Kerns
1
Saya setuju dengan Anda, Bob. Untuk memungkinkan fleksibilitas, tanpa mengizinkan akses penuh, Anda sering harus menggulung solusi Anda sendiri, sebagai skrip pembantu, dan hanya daftar putih skrip tersebut. daftar putih sudo mungkin melakukan apa yang Anda butuhkan, tetapi seringkali mereka terlalu terbatas, atau terlalu mudah untuk dieksploitasi.
joeytwiddle
5

Saya telah menemukan solusinya.

Saya telah membuka terminal dan berubah menjadi pengguna root dengan su -kemudian saya mengetik visudountuk mengedit.

maka pada akhirnya saya telah menulis baris seperti

user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart

Kemudian saya telah menyimpan & menutup dan memulai kembali juga.

Sekarang Jika saya mengetik sebagai service network restartatau service NetworkManager restartmaka itu tidak mengizinkan saya dan memberikan kesalahan seperti

Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain

dan juga untuk service network restartperintah.

shekhar
sumber
12
Itu akan bekerja untuk pengguna yang tidak berpengalaman dan tidak berbahaya, tetapi mudah untuk menghindari batasan sudo, (misalnya sudo cp -p /etc/init.d/network /etc/init.d/network-not-in-sudo, lalu sudo /etc/init.d/network-not-in-sudo restart). Itulah sebabnya jauh lebih aman untuk membuat inklusi daripada pengecualian dalam file sudoers, mis. Menyatakan layanan apa yang diizinkan untuk berinteraksi dengan mereka.
Thomas
Segala sesuatu yang 'restart jaringan layanan' tidak, Anda dapat lakukan dengan perintah lain, seperti yang ada di skrip init.d jaringan. Saya bahkan tidak akan mencoba mendaftarkannya di sini. Tetapi jika Anda ingin, misalnya, untuk benar-benar mencegah modifikasi keadaan antarmuka, maka kebijakan SELinux menurut saya adalah cara yang harus dilakukan. Ini adalah topik yang kompleks, tetapi ketika daftar putih terlalu ketat atau memberatkan, dan daftar hitam tidak memadai, itu mungkin pilihan terbaik Anda. Ini diimplementasikan dalam kernel, dan memungkinkan Anda untuk membatasi akses ke antarmuka jaringan (dan sumber daya lainnya) bahkan untuk pengguna yang sudo'd.
Bob Kerns
Jika mungkin dengan SELinux maka akan lebih senang. @ BobKerns Terima kasih. Saya akan mencoba dengan cara itu.
shekhar
3

Jawaban sebenarnya untuk ini adalah Anda tidak dapat benar-benar mencegahnya. Anda mungkin mencegah seseorang yang tidak berbahaya menjalankan perintah itu secara tidak sengaja melalui metode yang dijelaskan dalam jawaban lain, tetapi jika seseorang benar-benar ingin menjalankannya dan ada di daftar sudoers, mereka dapat menjalankannya. Misalnya, mereka dapat melakukan hal berikut:

joe@box:~$ sudo bash root@box:~# service network restart

Atau perintah menyenangkan lain yang bisa mereka gunakan untuk menghindari batasan Anda dalam file sudoers:

sudo visudo

Singkatnya, jika Anda bisa menggunakan sudo dan tidak terbatas untuk menjalankan perintah tertentu, Anda dapat melakukan hampir semua yang Anda inginkan. Bahkan jika Anda membatasi mereka untuk serangkaian perintah tertentu, Anda harus memastikan bahwa tidak mungkin bagi pengguna untuk menyalin beberapa perintah lain yang ingin mereka jalankan dengan nama yang sama dengan perintah yang mereka jalankan ( seperti dengan menimpa perintah yang mereka miliki izin untuk dijalankan.)

reirab
sumber
Ya. Orang harus menghindari perintah yang dapat memunculkan shell dari dalam.
Bonsi Scott
1
Masalahnya adalah, ini bukan perintah yang ingin Anda lindungi, tetapi status objek kernel, seperti tabel perutean, antarmuka, dll. - apa pun perintah (atau panggilan sistem) yang digunakan. Dan Anda ingin melindunginya dari beberapa, tetapi tidak semua, pengguna root. SELinux dirancang untuk skenario semacam ini. Tapi pertama-tama, saya akan mulai dengan ulasan mengapa semua pengguna ini memiliki akses sudo. Jika mereka hanya perlu melakukan beberapa hal tertentu, operasi daftar putih di sudoers mungkin yang Anda butuhkan.
Bob Kerns
2

Gunakan firejail untuk membatasi pengguna dengan kotak pasir.

https://github.com/netblue30/firejail/

Tetapkan firejail sebagai shell daripada bash di / etc / passwd, untuk setiap pengguna yang ingin Anda batasi. Sangat mudah digunakan dan memiliki dokumentasi yang baik.

Contoh:

user:x:1000:1000:user:/home/user:/usr/bin/firejail
Jeff
sumber