sudo가 필요한 bash 스크립트에서 암호를 한 번만 입력하는 방법


21

데이터

  • 이 컴퓨터의 운영자 사용자가 자신의 cifs 공유를 마운트하기를 원합니다
  • sudoers파일이 이미 포함되어 /bin/mount -t cifs //*/* /media/* -o username=*있는 모든 사업자들에게 명령을
  • 사용자가 cifs암호를 두 번이 아니라 한 번만 입력하는 스크립트를 통해 공유 를 마운트하기를 원합니다 .
  • sudo 비밀번호와 cifs 비밀번호는 동일합니다.

내가 이미 가지고있는 것

이 스크립트는 작동합니다 :

#!/bin/bash
sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... 하지만 사용자는 동일한 비밀번호를 두 번 입력해야합니다!

  • 한번 sudo
  • 마운트 자체에 한 번

이것은 또한 작동합니다 :

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... 하지만 모든 운영자 사용자가 할 수 있어야합니다sudo sh (주요 보안 문제)

의문

어떻게 CIFS 공유 마운트 bash는을 주지 않고 ¹ sh에서 sudoers파일 이나 영구 / 임시 파일을 생성 ???

참고 1 : 파이썬, 펄, C, 고, ... 제발?
참고 2 :sudoers 파일을 통해 비밀번호를 제거 할 수 있다는 것을 알고 있지만 편의를 포기하지 않으면 서 보안을 강화하려고 시도합니다.


2
어때요 printf "%s\n" "$szPassword" "$szPassword" | sudo -S mount -t cifs / ...?
muru December

지금 시도 중! @Muru
Fabby 2016

답변:


24

대신 sudo as를 사용하여 사용자가 호출하도록해야합니다 sudo script. 요청하지 않으면 스크립트가 루트로 실행되고 있는지 확인하십시오.

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use sudo "$0" instead" 1>&2
   exit 1
fi

사용자의 비밀번호를 캡처하려고 시도하지 마십시오.


1
어쩌면 내가 누락 된 것이 있지만 이것이 암호 프롬프트 수를 2에서 1로 줄이는 방법을 설명 할 수 있습니까? 그렇지 않으면 이것이 어떻게 질문에 대답하는지 알 수 없습니다.
Oliphaunt-복원 Monica Monica

@Oliphaunt 비밀번호 프롬프트가 두 개 표시되지 않습니다. 설명해 주시겠습니까? 또한이 답변은 OP가 원하는 것이 아니라 필요한 것입니다. 루트로 명령을 실행하고 다른 유틸리티가 수행하는 방법 (루트가 있는지 확인, 그렇지 않으면 구제)
Braiam

1
OP의 문제 (내가 이해하는 바와 같이)는 사용자가에 의해 암호를 입력하라는 메시지를 표시 sudo한 다음 (성공적으로 인증하면) 다시 입력하라는 것입니다 mount. 유스 케이스 에서이 비밀번호는 동일하므로 OP가 사용자 가이 비밀번호를 한 번만 입력 해야하는 이유를 알 수 있습니다. 귀하의 솔루션이 도움이되지 않습니다. 비밀번호를 캡처해서는 안된다는 데 동의합니다.
Oliphaunt-복직 모니카

고맙지 만, 나는 질문을 조금 단순화했을 것입니다 : 그것은 이미 스크립트이고 이미 테스트를 포함하고 있습니다 (을 제외하고 1>&2) 자동 시작에 있으며 하나의 cifs 공유에 사용되었지만 이제는 3 개의 암호 이므로 실제로는 하나의 암호입니다 필요합니다. (운영자 그룹의 구성원이 아닌 다른 사람이 실행하려고 시도하는 경우 이미 해당 테스트가 포함되어 있습니다)
Fabby

@Fabby 아직도 당신이 문제에 잘못 접근하고 있다고 생각합니다. 이러한 경우 CIFS / SMB 공유의 암호를 안전하게 ( ~/.smbcredentials예를 들어 편집 ), sudo가 필요없는 경우에도 (gvfs, umount 또는 polkit을 사용하는 경우) "기억"하는 도우미가 있습니다.
Braiam

7

난 바보 야!

다음 스크립트 :

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

그냥 작동하고 :

  1. 비밀번호가 포함 된 파일을 만들지 않습니다
  2. 사용자가 여러 공유 (Windows 공유 포함)에 대해 하나의 비밀번호 만 입력 할 수 있습니다.
  3. 추가 권한을 부여 할 필요가 없습니다. :-)

1
1 질문 : 명령을 프로세스 목록에 에코합니까?
Rinzwind

3
@Rinzwind는 내장되어 있으므로 bash 또는 zsh에 있으면 안됩니다. 그러나 mount 명령은 가능합니다.
muru December

<<<대신에 사용할 수도 printf 있지만 더 나은 방법은 read완전히 삭제하고 sudo --stdin자체적으로 사용 하는 것입니다. $ printf "Type out your password\n" && sudo --stdin apt-get update 사용자 와 같은 것들은 여전히 ​​sudo 비밀번호를 입력 할 수 있습니다. 프로세스 목록에 넣지 않습니다. 그러나 물론 키로거, 잠재적 취약성 sudo및 blah, blah, blah 및 blah와 같은 다른 보안 문제는 무한대로 발생합니다.
Sergiy Kolodyazhnyy

@ SergiyKolodyazhnyy : 사람은 자유롭게 편집하십시오 !
Fabby

3

sudo이 명령을 실행하기 위해 비밀번호가 필요하지 않습니다 . 암호 프롬프트가 mount남아 있습니다.

sudoers다음과 같은 것을 포함

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

이것을 포함시킨 후에 sudo는 더 이상이 특정 명령에 대한 암호를 요구하지 않습니다. 사용자는 여전히 mount명령에 암호를 제공해야합니다 .

참고 : 나는 당신이 질문에 포함 된 명령을 그대로 사용했습니다. 와일드 카드로 인해 사용자가 불쾌한 일을 할 수 있는지 여부는 확인하지 않았습니다. sudoers불쾌감의 예 는 맨 페이지를 읽으십시오 . 특히,이 줄 sudoers은 사용자가 -o스위치 또는 다른 인수를 여러 개 추가 할 수 있도록 mount합니다. 예를 들어 @Braiam 제안과 같은 스크립트를 추가하여 sudo추가 인증 없이이 방법을 실행할 수 있도록 접근 방식을 다시 생각할 수 있습니다 . 그러면 스크립트는 사용자가 mount원하는 특정 형식 만 실행할 수 있도록합니다.

또한 모든 사용자에게이를 허용하는 대신이를 특정 그룹의 구성원으로 제한 할 수도 있습니다. 예를 들어 그룹 cifsmount을 만든 다음

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

@Fabby 죄송하지만이 점이 왜 위험합니까? 또한 나는 냉소의 힌트를 감지 할 수 있습니다.
Oliphaunt-복직 모니카

sudo에 암호가 필요하지 않더라도 mount에는 여전히 암호가 필요할 수 있습니다. / etc / sudoers 파일은 sudo가 비밀번호를 요구하지 않도록하기 위해 사용될 수 있습니다. mount가 암호를 요구하는지 여부에는 영향을 미치지 않습니다. 사람이 마운트에 실패하면 sudo는 실패한 명령을 실행하게되므로 문제가되지 않습니다.
TOOGAM

@TOOGAM 저의 의도였습니다. 두 개가 아닌 하나의 암호.
Oliphaunt-복직 모니카

내 의도는 sudoers 파일에 하나의 "연산자"그룹을 유지하는 것이므로 운영자가 자체 항목을 마운트하려고 시도하는 경우 여전히 비밀번호를 입력해야하지만 "표준"운영자 마운트를 마운트하려면 비밀번호 만 입력하면됩니다. 한 번 대신 5 번 ...하지만 다른 사람에 대한 솔루션의 힘 작업, 그래서 ... upvoted (원래 주석 제거)
Fabby

1

이러한 문제에 대한 일반적인 해결책은 스크립트를 요구하는 sudo의 맨 위에 다음과 같은 프리앰블을 두는 것입니다.

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the sudo password only once)
      sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put sudo in front of commands

any more commands here will run as superuser ...

스크립트의 일부 명령 sudo을 실행할 필요가없는 경우 여기에는 불필요한 권한 상승이 있다는 단점이 있습니다.

어쨌든, 나는이 작은 팁을 공유 할 것이라고 생각했습니다. 그것에 대한 가장 좋은 점은 이미 유효한 루트 루트 (예를 들어 이미 sudo에서 호출 한 경우)라면 올바른 일을 정상적으로 수행한다는 것입니다. 또한 오류가 발생하고 sudo를 사용하여 다시 입력 / 재실행하도록하는 것이 덜 친숙합니다.

제한된 시간 동안 사용자 자격 증명을 기억하도록 지시 하는 timestamp_timeout변수 를 체크 아웃 할 수도 있습니다 (분수 일 수도 있음).man 5 sudoerssudo


내가 쉽게 답을 얻을 수있는 스크립트를 과도하게 단순화 : 스크립트가 이미 포함되어 #test if root: if not: bail out if [[ $EUID -ne 0 ]]; then echo "This script must be run as root, use sudo "$0" instead" 1>&2 exit 1 fi 요점은 그것은 또한 포함되어 있다는 것입니다 여러 마운트 (다시 : 제거) 동일한 암호 모든 ... 어쨌든,하지만 덕분에
Fabby

1
요점은 위의 솔루션은 암호를 한 번만 입력하면된다는 것입니다 (sudo 용). 다른 것은 필요하지 않습니다. 또한 여러 개의 (권한이 많은) 특권 명령이 필요한 경우에도 모든 유사한 문제에 대해 일반적이고 오류가 있고 sudo로 명령을 다시 입력하는 것보다 더 우아합니다.
arielf

그것은 해야 하지만 하지 않습니다 ! ;-) 각 cifs 공유 마운트에는 암호도 필요하기 때문입니다. ( 우분투 암호와 다를 있지만이 경우 운영자가 Windows와 우분투 암호를 동기화 된 상태로 유지하는 것은 아닙니다)
Fabby
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.