스크립트 내에서 루트 권한 요청


23

내가으로 실행할 수있는 스크립트가 sudo script.shpkexec script.sh

스크립트가 이름으로 비밀번호를 실행할 때 사용자에게 비밀번호를 요청하면 사용자 관점에서 훨씬 좋을 것입니다 script.sh.

루트 권한으로 전체 스크립트를 요청 pkexec하거나 " sudo실행 "하려면 어떻게해야합니까?

참고 로 모든 것을 실행하는 것이 sudo sh -c내가 스크립트의 기능을 가지고 힘 것이 최선의 해결책이 될 수 없습니다.

답변:


55

작동합니다 :

echo "$(whoami)"

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

예:

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

3
이것에 대한 좋은 점은 exec호출 자체를 통한 재귀 이지만 동시에 프로세스를 교체하는 것이므로 스크립트의 여러 인스턴스를 생성하지 않습니다.
Sergiy Kolodyazhnyy

1
구조 재귀 !!! 며칠 안에 이것에 현상금을 추가하도록 상기시켜주세요!
Fabby

6
이 작업을 수행 할 때 알아야 할 사항은 권한 에스컬레이션입니다. 기본적으로 루트로 실행되는 명령이 많을수록 악의적 인 해커가 루트 계정에 액세스하기 위해 무언가를 악용 할 기회가 더 많아집니다. 나는 전체 스크립트를 루트로 실행하는 것이 항상 잘못되었다고 말하는 것은 아니지만 그렇게 결정하기 전에 약간의 생각을 기울일 가치가 있습니다. 나는 대답이 그것에 닿으면 좋을 것이라고 생각합니다 (필수는 아니지만).
David Z

/ etc / sudoers에 적절한 시간 초과 값이 설정되어 있다면, 실제로 루트 액세스가 필요한 스크립트의 각 명령 앞에 sudo를 넣을 수 있으며 한 번만 요청합니다. sudo가 암호 입력을 위해 / dev / null을 가져 와서 실패하기 때문에 GUI에서 그러한 스크립트를 호출하면 작동하지 않는다는 것이 종종 엉망입니다. 그것이 gksudo와 kdesudo가 gui를 사용하여 암호를 요구하기 때문에 처리하도록 설계된 것입니다.
Joe

1
@ Coder256 : 편집 내용이 옳지 않다고 생각합니다. "$@"매개 변수마다 하나씩 여러 단어로 확장됩니다.
jwodder

12

예쁜 대화를 원한다면 이와 같은 것을 시도하십시오. 나는 이것을 내가 쓴 다른 것에서 똑바로 찢어 냈으므로 필요하지 않거나 원하지 않는 추가 자료가 있지만 일반적인 아이디어를 보여줍니다.

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 대화 상자

이것은 whiptail을 사용하며 아직 설치하지 않은 경우 설치할 수 있습니다.

sudo apt-get install whiptail

1
비밀번호를 변수에 저장하는 이유는 무엇입니까?
heemayl

10
전화하지 마십시오 exec echo [PASSWORD]! 모든 사용자가 볼 수있는 명령 줄에 암호를 사용하여 프로세스를 생성합니다. 어느 사용하는 내장 명령 echo(강제 내장 된 버전 builtin echo) 또는 bashism <<<(그래서 같은 : sudo ... <<< "$pass"); Sh와 다른 쉘에는 이러한 경우에 대한 문서 가 있습니다. 또한 특수 문자가 포함 된 경우 암호를 인용하십시오.
David Foerster

또는 whiptail명령을 별도의 스크립트에 넣고 사용자 정의 비밀번호 프롬프트를 처리 하는 것과 같은 SUDO_ASKPASS=/path/to/askpass-with-whiptail.sh sudo -A -p "My password prompt" -- "$0" "$@"것을 사용 sudo하십시오.
David Foerster

@DavidFoerster 작동 할 수 있지만 두 개의 스크립트가 필요하거나 askpass 스크립트를 임시 파일에 작성한 다음 sudo로 전달합니다.
Michael Hampton

그러나 다른 사람들은 이미 암호를 변수에 전달하는 것은 바람직하지 않다고 지적했습니다. 내가 여기에 표시된대로이 방법 아이디 접근 방식은 명명 된 파이프에 대화 상자의 출력을 전달하는 것입니다 askubuntu.com/a/704643/295286
세르지 Kolodyazhnyy

11

blade19899의 대답은 실제로 갈 길이지만, 세방에 전화 할 수도 있습니다 sudo bash.

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

명백한 경고는 스크립트가 호출되는 동안에 만 작동하며 스크립트가 호출 ./script되는 즉시 실패한다는 것입니다 bash script.


5
이것은 bash script스크립트를 호출하기 위해 명령 행에 입력하지 않아야하는 이유 중 하나입니다 . 스크립트 bash#!라인 이외의 것을 지정하면 호출 bash script이 실패합니다. 파이썬 스크립트를 사용하여 호출하려고하면 bash script.py실패합니다.
kasperd

1
perl script그래도 실행할 수 있습니다 . Perl은 정말 멋지게하기 위해 shebang 행을 확인하고 perl을 호출하지 않으면 올바른 프로그램을 실행합니다.
tbodt

sudo를 사용하여 스크립트의 모든 명령을 실행하기 때문에 이것은 나쁩니다. 실제로 sudo가 필요한 몇 가지 명령을 분리하여 필요한 곳에 추가하는 것이 좋습니다. 이러한 sudo 호출에 함수 평가를 포함시키지 마십시오. 가능한 한 명확하고 최소한이어야합니다.
Douglas

@DouglasHeld 동의 할 수도 있지만, 이것이 바로 다음과 같은 질문입니다. "루트 권한으로 전체 스크립트를 실행하도록 pkexec 또는 sudo에 요청을"포함 (embed) "할 수 있습니까?". 이 작업을 수행 할 수 있으면 유용 할 것입니다.
kos

6

스크립트에 루트 액세스 권한이 필요한 명령을 시작합니다 sudo. 사용자가 아직 권한을 얻지 못한 경우 스크립트는 해당 시점에 암호를 묻습니다.

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

이 스크립트는로 sudo <scriptname>또는로 실행할 수 있습니다 <scriptname>. 두 경우 모두 암호를 한 번만 요청합니다.


2
여기서 문제는 루트 액세스가 필요한 여러 명령이있을 수 있다는 것입니다. 즉 sudo25 개의 서로 다른 명령을 중복 호출하면 sudo를 한 번 호출하는 것이 더 쉽습니다. 그러나 스크립트가 sudo를 한 번만 호출하는 이유는 sudo의 시간이 15 분을 초과하기 때문입니다. 이보다 오래 걸리는 명령은 다시 프롬프트되어야합니다. 당신의 방법은 그냥 작동합니다. . . 내가 일하는 데 필요한 방식이 아닙니다.
Sergiy Kolodyazhnyy

@Serg 작은 스크립트의 경우, 내가 가진 방식이 빠르고 쉬웠습니다. 저는 정말 우아한 프로그래머가 아닙니다!
Charles Green

이 페이지에서 가장 우수한 프로그래머 게시입니다. sudo를 사용해야 할 때 정확히 사용해야합니다. 필요한 경우에만 매우 명확한 결과를 얻을 수 있습니다.
Douglas

4

여기서 아무도 명백한 우려를 해결 한 사람이없는 것 같습니다. 퍼팅 sudo은 다음 배포 할 것을 스크립트 내에서하는 것은 나쁜 사용자 습관을 추진하고 있습니다 . ( "사용자 관점에서"언급했기 때문에 배포한다고 가정합니다.)

진실은의 은행의 보안 원칙과 유사 응용 프로그램 및 스크립트 사용에 가이드 라인이있다이다 : 당신을 호출하고 그들은 "은행에서"전화하는거야라고 사람에게 개인 정보를 제공하지 마십시오가 , 어느 존재 비슷한 이유로.

응용 프로그램의 규칙은 다음과 같습니다.

비밀번호가 무엇인지 확실 하지 않은 경우 프롬프트가 표시되면 비밀번호를 입력하지 마십시오 . 이것은 sudo접근 권한 이있는 사람에게는 세 가지로 적용됩니다 .

sudo명령 줄에서 실행했기 때문에 비밀번호를 입력하는 경우 좋습니다. SSH 명령을 실행했기 때문에 입력하는 경우 좋습니다. 물론 컴퓨터에 로그인 할 때 입력하면 좋습니다.

외국어 스크립트 또는 실행 파일을 실행하고 암호를 묻는 메시지가 표시되면 암호를 입력 하면 스크립트가 무엇을하는지 알 수 없습니다 . 그것은 당신이 아는 모든 것을 위해 일반 텍스트로 임시 파일에 저장하고 심지어 자체 정리하지 못할 수도 있습니다.

분명히 알 수없는 명령 집합을 실행하는 것과 관련하여 별도의 추가 문제가 root있지만 여기서 말하는 것은 암호 자체에 대한 보안 유지 하는 것 입니다. 응용 프로그램 / 스크립트가 악성이 아니라고 가정하더라도 다른 응용 프로그램이 암호를 잡고 악의적으로 사용 하지 못하도록 암호를 안전하게 처리하기를 원합니다 .

따라서 이것에 대한 나의 개인적인 반응은 루트 권한이 필요한 경우 스크립트에 넣는 가장 좋은 방법은 다음과 같습니다.

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

# do privileged stuff, etc.

내가하는 일을 알지 못하고 무언가를 실행하는 사용자 인 당신에게 전적으로 동의하지만 sudo script_name, 동일합니다. 어쩌면이 아이디어는 나쁜 습관을 유발할 수 있습니다. 나는 그것에 대해 아무 말도하지 않습니다. 그러나 핵심은 프로그램이 무엇을하는지 아는 것이며, 이는 사용자의 책임입니다. 이것이 오픈 소스 소프트웨어의 기본 아이디어입니다. 내 자신의 스크립트에 관해서는. . . 스크립트는 평범한 텍스트입니다-사용자가 무엇을하는지 알고 싶다면 읽을 수 있습니다
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy는 비슷하지만 암호를 스크립트에 직접 입력하면 실제로 더 나쁩니다. sudo로 실행 된 스크립트는 여전히 비밀번호를 모릅니다.
와일드 카드

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.