프로그램이 sudo에서 실행되고 있다고 말할 수 있습니까?


27

"sudo"에서 실행되는 경우 다르게 동작해야하는 프로그램이 있습니다. sudo에서 실행되었는지 확인할 수있는 방법이 있습니까?

업데이트 : 누군가 내가 왜 이것을하고 싶은지 물었습니다. 이 경우 MacPorts를 사용하는 Mac에는 특정 명령을 잘라서 붙여 넣기하라는 출력이 있습니다. MacPorts 명령이 "sudo"로 실행 된 경우 샘플 명령에 sudo가 포함되어야합니다.

$ sudo port selfupdate 
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.2.1 installed,
MacPorts base version 2.2.1 downloaded.
--->  Updating the ports tree
--->  MacPorts base is already the latest version

The ports tree has been updated. To upgrade your installed ports, you should run
  port upgrade outdated

^^^^^^^^^ it would be really sweet if it output "sudo port upgrade outdated" instead.  It would be even better if it just did it for you :-)

궁금합니다 : 어떻게 다르게 행동해야하는지 설명 할 수 있습니까?
sciurus

1
@sciurus는 일반적으로 일반적인 사용 사례는 루트 권한이 필요한 설치 스크립트에 있습니다. 당신이 그들을하지 않으면 즉시 죽어.
Nick T

3
이것은 meta.stackexchange.com/questions/66377/what-is-the-xy-problem/… 처럼 들립니다 . 당신이 정말로 하고 싶은 것은 무엇입니까 ?
Jenny D는 Monica Reinstate Monica가

나는 명령이 루트로 실행되는지 아닌지를 인식하는 일부 명령을 모호하게 기억합니다 ... 대답이 "예"라고 생각합니다
Rolf

답변:


48

예, 프로그램이 sudo에서 실행될 때 4 개의 환경 변수가 설정됩니다.

$ sudo env |grep SUDO
SUDO_COMMAND=/usr/bin/env
SUDO_USER=tal
SUDO_UID=501
SUDO_GID=20

간단히 설정하면 위조 될 수 있습니다. 중요한 것을 믿지 마십시오.

예를 들어 :이 프로그램에서 사용자에게 다른 프로그램을 실행하도록 지시해야합니다. 현재 하나가 sudo로 실행 되었다면 다른 하나도 마찬가지입니다.

#!/bin/bash

echo 'Thank you for running me.'

if [[ $(id -u) == 0 ]]; then
  if [[ -z "$SUDO_COMMAND" ]]; then
    echo 'Please now run: next_command'
  else
    echo 'Please now run: sudo next_command'
  fi
else  echo 'Error: Sadly you need to run me as root.'
  exit 1
fi

먼저 루트로 실행되고 있음을 증명할 수있는 경우 SUDO_ * 변수 만 테스트합니다. 그럼에도 불구하고 유용한 텍스트를 변경하는 데만 사용됩니다.


2
"중요한 것"에 무엇을 사용 하시겠습니까?
Kevin-복원 자 Monica Monica

3
@Kevin 누군가가 자신의 환경을 망쳐 서 높은 특권을 행사하는 가짜 인 경우, 자신이하는 일을 알고 희망을 갖고 결과를 받아 들일 것입니다.
Nick T

"중요한 것을 믿지 마십시오"라는 자격을 갖추어야하는 답변은 전혀 답이 아니라 추악한 해킹이기 때문입니다.
Stephen C

이것은 질문에 대한 완벽한 대답입니다. sudo를 감지 하지 않고 사용 하지 못하게 하려는 사람들을 위해 경고가 있어야 합니다. 사용자가 실행할 수있는 명령을 제한하려면 sudo의 명령 별명을 사용하여 예방해야합니다.
dwurf

11

이것은 질문에 직접 대답하지 않지만 올바른 질문이 여기에 있다고 생각하지 않습니다. asker는 특정 권한이 있는지 여부에 따라 아마도 다르게 작동하는 프로그램을 원하지만, sudo를 확인하는 것이 그렇게하는 방법이 아니라고 주장합니다. 첫째로 많은 시스템이 "스도"를 구현하지 않을 수도 있지만, 리눅스 나 많은 유닉스에서는 필요하지 않습니다.

예를 들어, 사용자가 이미 root로 로그인하여 sudo를 무의미하게 만들거나 시스템에 root 사용자가 아닌 사용자가 여전히 프로그램에서 수행하려는 관리 작업을 수행 할 수있는 기능을 가지고있을 수 있습니다. 마지막으로 시스템에는 루트 또는 sudo가 전혀 없으며 대신 다른 기능을 가진 필수 액세스 제어 시스템을 사용하고 모든 수퍼 유저가 sudo를 잡을 수는 없습니다. 또는 사용자는 보안상의 이유로 자신의 계정보다 권한이 적은 계정으로 sudoed 할 수 있지만 (권한을 높이 지 않고 삭제하기 위해 램 디스크에만 쓸 수있는 임시 권한이없는 사용자로 신뢰할 수없는 코드를 실행하는 경우가 종종 있습니다) ). sudo 또는 root의 존재와 같은 특정 권한 모델을 가정하거나 sudoed 사용자에게 특정 권한이 있다고 가정하는 것은 전반적으로 나쁜 생각입니다.

작업을 수행 할 수있는 권한이 있는지 확인하려면 일반적으로 간단하게 시도하여 수행 한 다음 실패한 경우 또는 실패하거나 모두 실패해야하는 다단계 작업 인 경우 errno에서 권한 문제를 확인하십시오. 작업이 POSIX 액세스 기능 과 같은 기능과 작동하는지 확인할 수 있습니다 (권한이 활발하게 변경되는 경우 가능한 경쟁 조건에주의하십시오)

또한 sudo 뒤에 실제 사용자를 알아야하는 경우 기본 터미널과의 대화 형 세션에서 작동 해야하는 getlogin 함수를 사용할 수 있으며 예를 들어 감사를 위해 명령을 '실제로'실행하는 사람을 찾을 수 있습니다. 로그를 저장할 실제 사용자의 홈 디렉토리.

마지막으로 실제로 원하는 것이 사용자에게 루트 액세스 권한이 있는지 알아내는 것입니다 (나쁜 아이디어이지만 구현에 덜 영향을 미칩니다) getuid 를 사용 하여 uid가 0인지 루트인지 확인할 수 있습니다 .


7

사용할 수있는 두 가지 메커니즘이 있습니다.

  • 환경 변수 확인은 어느 쪽이든 위조 될 수 있지만 가장 쉬운 방법입니다. growisofsSUDO에서 실행하는 것을 좋아하지 않으므로 SUDO 변수를 사용하는 스크립트에서 SUDO 변수를 설정 해제했습니다. 다른 방법으로는 위조 될 수 있습니다. (SUDO 변수는 at 및 batch 명령으로 실행되는 스크립트의 환경으로도 전달됩니다.)
  • sudo에서 실행 중인지 확인하는 또 다른 방법은 상위 프로세스에서 프로세스 목록을 검색하여 sudo를 찾는 것입니다. sudo에서 이런 식으로 달리고 있다는 것을 숨기는 것은 어렵지만 더 복잡합니다. sudo에서 실행 중이라는 것은 여전히 ​​가짜 일 수 있습니다.

적절한 사용자로 실행 중인지 확인하는 것이 더 일반적입니다. 이 id명령을 사용하여이를 수행 할 수 있습니다. TomOnTime의 스크립트는 id명령을 사용 sudo하여 다음 명령을 실행 해야하는지 여부를 결정합니다 .


1
> sudo에서 이런 식으로 실행 중이라는 것을 숨기는 것이 어려울 것입니다 . sudo바이너리의 이름 을 다른 것으로 바꿀 수 없었 습니까? 아니면 다른 실행 파일 이름을 지정 sudo하여 반대를 가짜로 만드십시오. 내가 정말로 제정신 인 사람이 그렇게 할 것으로 기대하지는 않습니다.
Bob

@Bob 실행 파일 root이름을 바꾸려면 액세스 권한 이 필요 합니다 sudo. 일반 사용자는이 작업을 수행 할 수 없습니다. 나는 당신이 아래에서 달리고 있다는 것을 가짜 할 수 있음을 언급했습니다 sudo. 기존 프로그램의 이름을 바꾸면 작동합니다. 전용 가짜 sudo프로그램에 필요한 코드 는 간단합니다.
BillThor

당신은 어딘가에서 sudo 바이너리를 다운로드하고 올바른 권한을 부여 할 수 있습니다 ...
Jens Timmerman

@JensTimmerman 올바른 권한을 부여하려면 루트 액세스 권한이 필요합니다. 이름을 바꾸거나 하드 링크하면됩니다. 다운로드 할 필요가 없습니다. SUID를 대상 사용자 ID에 설치 한 경우 (그런 식으로 작동하는 경우) 대상 사용자 ID를 이미 손상시켜야합니다.
BillThor

아, 맞아, 그것은 setuid없이 일하는 것을 거부한다, 나의 나쁜 ...
Jens Timmerman

2

유효 사용자 ID와 실제 사용자 ID를 비교할 수 있습니다.

이것은 실행 취소 sudo (setuid'd도 가능)를 실행한다는 것을 의미하지는 않지만 프로그램이 사용자가 기대할 수있는 것보다 더 많은 권한을 가지고 있음을 나타냅니다. (예를 들어 일반적으로 이러한 권한없이 실행되지만 설치 중 또는 업데이트를 설치하기 위해 해당 프로그램과 함께 실행해야하는 프로그램에서이 기능을 사용하여 이에 대한 경고 피드백을 제공 할 수 있습니다).


2
아니요, sudo유효 ID와 실제 ID를 모두 설정합니다. suid와는 달리, 그렇지 않습니다. 다음은 테스트에 사용할 수있는 간단한 C 프로그램입니다 (죄송합니다. 주석이 줄 바꿈을 제거하므로 다시 추가해야합니다) :#include <stdio.h> #include <unistd.h> #include <sys/types.h> int main() { printf("real = %i, effective = %i\n", getuid(), geteuid()); return 0; }
derobert

... 또는 대안으로perl -E 'say $<, "\n", $>'
derobert

2

다음과 같이 유효 UID (EUID) 변수를 확인할 수 있습니다.

if [[ $EUID -eq 0 ]]; then
    echo "running as root"
else
    echo "not running as root"
fi

이것은 질문에 대답하지 않습니다. 이 코드는 루트로 실행될 때 sudo로 실행할 때와 동일한 출력을 제공합니다.
Stephen C

@StephenC-OP의 목적에는 차이가 없다고 생각합니다. IMHO의 목표는 확실한 루트 쉘에서 sudo 실행 또는 실행을 구별하지 않고 식별하는 것입니다.
Eliran Malka

1
당신이 옳을 것 같아요 sudo echo $USER권한이없는 사용자 이름을 인쇄하는 이유를 이해하지 못했기 때문에 여기에 왔습니다 (변수는 sudo 전에 대체됩니다). 실제로 스크립트에서 코드를 사용했습니다. 고맙습니다!
Stephen C

가장 환영합니다 :)
Eliran Malka

-1

파일을 터치 한 /root다음 터치 할 수 있습니다 if -e. -e가 true이면 rm(오류 코드 확인) 테스트가 다음에 작동합니다.

rm 후 오류 코드 (또는 리턴 코드)를 확인하면 누군가가 sudo 권한을 사용하여 장난으로 파일을 만들 수 없습니다.


4
이 답변은 프로세스에 쓸 수 /root있는 권한이 있는지 확인하지만 (UID 0과 달리 반드시 같은 것은 아님),를 사용하여 해당 권한을 얻었는지 확인하지는 않습니다 sudo.
Ladadadada

그렇습니다. "고양이를 피부에 대는 수천 가지 방법"; 답을 썼을 때, 나는 또 다른 4 가지 또는 5 가지 사항을 생각 했으므로 마무리했습니다.
Chris K

-2

나는 이것이 이것에 잘 작동한다는 것을 알았다.

[ $(cat /proc/$PPID/loginuid) -ne 0 ] && [ "$USER" == "root" ]

FreeBSD, Centos7 또는 MacOS X에서 시도 할 때 작동하지 않습니다. "/ etc"대신 "/ proc"을 의미한다고 생각합니다. 그러나 그 변화가 있더라도 그 세 가지 중 어느 것도 작동하지 않습니다. "$ USER"는 sudo에 의해 재설정됩니다. $ SUDO_USER 님을 의미 했습니까? 또한 "["대신 "[["을 (를) 의미 했습니까?
TomOnTime

1
나는 예를 고쳤다. 기본적으로 loginuid를 확인하는 것은 0이 아니지만 사용자는 root입니다.
ruckc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.