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


23

내가으로 실행할 수있는 스크립트가 sudo script.sh나pkexec 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.