Bir komut dosyasından kök ayrıcalık isteyin


23

Olarak çalıştırabilecek bir betiğim var sudo script.shveyapkexec script.sh

Komut dosyası, yalnızca adıyla çalıştırırken kullanıcıdan parolayı isterse kullanıcı açısından çok daha iyi olurdu script.sh.

Tüm komut dosyasını kök ayrıcalıklarla çalıştırma pkexecveya sudoçalıştırma isteğini nasıl "gömebilirim" ?

Not herşeyi çalıştıran sudo sh -cSenaryonun içinde fonksiyonlara sahip olarak kudretini en iyi çözüm olmayabilir.

Yanıtlar:


55

Bu işe yarayacak:

echo "$(whoami)"

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

örnek:

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

3
Bununla ilgili iyi olan şey, özyinelemeyledir exec- kendisini çağırın ama aynı zamanda süreci değiştirirken, komut dosyasının birden çok örneğini ortaya çıkarmayız
Sergiy Kolodyazhnyy

1
Kurtarmaya geri çekilme !!! Birkaç gün içinde buna bir ödül eklememi hatırlat!
Fabby

6
Bunu yaparken dikkat edilmesi gereken bir şey ayrıcalık artışıdır; Temel olarak, root olarak ne kadar çok komut çalıştırırsanız, kötü niyetli bir bilgisayar korsanının root hesabına erişmek için bir şeyden faydalanması için o kadar çok fırsat var. Tüm senaryoyu root olarak çalıştırmanın her zaman yanlış olduğunu söylemiyorum , ancak karar vermeden önce biraz düşünmeye değer. Cevabın buna değmesi güzel olurdu (gerekli olmasa da).
David Z

/ Etc / sudoers içinde ayarlanmış düzgün bir zaman aşımı değerine sahipseniz, isteğe bağlı olarak gerçekten root erişimi gerektiren komut dosyasındaki her komutun önüne sudo koyabilirsiniz ve yalnızca bir kez soracaktır. Sık sık karıştığım şeylerden biri, bir gui'den böyle bir betiği çağırmanın işe yaramamasıdır çünkü sudo şifre girişi için / dev / null komutunu alır ve başarısız olur. Bu, gksudo ve kdesudo'nun işlemek için tasarlandığı şeydi çünkü parola istemek için gui'yi kullanacaklar.
Joe

1
@ Coder256: Düzenlemenizin doğru olduğunu sanmıyorum. "$@"Her parametre için bir tane olmak üzere birden çok kelimeye genişleyecektir.
jwodder

12

Güzel bir iletişim istiyorsanız, bunun gibi bir şey deneyin. Bunu, yazdığım başka bir şeyden kopardım, bu yüzden ihtiyaç duymayacağınız ya da istemeyeceğiniz ekstra şeyler var, ancak genel fikri gösteriyor:

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 iletişim kutusu

Bu, zaten yoksa, yükleyebileceğiniz whiptail kullanır:

sudo apt-get install whiptail

1
Şifreyi neden bir değişkende saklıyorsunuz?
heemayl

10
Arama exec echo [PASSWORD]! Herhangi bir kullanıcının görebileceği komut satırında parolayı içeren bir işlem oluşturur. Yerleşik komutu kullanın echo(yerleşik sürümü ile builtin echozorlayın) veya bashism <<<(öyleyse :) sudo ... <<< "$pass"; Sh ve diğer mermilerin bu gibi durumlar için İşte Belgeleri var . Ayrıca, özel karakterler içermesi durumunda şifreyi de belirtin.
David Foerster

Alternatif olarak, koyun whiptailgibi ayrı bir komut ve kullanım şey haline komutu SUDO_ASKPASS=/path/to/askpass-with-whiptail.sh sudo -A -p "My password prompt" -- "$0" "$@"olması sudoistemi özel şifre ile anlaşma.
David Foerster

@DavidFoerster İşe yarayabilir, ancak daha sonra iki komut dosyasına ihtiyacınız vardır veya askpass komut dosyanızı geçici bir dosyaya yazıp sudo'ya iletirsiniz.
Michael Hampton

Tamam, ancak diğerleri zaten parolayı bir değişkene iletmenin istenmediğini belirtti. Bu kimliğe yaklaşma yolu, diyalog çıktısını burada gösterildiği gibi adlandırılmış yöneltme kanalına iletmektir. Askubuntu.com/a/704643/295286
Sergiy Kolodyazhnyy

11

blade19899'ın cevabı gerçekten de gitmenin yoludur, ancak biri shebang'da arayabilir sudo bash:

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

Belirgin uyarı, bunun yalnızca komut dosyası ile çağrıldığı sürece çalışacağı ve komut dosyası ile çağrıldığı ./scriptanda başarısız olacağıdır bash script.


5
Bu, bash scriptbir komut dosyasını çağırmak için hiçbir zaman komut satırına yazmamanızın nedenlerinden biridir . Dışındaki komut dosyasının belirtir şey varsa bashiçinde #!çizgi, o zaman onu çağırma bash scriptbaşarısız oluyor. Bir python betiğini çağırmaya çalışırsam bash script.py, aynı zamanda başarısız olur.
kasperd

1
Bununla birlikte perl script, çalıştırabilirsiniz . Gerçekten güzel olmak için Perl, Shebang hattını kontrol ediyor ve eğer Perl'i çağırmıyorsa doğru programı çalıştırıyor.
tbodt

Bu kötü, çünkü komut dosyasındaki her komutu sudo ile çalıştırıyor. Gerçekten sudo'ya ihtiyaç duyan birkaç komutu izole etmek ve gerektiğinde bunları eklemek daha iyidir. Bu sudo çağrılarına fonksiyonların değerlendirmesini dahil etmeyin; mümkün olduğu kadar açık ve minimal olmalıdır.
Douglas,

@DouglasHeld Buna katılıyorum olsa da, soruyu sorduğum şey şu: “Tüm betiği root ayrıcalığı ile çalıştırma isteğini pkexec veya sudo'ya nasıl isteklendirebilirim?”. Bunu yapmanın yararlı olacağı kullanım durumları olacağından oldukça emin olabilirsiniz.
kos

6

Kod içinde root erişimi gerektiren komutları öneriyorum sudo- eğer kullanıcı zaten izin alamadıysa, komut dosyası o noktada bir parola ister.

örnek

#!/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

Bu komut dosyası olarak sudo <scriptname>veya olarak çalıştırılabilir <scriptname>. Her iki durumda da şifreyi yalnızca bir kez soracaktır.


2
Buradaki sorun, kök erişimine ihtiyaç duyan çoklu komutların olabileceğidir, bu da sudoyedekli 25 farklı komut çağırmak anlamına gelir - bir kez sudo çağırmak daha kolaydır. Bununla birlikte, komut dosyanızın yalnızca bir kez sudo çağrısı yapmasının nedeni, sudo'nun 15 dakikadan fazla zaman harcadığıdır - bundan daha uzun süren komutların yeniden gönderilmesi gerekir. Senin tarzın işe yarıyor. . . Çalışmam için ihtiyacım olduğu gibi değil.
Sergiy Kolodyazhnyy

@Serg Küçük bir senaryo için sahip olduğum yöntem hızlı ve kolaydı - Gerçekten şık bir programcı değilim!
Charles Green

Bu sayfadaki en iyi programcı gönderisisiniz. Kullanılması gerektiği gibi sudo kullanıyorsunuz - yalnızca ihtiyaç duyulduğunda ve çok net sonuçlar bekleniyor.
Douglas

4

Görünüşe göre, buradaki kaygıyla başka kimsenin ilgilenmediği görülüyor. sudoBetiğinizin içine dağıttığınızı koymak , kötü kullanıcı alışkanlıklarını teşvik eder . (Dağıtım yaptığınızı farz ediyorum çünkü "kullanıcı açısından" diyorsunuz.)

Gerçek şu ki, bankacılığın güvenlik ilkesine benzer uygulamaların ve komut dosyalarının kullanımında bir rehber vardır: Kişisel bilgilerinizi asla sizi arayan ve "bankanızdan" aradıklarını söyleyen ve var olanları söyleme benzer nedenlerden dolayı.

Uygulamalar için kural:

Sizden ne yapıldığından emin değilseniz, istendiğinde şifrenizi asla yazmayın . Bu, sudoerişimi olan herkes için üç kere uygulanır .

Parolanızı yazıyorsanız, çünkü sudokomut satırında koştuğunuzda harika. Bir SSH komutu çalıştırdığınız için yazıyorsanız, sorun değil. Bilgisayarınızda oturum açtığınızda yazıyorsanız, elbette, harika.

Yalnızca bir yabancı komut dosyasını veya yürütülebilir dosyasını çalıştırırsanız ve istendiğinde şifrenizi tam olarak girerseniz , betiğin onunla ne yaptığı hakkında hiçbir fikriniz yoktur . Bildiğiniz her şey için düz metin dosyasında geçici bir dosyada depolanıyor olabilir ve hatta kendisinden sonra temizleyemeyebilir.

Açıkçası, bilinmeyen bir dizi komutun çalıştırılmasıyla ilgili ayrı ve ek endişeler var root, fakat burada bahsettiğim parola üzerindeki güvenliği korumak . Uygulamanın / komut dosyasının kötü amaçlı olmadığını varsaysanız bile, diğer uygulamaların onu ele geçirmesini ve kötü amaçlı olarak kullanmasını önlemek için şifrenizin güvenli bir şekilde kullanılmasını istiyorsunuz.

Bu yüzden, kendi kişisel cevabım, kök ayrıcalıklarına ihtiyaç duyuyorsa bülteninize koymak için en iyi şey şudur:

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

# do privileged stuff, etc.

Sizinle tamamen aynı fikirdeyken, ne sudo script_namekadar hassas olduğunu bilmeden bir şeyi çalıştıran bir kullanıcı , aynı. Belki bu fikir kötü alışkanlıkları teşvik eder - bunun hakkında hiçbir şey söylemeyeceğim. Ancak kilit nokta bir programın ne yaptığını bilmektir ve bu kullanıcının sorumluluğundadır. Açık kaynaklı yazılımın arkasındaki bütün fikir budur. Kendi senaryomu gelince, iyi. . . bir komut dosyası düz metindir - kullanıcılar ne yaptığını bilmek isterlerse okuyabilir
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy benzer, ancak şifrenizi doğrudan komut dosyasına yazarsanız, aslında daha da kötü. Sudo ile çalışan bir script hala şifrenizi bilmiyor.
Joker

1

Bu şekilde yaptım:

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

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

4
En azından değişkenlerinizden alıntı yapın.
muru

Değişkenlerinizden alıntı yapmak, şifreniz kısa çizgi ile başlasa bile yardımcı olmayabilir .
Joker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.