Menggunakan CmndAlias ALL
tidak akan pernah aman
Ada 1000 cara untuk menjalankan service network restart
tanpa melakukan sudo service network restart
. Berikut adalah contoh yang mungkin dicoba oleh pengguna nakal:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Jika Anda memberikan ALL
kepada pengguna alias perintah, dan kemudian mencoba membuat daftar hitam, mereka akan selalu dapat menemukan jalan keluarnya. Daftar hitam bash, dan mereka akan menggunakan python. Daftar hitam python, dan mereka akan menggunakan Perl. Blacklist Perl, dan mereka akan menggunakan PHP. Tidak ada yang menginginkan itu!
Jika Anda benar-benar tidak ingin seseorang melakukan sesuatu, Anda harus melakukan apa yang dikatakan Thomas, dan membuat daftar putih dari hal-hal yang mereka diizinkan untuk dilakukan.
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 dimanfaatkan untuk mengubah kata sandi root! Lihat komentar di bawah untuk mengetahui caranya.)
Kami dapat mencoba menyesuaikannya dengan kasus Anda, untuk menawarkan semua service
perintah ke grup staf, tetapi kecualikan service network
perintah yang menjadi perhatian Anda:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(ALL
dalam posisi itu mengacu pada Host_Alias, bukan Cmnd_Alias - membingungkan bukan?)
Pengguna tidak akan dapat menjalankan sudo bash
atau sudo tee
atau sudo wget
atau sudo /path/to/malicious_script
. Anda dapat memasukkan lebih banyak perintah admin untuk pengguna Anda jika Anda berhati-hati. Spesifik saja!
Catatan:Saya menambahkan *
sebelum kata network
di atas, kalau-kalau bendera yang tidak berbahaya pernah ditambahkan ke service
alat di masa depan. Bayangkan sebuah --verbose
flag ditambahkan di masa mendatang, maka pengguna akan dapat menjalankan yang berikut:
$ sudo service --verbose network restart
Jadi kita membutuhkan *
untuk menggunakan flag apa pun sebelum nama layanan. Satu-satunya kelemahan adalah bahwa ini dapat memblokir layanan lain yang Anda sebenarnya tidak keberatan dijalankan oleh pengguna, mis. sebuah layanan bernama safe-network
atau network-monitor
juga akan ditolak.
Izinkan pengguna mengedit file menggunakan izin grup
Di bawah ini Anda dapat menemukan berbagai upaya menggunakan rnano
melalui sudo
untuk membiarkan pengguna mengedit file atau file. Tapi sebenarnya mereka lebih kompleks dan lebih berbahaya dari yang seharusnya.
Solusi yang jauh lebih sederhana dan lebih aman adalah mengubah izin grup pada file tertentu yang ingin Anda buka hak editnya. Berikut beberapa contohnya:
### 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 memerlukan kontrol yang lebih halus (misalnya:akses hanya untuk 3 pengguna, tetapi tidak semua anggota staf), Anda dapat membuat grup baru menggunakan addgroup
perintah, dan tambahkan hanya beberapa pengguna ke dalamnya.
Biarkan pengguna mengedit file melalui sudo
Sisa dari jawaban ini menjadi penyelidikan tentang betapa mudahnya meninggalkan lubang di sudo
Anda konfigurasi saat 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
rnano
hanya akan membiarkan mereka mengedit file yang ditentukan. Itu penting untuk mencegah pengguna jahat mengedit layanan baru yang berbeda (misalnya /etc/init.d/urandom
), dan menambahkan baris ke dalamnya yang akan menjalankan service network restart
.
Sayangnya saya tidak menemukan cara untuk membatasi rvim
secukupnya (pengguna masih dapat membuka file apapun menggunakan :e
), jadi kita terjebak dengan nano
.
Sayangnya mengizinkan 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 karakter pengganti! Jika Anda menawarkan terlalu banyak fleksibilitas (atau fleksibilitas apa pun), itu dapat dimanfaatkan:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
Dalam hal ini, pengguna jahat dapat mengedit skrip layanan pemula lainnya, lalu menjalankannya:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Sudo sebenarnya mencegah .
dan ..
ekspansi pada 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!
Sejak sudo
saat ini hanya menawarkan glob pola, *
itu akan cocok dengan apa pun - ini bukan regexp!
(Sunting:Saya memang mempertimbangkan jika Anda mungkin lolos dengan yang di atas dalam situasi Anda, karena tidak ada sub-folder di bawah sites-available
. Kami memang meminta satu karakter dicocokkan setelah folder, dan /..
harus gagal setelah nama file. Namun ini bukan solusi yang bisa diterapkan, karena rnano
menerima banyak argumen. Lagi pula secara umum ini masih tidak aman pada folder yang memiliki subfolder!)
Meskipun kami tidak memiliki subfolder, dan kami mengecualikan setiap baris yang berisi /../
, aturan yang menawarkan *
glob masih bisa dieksploitasi, karena rnano
menerima beberapa argumen (menggilirnya di <C-X>
, dan ruang tersebut diterima dengan senang hati oleh *
gumpalan.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. Mendorong amplop (juga pada akhirnya tidak aman)
Jadi bagaimana jika kita menolak setiap baris yang berisi spasi, atau mencoba mencapai /..
? Maka solusi terakhir yang bisa diterapkan mungkin adalah ini:
# 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 ke rnano
jika /..
atau /.
atau dilewatkan, atau jika folder tersebut ditargetkan secara langsung. (Secara teknis,
/.
pengecualian membuat /..
pengecualian berlebihan, tetapi saya membiarkan keduanya untuk kejelasan.)
Saya menemukan folder dan /.
pengecualian diperlukan karena jika tidak, pengguna dapat menargetkan folder itu sendiri. Sekarang Anda mungkin berpikir rnano
akan memblokir jika diarahkan ke folder, tetapi Anda salah. Sebenarnya versi saya (2.2.6-1ubuntu1) dimulai dengan peringatan ringan dan file kosong, lalu pada <C-X>
meminta saya untuk memasukkan nama file apa pun yang saya suka untuk menyimpan, membuka vektor serangan baru! Setidaknya itu menolak untuk menimpa file yang ada (dalam satu tes yang saya lakukan). Lagi pula, karena tidak ada cara untuk memasukkan subfolder ke dalam daftar hitam dengan sudo, kita harus menyimpulkan bahwa pendekatan ini sekali lagi tidak aman. Maaf pengguna!
Penemuan ini membuat saya meragukan ketelitian nano
mode "terbatas". Mereka mengatakan sebuah rantai hanya sekuat mata rantai terlemahnya. Saya mulai merasakan kombinasi dari sudo
blacklist black-magic dan rnano
mungkin tidak lebih aman dari rangkaian bunga aster.
3. Pendekatan yang aman namun terbatas
Gumpalan sangat dibatasi - mereka tidak mengizinkan kami mencocokkan kelas karakter berkali-kali. Anda bisa tawarkan beberapa pengeditan file, jika semua nama file Anda memiliki panjang yang sama (dalam hal ini host
diikuti dengan satu digit):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Namun jika Anda ingin memberi pengguna akses 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 *
kapan saja. 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 (keamanan sekarang menjadi tanggung jawab Anda)
Saya harap mereka akan menambahkan dukungan regexp ke sudo
di masa depan; itu bisa memecahkan banyak masalah jika digunakan dengan benar. Namun, kami juga mungkin memerlukan kemampuan untuk memeriksa properti argumen (untuk mengizinkan hanya file, hanya folder, atau hanya flag tertentu).
Tapi ada satu alternatif untuk menciptakan fleksibilitas dalam sudo. Berikan tanggung jawab:
%staff ALL = /root/bin/staffedit *
Kemudian tulis staffedit
Anda sendiri skrip atau dapat dieksekusi untuk memeriksa apakah argumen yang diberikan oleh pengguna sah, dan hanya melaksanakan permintaan mereka jika benar.
Pertama, buka file sudoers dengan sudo visudo
. Menambahkan user ALL=!/usr/sbin/service
akan, IIRC, melarang service
perintah untuk pengguna user
.
Sumber:http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-Sudo-su-Bash-Shell
Saya telah menemukan solusinya.
Saya telah membuka terminal dan berubah menjadi pengguna root dengan su -
maka saya telah mengetik visudo
untuk mengedit.
kemudian 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 ulang juga.
Sekarang Jika saya mengetik sebagai service network restart
atau service NetworkManager restart
maka 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 restart
perintah juga.