Pertanyaan Minta hak akses root dari dalam skrip


Saya memiliki skrip yang dapat dijalankan sebagai sudo script.sh atau pkexec script.sh

Akan jauh lebih baik dari sudut pandang pengguna jika skrip meminta kata sandi dari pengguna saat menjalankannya dengan nama script.sh.

Bagaimana saya bisa "menanamkan" permintaan pkexec atau sudo menjalankan seluruh skrip dengan hak istimewa root?

Catatan yang menjalankan segalanya dengan sudo sh -c mungkin bukan solusi terbaik karena saya memiliki fungsi dalam skrip.


23
2018-03-15 15:38


asal




Jawaban:


Ini akan berfungsi:

echo "$(whoami)"

[ "$UID" -eq 0 ] || exec sudo "$0" "$@"

contoh:

./test.sh 
blade
[sudo] password for blade: 
root

49
2018-03-15 15:40



Apa yang baik tentang ini adalah rekursi exec - memanggil dirinya sendiri tetapi pada saat yang sama menggantikan proses, jadi kami tidak menelurkan beberapa contoh skrip - Sergiy Kolodyazhnyy
Rekursi untuk menyelamatkan !!! Ingatkan saya untuk menambahkan hadiah untuk yang ini dalam beberapa hari! - Fabby
Sesuatu yang harus diperhatikan ketika melakukan ini adalah eskalasi hak istimewa; pada dasarnya, semakin banyak perintah yang Anda jalankan sebagai root, semakin banyak peluang bagi peretas jahat untuk mengeksploitasi sesuatu untuk mendapatkan akses ke akun root. Saya tidak mengatakan itu selalu salah untuk membuat seluruh skrip berjalan sebagai root, tetapi ada gunanya untuk memikirkannya sebelum Anda memutuskan untuk melakukannya. Saya pikir itu akan baik (meskipun tidak perlu) jika jawabannya akan menyentuh itu. - David Z
Jika Anda memiliki nilai timeout layak di / etc / sudoers, maka Anda dapat secara opsional menempatkan sudo di depan setiap perintah dalam skrip yang benar-benar membutuhkan akses root dan itu hanya akan ditanyakan satu kali. Satu hal yang sering saya salahkan adalah bahwa memanggil skrip semacam itu dari gui tidak akan berfungsi karena sudo mendapat / dev / null untuk memasukkan kata sandi dan gagal. Itulah yang dirancang gksudo dan kdesudo karena mereka akan menggunakan gui untuk meminta kata sandi. - Joe
@ Coder256: Saya tidak berpikir hasil edit Anda benar. "$@" akan meluas ke beberapa kata, satu untuk setiap parameter. - jwodder


Jika Anda ingin dialog yang cantik, cobalah sesuatu seperti ini. Saya merobek ini langsung dari sesuatu yang lain yang saya tulis, jadi ada barang ekstra yang mungkin tidak Anda butuhkan atau inginkan, tetapi itu menunjukkan gagasan umum:

brand="My Software"

# Check that the script is running as root. If not, then prompt for the sudo
# password and re-execute this script with sudo.
if [ "$(id -nu)" != "root" ]; then
    sudo -k
    pass=$(whiptail --backtitle "$brand Installer" --title "Authentication required" --passwordbox "Installing $brand requires administrative privilege. Please authenticate to begin the installation.\n\n[sudo] Password for user $USER:" 12 50 3>&2 2>&1 1>&3-)
    exec sudo -S -p '' "$0" "$@" <<< "$pass"
    exit 1
fi

sudo dialog

Ini menggunakan whiptail, yang dapat Anda instal jika Anda belum memilikinya:

sudo apt-get install whiptail

12
2018-03-16 03:49



Mengapa Anda menyimpan kata sandi dalam sebuah variabel? - heemayl
Jangan telepon exec echo [PASSWORD]! Ini akan menelurkan proses dengan kata sandi pada baris perintah yang dapat dilihat oleh setiap pengguna. Gunakan perintah built-in echo (paksa versi bawaan dengan builtin echo) atau bashisme <<< (seperti ini: sudo ... <<< "$pass"); Sh dan shell lainnya Di sini Dokumen untuk kasus-kasus ini. Juga, kutip kata sandi jika berisi karakter khusus. - David Foerster
@DavidFoerster Semua ide bagus, terima kasih! - Michael Hampton
Sebagai alternatif, masukkan whiptail perintah ke skrip terpisah dan gunakan sesuatu seperti SUDO_ASKPASS=/path/to/askpass-with-whiptail.sh sudo -A -p "My password prompt" -- "$0" "$@" memiliki sudo berurusan dengan permintaan kata sandi khusus. - David Foerster
@DavidFoerster Itu bisa berfungsi, tetapi Anda juga membutuhkan dua skrip, atau Anda menulis skrip askpass ke file sementara lalu meneruskannya ke sudo. - Michael Hampton


Jawaban blade19899 memang cara untuk pergi, namun orang juga bisa menelepon sudo bash di shebang:

#!/usr/bin/sudo bash
# ...

Peringatan yang jelas adalah ini hanya akan berfungsi selama script dipanggil ./script dan akan gagal segera setelah skrip dipanggil bash script.


11
2018-03-15 16:28



Ini adalah salah satu alasan mengapa Anda tidak perlu mengetik bash script pada baris perintah untuk memanggil skrip. Jika skrip menentukan hal lain selain bash dalam #! baris, kemudian memohonnya dengan bash script akan gagal. Jika saya mencoba untuk memanggil skrip python menggunakan bash script.py itu juga akan gagal. - kasperd
Anda bisa menjalankannya perl script, meskipun. Perl, dalam upaya untuk menjadi benar-benar sangat bagus, periksa garis shebang, dan jika itu tidak memohon perl menjalankan program yang benar. - tbodt
Ini buruk karena menjalankan setiap perintah dalam skrip dengan sudo. Lebih baik untuk mengisolasi beberapa perintah yang benar-benar membutuhkan sudo dan menambahkannya jika diperlukan. Jangan sertakan evaluasi fungsi dalam panggilan sudo ini; mereka harus sejelas dan sesedikit mungkin. - Douglas Held
@DouglasHeld Meskipun saya setuju dengan itu, inilah pertanyaan yang ditanyakan: "Bagaimana saya bisa" menanamkan "permintaan ke pkexec atau sudo untuk menjalankan seluruh skrip dengan hak istimewa root?". Cukup yakin akan ada kasus penggunaan yang dapat melakukan hal ini akan berguna. - kos


Saya mengawali perintah dalam skrip yang perlu akses root sudo - jika pengguna belum mendapatkan izin, skrip meminta kata sandi pada saat itu.

contoh

#!/bin/sh 
mem=$(free  | awk '/Mem:/ {print $4}')
swap=$(free | awk '/Swap:/ {print $3}')

if [ $mem -lt $swap ]; then
    echo "ERROR: not enough RAM to write swap back, nothing done" >&2
    exit 1
fi

sudo swapoff -a && 
sudo swapon -a

Skrip ini dapat dijalankan sebagai sudo <scriptname> atau sebagai <scriptname>. Dalam kedua kasus itu akan meminta kata sandi, hanya sekali.


6
2018-03-15 15:51



Masalahnya di sini adalah mungkin ada beberapa perintah yang membutuhkan akses root, yang berarti menelepon sudo untuk 25 perintah yang berbeda redundant - lebih mudah untuk memanggil sudo sekali. Namun di sini, alasan skrip Anda memanggil sudo hanya sekali karena sudo memiliki waktu dari 15 menit - perintah yang membutuhkan waktu lebih lama daripada yang perlu ditinjau kembali. Cara Anda bekerja dengan adil. . . bukan cara saya membutuhkannya untuk bekerja. - Sergiy Kolodyazhnyy
@Serg Untuk skrip kecil, cara saya cepat dan mudah - saya benar-benar bukan programmer yang elegan! - Charles Green
Anda adalah memposting programer terbaik di halaman ini. Anda menggunakan sudo persis seperti yang seharusnya digunakan - hanya jika diperlukan dan dengan hasil yang sangat jelas yang diharapkan. - Douglas Held


Tampaknya tidak ada orang lain yang membahas masalah yang jelas di sini. Puting sudo dalam naskah Anda yang kemudian Anda distribusikan mempromosikan kebiasaan pengguna yang buruk. (Saya berasumsi Anda mendistribusikannya karena Anda menyebutkan "dari sudut pandang pengguna.")

Yang benar adalah bahwa ada pedoman dalam menggunakan aplikasi dan skrip yang mirip dengan prinsip keamanan dalam perbankan: Jangan pernah memberikan informasi pribadi Anda kepada seseorang yang menelepon Anda dan mengatakan bahwa mereka memanggil "dari bank Anda", dan yang ada karena alasan serupa.

Aturan untuk aplikasi adalah:

Jangan pernah mengetikkan kata sandi Anda ketika diminta kecuali Anda tertentu apa yang sedang dilakukan dengan itu.  Ini berlaku triply bagi siapa saja dengan sudo mengakses.

Jika Anda mengetikkan kata sandi karena Anda berlari sudo pada baris perintah, bagus. Jika Anda mengetiknya karena Anda menjalankan perintah SSH, baiklah. Jika Anda mengetiknya ketika Anda masuk ke komputer Anda, bagus, tentu saja.

Jika Anda hanya menjalankan skrip asing atau dieksekusi dan tanpa rasa masukkan kata sandi Anda ketika diminta untuk itu, Anda punya tidak ada ide apa yang dilakukan skrip dengan itu. Itu bisa menyimpannya dalam file temp di plaintext, untuk semua yang Anda tahu, dan bahkan mungkin gagal untuk membersihkannya sendiri.

Tentunya ada kekhawatiran terpisah dan tambahan tentang menjalankan satu set perintah yang tidak dikenal sebagai root, tapi yang saya bicarakan di sini adalah menjaga keamanan pada kata sandi itu sendiri. Bahkan dengan asumsi aplikasi / skrip tidak berbahaya, Anda tetap ingin kata sandi Anda ditangani secara aman untuk mencegahnya lain aplikasi untuk memperolehnya dan menggunakannya dengan jahat.

Jadi, tanggapan pribadi saya sendiri terhadap hal ini adalah, hal terbaik untuk dimasukkan ke dalam skrip Anda jika membutuhkan hak akses root, adalah:

#!/bin/bash
[ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;}

# do privileged stuff, etc.

3
2018-03-21 01:28



Sementara saya sepenuhnya setuju dengan Anda, pengguna yang menjalankan sesuatu tanpa mengetahui apa yang dilakukannya sudo script_name sama rentan, itu sama. Mungkin ide ini mempromosikan kebiasaan buruk - saya tidak akan mengatakan apa pun tentang itu. Tetapi kuncinya adalah mengetahui apa yang program lakukan, dan itu tanggung jawab pengguna. Itulah ide di balik perangkat lunak open-source. Seperti untuk naskah saya sendiri, yah. . . script adalah teks biasa - pengguna dapat membacanya jika mereka ingin tahu apa yang dilakukannya - Sergiy Kolodyazhnyy


Saya melakukannya dengan cara ini:

echo -n "Enter password for sudo rights: "
read -s pass

echo $pass | sudo -S [your command here]

1
2018-03-19 09:32



Setidaknya mengutip variabel Anda. - muru
Dan mengutip variabel Anda bahkan mungkin tidak membantu jika kata sandi Anda dimulai dengan tanda hubung. - Wildcard