Jalankan hanya sebagian skrip sebagai sudo, masukkan kata sandi hanya sekali

14

Saya menulis skrip (sebenarnya kombinasi skrip dan makefile) yang menginstal dependensi eksternal: beberapa apt-getperintah, beberapa gitkloning, membangun, menginstal, menambahkan pengguna ke grup, ...

Beberapa operasi dalam skrip ini memerlukan izin pengguna super, beberapa tidak.

Sampai sekarang saya telah menjalankan seluruh proses make dengan sudo, tetapi memiliki beberapa kelemahan:

  • gitrepo yang saya klon dapatkan rootsebagai pemilik, yang berarti saya tidak dapat memodifikasinya sesudahnya tanpa sudoatauchown
  • skrip yang menambahkan pengguna ke grup tidak tahu pengguna mana yang akan ditambahkan sejak whoamikembaliroot

Apa cara terbaik untuk menjalankan sebagai superuser hanya perintah yang membutuhkannya? Idealnya proses ini masih mengharuskan saya untuk memasukkan sudokata sandi, tetapi hanya sekali pada awal proses instalasi. Maka akan melupakannya di akhir, tetapi tetap sepanjang waktu sampai saat itu (bisa memakan waktu beberapa jam).

Solusi yang saya temukan online meliputi:

  • sudo -vpada awal naskah, tetapi jika saya mengerti benar kali ini. Skrip saya dapat berjalan selama beberapa jam
  • menjalankan skrip dengan sudo, tetapi perintah yang tidak perlu superuser sudo -u $(logname) <command>. Inilah yang saya lakukan sekarang, tetapi rasanya harus sebaliknya.

Idealnya, saya ingin skrip saya untuk:

  1. meminta kredensial pengguna super
  2. jalankan perintah normal sebagai pengguna yang login
  3. jalankan perintah sudo dengan kredensial yang dimasukkan pada langkah 1
  4. sudo -k untuk menutup sesi pengguna super
Gauthier
sumber
2
Anda masih dapat menjalankan semuanya sebagai sudo, dan skrip Anda dapat memeriksa SUDO_USERvariabel lingkungan. Jika ada, ini akan berisi nama pengguna pengguna yang meminta sudo. Jadi, Anda dapat (sebagai root) chown $ SUDO_USER: $ SUDO_GID $ your_files. Demikian pula, Anda dapat memeriksa variabel-variabel ini sehingga perintah adduser Anda tahu pengguna mana yang akan ditambahkan.
roadmr
... atau jalankan semuanya sebagai root dan gunakan su $SUDO_USER -c commanduntuk perintah yang dijalankan sebagai pengguna normal.
Rmano

Jawaban:

7

Karena Anda memiliki akses sudo, buat sendiri file sudoers, lalu hapus ketika skrip selesai:

# grant this user access to the sudo commands without passwords
# add all required cmds to the CMDS alias
sudo tee /etc/sudoers.d/$USER <<END
$USER $(hostname) = NOPASSWD: /usr/bin/apt-get, /usr/sbin/adduser, /bin/rm, ...
END

# your script goes here
sudo apt-get install ...
git clone ...
sudo adduser group2 $USER
sudo adduser group1 $USER
: ...

# then, remove the sudo access
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
glenn jackman
sumber
2

Salah satu cara, bahwa saya tidak akan umumnya merekomendasikan, adalah untuk membaca sandi sendiri, dan menggunakan sudo's -Spilihan untuk melewati password sebagai dan bila diperlukan:

#! /bin/bash
IFS= read -rsp 'Enter your password: ' password
git clone ...
sudo -S apt-get install foo -y <<<"$password"

Dari man sudo:

 -S, --stdin
             Write the prompt to the standard error and read the password
             from the standard input instead of using the terminal device.
             The password must be followed by a newline character.
muru
sumber
1
Apakah itu aman? echo "$password"??
αғsнιη
@KasiyA echo "$password"tidak akan, tetapi heredocs dan herestrings sedikit lebih aman. Mereka tidak terlihat di baris perintah yang ditunjukkan oleh alat yang biasa.
muru
1
Saya pikir, tegasnya, echo "$password"di sisi kiri dari pipa adalah aman di script bash. echoadalah shell builtin; /bin/echotidak berjalan ketika itu disebut sederhana echo .... Beberapa cangkang lain memiliki echobuiltin ( dash, misalnya), tetapi cangkang Bourne-style tidak diharuskan memilikinya. Jadi saya pikir echo "$password" |ini dapat diterima di bash tetapi mungkin lebih baik dihindari jika seseorang port script ke shell lain tanpa memperhatikan masalah ini. Saya menggunakan non-portabel [[alih - alih [dalam skrip itu untuk menghindari masalah yang sama. @KasiyA
Eliah Kagan