CentOS 6.5에서 sudo-1.8.6을 실행하고 있습니다. 내 질문은 간단합니다. SHELL이 사용자 환경에서 sudo 환경으로 전파되는 것을 방지하는 방법은 무엇입니까?
종종 사람들은 다른 방향으로 갑니다. 그들은 환경 변수를 보존하기를 원합니다. 그러나 사용자 "zabbix"의 셸이 /sbin/nologin
sudo를 통해 명령을 실행하려고 할 때 문제가 발생했습니다. Sudo는 /sbin/nologin
루트가 하위 쉘을 실행할 수 없도록 유지됩니다 .(업데이트: 이 부분은 맞지만 SHELL 환경 변수가 아닙니다. 문제는 /etc/passwd에서 추출한 쉘 값입니다.)
문제를 설명하는 테스트를 포함했습니다. 실제 사용 사례는 아니지만 호출하는 사용자의 SHELL이 보존된다는 점만 보여줍니다. 사용자로 실행되는 프로그램이 있습니다 zabbix
. 호출합니다(프로그래밍 방식으로 daemon 으로 실행되므로 /usr/bin/sudo -u root /tmp/doit
비밀번호 파일의 쉘이 이를 차단하지 않습니다). 다음만 포함하는 쉘 스크립트입니다.zabbix
/sbin/nologin
/tmp/doit
#!/bin/sh
env > /tmp/outfile
(분명히 모드는 755입니다.) outfile
내가 볼 수 있는 한 그것은 SHELL
이다 /sbin/nologin
. 하지만 이 시점에서는 스크립트가 sudo를 통해 루트로 실행 중이므로 이전 사용자의 환경 변수가 없어야겠죠?
이것은 내 /etc/sudoers입니다:
기본값은 필수입니다. 기본값 !visiblepw 기본값은 Always_set_home 기본값 env_reset 기본값 env_keep = "컬러 표시 호스트 이름 HISTSIZE INPUTRC KDEDIR LS_COLORS" 기본값 env_keep += "MAIL PS1 PS2 QTDIR 사용자 이름 LANG LC_ADDRESS LC_CTYPE" 기본값 env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASURMENT LC_MESSAGES" 기본값 env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" 기본값 env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" 기본 secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin ## 루트가 어디서나 명령을 실행할 수 있도록 허용 루트올=(모두)모두 #includedir /etc/sudoers.d
이 내 꺼야 /etc/sudoers.d/zabbix
:
기본값: zabbix !requiretty zabbix ALL=(루트) NOPASSWD: /tmp/doit
편집: 추가 정보:
sudo를 실행하는 프로세스는 zabbix_agentd
Zabbix 모니터링 소프트웨어에서 가져온 것입니다. 파일에 다음 /etc/zabbix/zabbix_agentd.d/userparameter_disk.conf
과 같은 항목이 있습니다.
UserParameter=example.disk.discovery,/usr/local/bin/zabbix_raid_discovery
/usr/local/bin/zabbix_raid_discovery
파이썬 스크립트입니다. 간단히 이렇게 하도록 수정했습니다.
print subprocess.check_output(['/usr/bin/sudo', '-u', 'root', '/tmp/doit'])
/tmp/doit
이렇게 하세요:
#!/bin/sh 환경 >> /tmp/outfile
Zabbix 서버에서 다음 명령을 실행하여 스크립트를 실행합니다 /usr/local/bin/zabbix_raid_discovery
.
zabbix_get -s 클라이언트_호스트 이름 -k 'example.disk.discovery'
그런 다음 확인하면 /tmp/outfile
다음과 같습니다.
SHELL=/sbin/nologin 용어=리눅스 사용자=루트 SUDO_USER=자빅스 Sudo_UID=497 사용자 이름=루트 경로=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin 메일=/var/mail/root 비밀번호=/ LANG=en_US.UTF-8 SLVL=1 SUDO_COMMAND=/tmp/doit 홈페이지=/루트 디렉토리 로그 이름=루트 SUDO_GID=497 _=/빈/환경
그 SHELL
대사가 정말 거슬리네요. 파일은 루트가 소유하므로 루트가 생성한 것으로 알고 있지만 쉘은 호출하는 사용자( zabbix
)로부터 온 것입니다.
답변1
대답은 sudo
버그가 있다는 것입니다. 첫째, 해결책: 나는 이것을 내 안에 넣었습니다 /etc/sudoers.d/zabbix file
.
zabbix ALL=(루트) NOPASSWD: /bin/env SHELL=/bin/sh /usr/local/bin/zabbix_raid_discovery
이제 zabbix_raid_discovery
작업 내에서 하위 명령을 호출하십시오.
이 문제를 해결하기 위한 패치는 sudo 1.8.15에서 출시될 예정입니다. 관리자 Todd Miller의 말:
그것은 단지 "항상 이런 식이었습니다." 아니요 이것은 참으로 타당한 이유입니다. 다음과 같은 차이로 인해 동작이 이루어져야 합니다. 문서와 일치합니다. - 토드 diff -r adb927ad5e86 플러그인/sudoers/env.c --- a/plugins/sudoers/env.c 2015년 10월 6일 화요일 -0600 +++ b/plugins/sudoers/env.c 2015년 10월 6일 화요일 10:04:03 -0600 @@ -939,8 +939,6 @@ CHECK_SETENV2("사용자 이름", runas_pw->pw_name, ISSET(didvar, DID_USERNAME), true); } 다른 { - if (!ISSET(didvar, DID_SHELL)) - CHECK_SETENV2("SHELL", sudo_user.pw->pw_shell, false, true); /* def_set_logname의 경우 나중에 LOGNAME을 설정합니다. */ if (!def_set_logname) { if (!ISSET(didvar, DID_LOGNAME)) @@ -984,6 +982,8 @@ if (!env_should_delete(*ep)) { if (strncmp(*ep, "SUDO_PS1=", 9) == 0) ps1 = *ep + 5; + else if (strncmp(*ep, "SHELL=", 6) == 0) + SET(didvar, DID_SHELL); 그렇지 않은 경우 (strncmp(*ep, "PATH=", 5) == 0) SET(didvar, DID_PATH); 그렇지 않은 경우 (strncmp(*ep, "TERM=", 5) == 0) @@ -1039,7 +1039,9 @@ if (홈페이지 재설정) CHECK_SETENV2("홈", runas_pw->pw_dir, true, true); - /* $TERM 및 $PATH가 설정되지 않은 경우 기본값을 제공합니다. */ + /* 설정되지 않은 경우 $SHELL, $TERM 및 $PATH에 대한 기본값을 제공합니다. */ + if (!ISSET(didvar, DID_SHELL)) + CHECK_SETENV2("SHELL", runas_pw->pw_shell, false, false); if (!ISSET(didvar, DID_TERM)) CHECK_PUTENV("TERM=알 수 없음", false, false); if (!ISSET(didvar, DID_PATH))
답변2
문제는 내가 문제라고 생각한 것이었지만 문제는 SHELL 변수에 발생한 것이 아니라 sudo가 실제로 무엇을 했는지에 있는 것으로 나타났습니다. 예를 들어:
-bash-4.1$ whoami 테스트 친구 -bash-4.1$ grep testdude /etc/passwd testdude:x:1001:10:테스트 친구:/tmp:/bin/bash -bash-4.1$ sudo 환경 [sudo] testdude의 비밀번호: ... 쉘=/bin/bash ...
여태까지는 그런대로 잘됐다. ...하지만 문제는 문서와 달리 sudo가 호출 수신자가 아닌 호출자의 셸을 사용한다는 것입니다. 실제로 /etc/passwd를 편집하여 셸을 변경하면 sudo가 대신 호출자의 셸을 따르는 것을 볼 수 있습니다 SHELL
.
-bash-4.1$ grep root /etc/passwd 루트:x:0:0:루트:/루트:/bin/bash -bash-4.1$ sudo sed -i -e '/testdude/s/bash/sh/' /etc/passwd -bash-4.1$ grep testdude /etc/passwd testdude:x:1001:10:테스트 친구:/tmp:/bin/sh -bash-4.1$ sudo 환경 ... 쉘=/bin/sh ... -bash-4.1$ 내보내기 SHELL=/완전/의미 없음/경로 -bash-4.1$ sudo 환경 ... 쉘=/bin/sh ...
sudo -i
초기 로그인을 시뮬레이션하고 싶지 않기 때문에 사용할 수 없습니다 . sudo -s
sudoers 파일에 올바른 명령이 있으면 작동합니다. 그러나 예상되는 동작(맨 페이지: " The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables
"에 반영된 대로)은 쉘이 호출 수신자의 것입니다. sudo env의 PATH
, HOME
, LOGNAME
변수 를 보면 USER
root의 내용을 볼 수 있습니다. SHELL
또한 루트 쉘이어야 합니다.