쉘 스크립트에서 "sudo su"가 나머지 스크립트를 루트로 실행하지 않는 이유는 무엇입니까?


36

샘플 스크립트는 다음과 같습니다.

#!/bin/bash
sudo su
ls /root

사용하는 경우 ./test.sh일반 사용자로 대신 실행 ls이 루트로 전환, 슈퍼 사용자 종료로; 로그 아웃 ls /root하면 일반 사용자로 실행 됩니다.

아무도 그것에 대한 메커니즘에 대해 말해 줄 수 있습니까?


13
sudo su눈이 아프다
gelraen

사람들이 sudo를 충분히 알지 못하기 때문에 사용되기 때문에 의도적으로 손상된 암호로 root가 보호되는 시스템에서 su를 실행할 수있는 방법이 필요합니다. 그러나 sudo는 su의 사용을“중복”합니다.
Johan

1
sudo -s그래도 사용할 수 는 없습니까?
Joe Z.

@Johan, 내가 자주 사용하는 sudo su좀 더의 옵션을 사용이기 때문에 su내가들의 나보다 sudo. sudo의 옵션을 충분히 알고 있지만 su를 빠르게 입력 할 수 있습니다. 그러나 그래, 나는 그것이 sudo를 충분히 모른다는 것을 의미한다고 생각한다.
user606723

1
방금 sudo 매뉴얼 페이지를 확인했습니다. 마치 (대시없이) 작동 하는 sudo -i것과 비슷해 보입니다su -sudo -ssu
Johan

답변:


49

스크립트의 명령은 하나씩 독립적으로 실행됩니다. 스크립트 자체는 스크립트에있는 모든 명령의 부모로서 다른 독립 프로세스이며 su 명령은 루트로 변경할 수 없으며 루트로 변경할 수 없습니다. su 명령은 루트 권한으로 새 프로세스를 작성합니다.

su 명령이 완료된 후에도 여전히 동일한 사용자로 실행중인 상위 프로세스는 나머지 스크립트를 실행합니다.

당신이하고 싶은 것은 래퍼 스크립트를 작성하는 것입니다. 권한있는 명령은 기본 스크립트로 이동합니다 (예 :~/main.sh

#!/bin/sh
ls /root

랩퍼 스크립트는 다음과 같이 루트 권한으로 기본 스크립트를 호출합니다.

#!/bin/sh
su -c ~/main.sh root

이 프로세스를 시작하려면 랩퍼를 실행하고 사용자를 루트 사용자로 전환 한 후 기본 스크립트를 실행합니다.

이 래퍼 기술을 사용하면 스크립트를 자체 래퍼로 바꿀 수 있습니다. 기본적으로 루트로 실행 중인지 확인하고, 그렇지 않은 경우 "su"를 사용하여 다시 시작하십시오.

$ 0는 스크립트가 자신을 참조 할 수있는 편리한 방법이며 whoami 명령은 우리가 누구인지 알려줄 수 있습니다 (우리는 근본입니까?)

래퍼가 내장 된 기본 스크립트는

#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root

exec 사용에 유의하십시오. "이 프로그램을 다음으로 교체"를 의미합니다.이 프로그램은 실행을 효과적으로 종료하고 루트에서 su로 시작하여 새 프로그램을 시작하여 맨 위에서 실행합니다. 대체 인스턴스는 "루트"이므로 ||의 오른쪽을 실행하지 않습니다.


1
fwiw,이 점에 대한 부록. 내가 같은 스크립트를 작성하고 있다면 시작 부분에 $ EUID를 검사하고 sudo 자체가 0이 아닌 경우 종료하고 if 그렇지 않으면 스크립트 실행을 계속하십시오.
Bratchley

동의하며 이에 대한 답변을 업데이트하겠습니다.
Johan

2
어쩌면 조금 고풍 스럽지만 모든 실행 파일에 대한 절대 경로를 좋아하여 누군가가 ~ / main.sh 스크립트를 사악한 것으로 변경할 수 없습니다. 스크립트의 사용자 부분을 공격
artifex

2
$ *에 대한 참조를 포함하여 전달 된 인수를 잡을 수도 있습니다.
Bratchley

@JoelDavis 나는 항상 "인수에 공백 문자가 있다면 어떨까"라는 벽에 부딪칩니다. 만족스러운 해결책을 찾지 못했습니다. 일단 인수를 임시 파일 (한 줄당 하나의 인수)에 넣은 스크립트를 작성한 다음 필요한 모든 것을 호출하고 원래의 인수를 찾기 위해 읽을 파일의 인수를 최종 스크립트에 전달했습니다.
Johan

20

스크립트에서 다음을 사용하십시오.

sudo su <<HERE
ls /root
HERE

HERE 블록 사이의 코드는 루트로 실행됩니다.


6
sudo su두 개의 프로그램을 호출하고 있습니다. 사용 sudo -s <<HEREDOC또는 su user <<HEREDOC... 바보 5 분 제한.
Johan

6

추가 인수 su가 없으면 루트에 대한 로그인 쉘이 실행됩니다. 이것이 스크립트의 첫 번째 줄이 실제로하는 일입니다. 종료하면 로그인 셸이 닫히고 su가 반환되고 스크립트가 계속 실행됩니다 (두 번째 줄 포함) ls /root. 나는 sudo ls /root당신이 원하는 것을 간단히 할 수 있다고 생각합니다 .


예,에 대해이 작업을 수행 할 수 있다는 것을 알고 ls있지만 이는 샘플 일뿐입니다. 사실 나는 루트 권한으로 더 많은 일을해야합니다 :-) 그래서 나는 @Ankit의 대답을 선호합니다.
Hongxu Chen

1

당신이 발사되면 sudo su유효로 새로운 프로세스 userid (euid=EUID)갈래의 슈퍼 사용자를, 따라서 우리는 다른 프로세스 ID에서 실행 새로운 bash는이 (pid=PID)같은 터미널과 관련된를 (tname=TTY).

설명

소성 후 가정 ps -A | grep bash당신이 21460 pts/2 00:00:00 bash출력으로. 이제, 당신이 실행할 때 ./test.sh두 명령을 sudo suls /root에 스풀 얻을 것이다 PID 21460. root활성 사용자로 ps -A | grep bash다시 방문 했을 때 실행 후에 새로운 bash가 실행되고 있음을 알 수 PID say, 21570있습니다. 종료 root bash하면 새로 분기 된 bash가 되돌려 지고 프롬프트가 해제되기 전에 user's bash스풀 명령을 실행 ls /root합니다.


su 또는 sudo를 사용하는 것이 bash (또는 다른 곳)에서 "지속적"인 경우 해결 된 것보다 많은 문제가 발생합니다. 안전과 보안을 위해 가능한 한 최소한의 루트를 사용해야합니다. su와 sudo (보안 이외의 것)를 갖는 주요 요점은 루트 권한이 필요한 것에 대해 신중하게 생각하는 것입니다.
Joe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.