Praktik terbaik tentang penggunaan sudo dalam skrip bash

11

Saya memiliki skrip bash yang panjang dan berjalan lama di mana beberapa perintah perlu dijalankan sebagai root sementara mayoritas perintah harus dijalankan sebagai pengguna biasa sebelum sudo, karena itu akan mengacaukan kepemilikan file dan semacamnya.

Saya datang dengan beberapa metode, tetapi masing-masing memiliki beberapa masalah

Metode 1: Menggunakan sudo di dalam file

#!/bin/bash
sudo echo "I must be run by root"
touch needsToBeOwnedByUser1
echo "needs to be run by user"
sleep 1000
sudo echo "I, again, must be run by root"

Ini akan terlihat bagus, dari cara kode ditulis. sudoditulis sebelum beberapa pernyataan yang sebenarnya perlu dijalankan oleh root, tetapi jika waktu antara setiap sudopanggilan terlalu lama sudolagi meminta kata sandi. Juga, jika eksekusi pertama sudogagal, misalnya karena kata sandi tidak valid, sisa skrip masih dieksekusi.

Metode 2: menggunakan sudo untuk memanggil file dan kemudian kembali ke pengguna asli saat diperlukan

#!/bin/bash
echo "I must be run by root"
su username -c 'touch needsToBeOwnedByUser1'
su username -c 'echo "needs to be run by user"'
su username -c 'sleep 1000'
echo "I, again, must be run by root"

Ini juga menyebalkan, karena saya perlu menambahkan su username -cdi depan hampir setiap baris. Juga menemukan nama pengguna asli setelah sudoitu mungkin, tetapi rumit.

Apakah ada cara yang lebih baik?

Sunting: Saya hanya memposting skrip kecil yang tidak masuk akal di sini untuk menunjukkan apa yang saya bicarakan. Dalam skrip yang sebenarnya saya memiliki beberapa baris yang memerlukan sudo (layanan mulai dan berhenti), beberapa baris di mana tidak masalah jika ada sudo dan cukup banyak baris yang benar-benar perlu dijalankan tanpa sudo.

Dakkaron
sumber
4
Ini sangat jarang dibutuhkan. Dalam kebanyakan kasus, Anda hanya menjalankan skrip dengan sudojika perlu memiliki izin yang lebih tinggi. Tapi tidak ada gunanya beralih su username -cke menjalankan echo. Dengan kata lain, ini terdengar seperti [XY]. Bisakah Anda mengedit dan menjelaskan apa yang sebenarnya akan dilakukan skrip Anda dan mengapa Anda merasa harus sering berganti pengguna?
terdon
1
@ElderGeek apakah Anda menempelkan tautan yang salah? Itu bahkan tidak tampak berhubungan. Ini mungkin merupakan duplikat dari Bagaimana saya menjalankan perintah 'sudo' di dalam skrip? tapi saya harap OP bisa menjelaskan sedikit lagi.
terdon
@terdon Sepertinya begitu. Membersihkan.
Penatua Geek
Ini hanya contoh skrip. Saya tidak ingin menempelkan 200+ skrip baris di sini. Saya akan mengedit jawabannya untuk lebih jelasnya.
Dakkaron
Sudahkah Anda mempertimbangkan opsi validasi, yang dijelaskan dalam man sudo? -v, --validate 'Perbarui kredensial yang di-cache pengguna, diautentikasi jika perlu. Untuk plugin sudoers, ini memperpanjang batas waktu sudo selama 15 menit secara default, tetapi tidak menjalankan perintah. Tidak semua kebijakan keamanan mendukung kredensial yang di-cache. ' (Jika Anda menjalankannya cukup sering, sudo autentikasi seharusnya tidak habis.)
sudodus

Jawaban:

5

Mengenai metode 2, lebih mudah menggunakan fungsi. Sebagai contoh:

#!/bin/bash

func(){
    echo "Username: $USER"
    echo "    EUID: $EUID"
}

export -f func

func
su "$SUDO_USER" -c 'func'

$SUDO_USERadalah nama pengguna sudoer. Anda juga bisa menggunakannya $(logname)sebagai gantinya.

Berjalan di mesin saya:

$ sudo bash test.sh
[sudo] password for wja: 
Username: root
    EUID: 0
Username: wja
    EUID: 1000
wjandrea
sumber
2

Dengan membaca man sudoers, orang melihat:

 PASSWD and NOPASSWD

   By default, sudo requires that a user authenticate him or herself
   before running a command.  This behavior can be modified via the
   NOPASSWD tag.  Like a Runas_Spec, the NOPASSWD tag sets a default for
   the commands that follow it in the Cmnd_Spec_List.  Conversely, the
   PASSWD tag can be used to reverse things.  For example:

   ray     rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm

   would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm
   as root on the machine rushmore without authenticating himself. 

Dengan demikian, Anda dapat mengizinkan regularhost machine1untuk mengeksekusi command1dan command2sebagai root, tanpa otentikasi kata sandi dengan:

reguser machine1 root = NOPASSWD: /usr/local/command1, /usr/local/command2  

tapi baca masing-masing man -k sudountuk detailnya.

waltinator
sumber
0

Mungkin ini bisa membantu:

chmod 775 milikmu script.sh

Kemudian Anda dapat menggunakan sudo di dalam skrip (tanpa kata sandi) dan tidak dapat menggunakan sudo untuk perintah lain di dalam skrip Anda.

1337 HaXxoR
sumber
Saya khawatir itu tidak berhasil. chmod 775hanya memungkinkan Anda untuk mengeksekusi file dan tidak mengubah pengguna yang mengeksekusi file atau hak-hak mereka.
Dakkaron