Cara yang tepat untuk membiarkan pengguna memasukkan kata sandi untuk skrip bash hanya menggunakan GUI (dengan terminal tersembunyi)

8

Saya telah membuat skrip bash yang menggunakan kdialog secara eksklusif untuk berinteraksi dengan pengguna. Diluncurkan dari file ".desktop" sehingga pengguna tidak pernah melihat terminal. Ini terlihat 100% seperti aplikasi GUI (meskipun itu hanya skrip bash). Hanya berjalan di KDE (Kubuntu 12.04).

Satu-satunya masalah saya adalah menangani input kata sandi dengan aman dan nyaman. Saya tidak dapat menemukan solusi yang memuaskan.

Skrip dirancang untuk dijalankan sebagai pengguna biasa dan untuk meminta kata sandi saat perintah sudo pertama kali diperlukan. Dengan cara ini, sebagian besar perintah, yang tidak memerlukan hak sudo, dijalankan sebagai pengguna normal. Apa yang terjadi (ketika skrip dijalankan dari terminal) adalah bahwa pengguna diminta kata sandi mereka satu kali dan batas waktu sudo default memungkinkan skrip untuk menyelesaikan, termasuk perintah sudo tambahan, tanpa meminta pengguna lagi. Ini adalah bagaimana saya ingin itu berfungsi ketika dijalankan di belakang GUI juga.

Masalah utama adalah bahwa menggunakan kdesudountuk meluncurkan skrip saya, yang merupakan cara GUI standar, berarti bahwa seluruh skrip dieksekusi oleh pengguna root. Jadi kepemilikan file ditugaskan untuk pengguna root, saya tidak bisa bergantung pada ~/jalur, dan banyak hal lain yang kurang ideal. Menjalankan seluruh skrip sebagai pengguna root hanyalah solusi yang sangat tidak memuaskan dan saya pikir ini adalah praktik yang buruk.

Saya menghargai ide apa pun untuk membiarkan pengguna memasukkan kata sandi sudo hanya sekali melalui GUI sementara tidak menjalankan seluruh skrip sebagai root. Terima kasih.

MountainX
sumber

Jawaban:

14

The -Apilihan sudo memungkinkan Anda untuk menentukan program pembantu (dalam variabel SUDO_ASKPASS) yang akan meminta password.

Buat skrip untuk meminta kata sandi (myaskpass.sh):

#!/bin/bash
zenity --password --title=Authentication

Kemudian masukkan baris ini di awal skrip Anda:

export SUDO_ASKPASS="/path/to/myaskpass.sh"

dan ganti semua kejadian sudo <command>dengan:

sudo -A <command>

Anda dapat menggunakan program meminta kata sandi apa pun yang Anda inginkan zenity. Saya harus merangkumnya dalam skrip karena SUDO_ASKPASS harus mengarah ke file, sehingga tidak akan berfungsi dengan --passwordopsi yang diperlukan oleh zenity.

Perintah di atas berfungsi seperti jimat jika dijalankan dari baris perintah atau jika Anda memilih Jalankan di terminal setelah mengklik dua kali file skrip di manajer file, tetapi jika Anda memilih Jalankan atau coba jalankan dari file .desktop, setiap orang sudoakan meminta untuk kata sandi lagi.


Jika Anda tidak menginginkan jendela terminal sama sekali, Anda dapat menyimpan kata sandi dalam sebuah variabel dan mengirimkannya ke pipa sudo -S. Mungkin ada beberapa masalah keamanan, tapi saya pikir ini cukup aman (baca komentar pada jawaban ini ).

Masukkan baris ini di awal skrip Anda:

PASSWD="$(zenity --password --title=Authentication)\n"

dan ganti semua kejadian sudo <command>dengan:

echo -e $PASSWD | sudo -S <command>
Eric Carvalho
sumber
Terima kasih. Itu sangat menarik. Namun, saat menggunakan ini, batas waktu sudo yang biasa (misalnya, 15 menit) hilang. Skrip saya, yang memiliki lebih dari 50 perintah sudo sekarang meminta kata sandi pengguna 50+ kali! Saya mencari sedikit di Google dan saya tidak melihat solusi. Apakah kamu kenal satu?
MountainX
Terima kasih atas pembaruannya. Alternatif yang Anda sarankan adalah sesuatu yang saya singkirkan karena masalah keamanan, tetapi dari membaca komentar di tautan yang Anda berikan, saya pikir itu mungkin cukup aman. Dan itu adalah cara mudah untuk menyelesaikan masalah. Terima kasih.
MountainX
Pengujian pada sistem saya harus sudo -s(huruf kecil s) dan bukan sudo -S(huruf besar s).
WinEunuuchs2Unix
0

Ini didasarkan pada jawaban Eric Carvalho yang luar biasa. Saya mempostingnya untuk menguraikan masalah yang saya temui. Khususnya, ketika menggunakan ini, batas waktu sudo yang biasa (misalnya, 15 menit) hilang. Skrip saya, yang memiliki lebih dari 50 perintah sudo sekarang meminta kata sandi pengguna 50+ kali!

Berikut adalah contoh kerja penuh dari semua bagian dari solusi. Ini terdiri dari skrip bash, skrip "myaskpass" seperti yang disarankan Eric, dan file ".desktop". Semuanya harus 100% GUI (tidak ada interaksi terminal sama sekali), sehingga file .desktop sangat penting (afaik).

$ cat myaskpass.sh 
#!/bin/bash
kdialog --password "Please enter your password: "
exit 0


$ cat askpasstest1.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Comment=SUDO_ASKPASS tester1
Exec=bash /home/user/test/askpasstest1.sh
GenericName=SUDO_ASKPASS tester1
Name=SUDO_ASKPASS tester1
NoDisplay=false
Path[$e]=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
Categories=Application;Utility;
X-KDE-SubstituteUID=false
X-KDE-Username=

Dan skrip uji itu sendiri. Yang ini akan meminta kata sandi Anda dua kali saat menggunakan solusi ini. (Biasanya, itu akan meminta hanya sekali karena batas waktu sudo default.)

#!/bin/bash

sudo -k
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass1
touch filemadeas_regularuser1
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass2
touch filemadeas_regularuser2
ls -la filemadeas* > /home/user/test/fma.log
kdialog --title "Files Created" --textbox /home/user/test/fma.log 640 480
sudo rm filemadeas_*
rm fma.log

exit 0
MountainX
sumber
Menjalankan skrip ini dari baris perintah, kata sandi hanya diminta sekali. Berjalan dari GUI (mengeklik .desktop atau .sh di pengelola file) setiap kali sudo -Aditanyakan ulang kata sandi. Saya akan mencoba mencari tahu ini.
Eric Carvalho
Saya baru saja memperbarui jawaban saya.
Eric Carvalho
Eric ... apakah Anda mencari solusi untuk masalah ini?
anthony
0

Script berikut ini berfungsi melalui baris perintah, file desktop atau klik dua kali, hanya meminta kata sandi, dan pola perintah sudo -Sp '' <your command here> <<<${sudo_password}dapat digunakan beberapa kali di mana saja dalam file:

    # get sudo password
    sudo_password=$( gksudo --print-pass --message="Provide permission to make system changes: Type your password or press Cancel." -- : 2>/dev/null )
    # check for null entry or cancellation
    if [[ ${?} != 0 || -z ${sudo_password} ]]
    then
        exit 4
    fi
    if ! sudo -kSp '' [ 1 ] <<<${sudo_password} 2>/dev/null
    then
        exit 4
    fi
    # command
    sudo -Sp '' gedit "/etc/hosts" <<<${sudo_password}
Sadi
sumber