비밀번호 없이 sudo를 실행할 수 있다면 sudo를 실행하는 데 왜 tty가 필요합니까?

비밀번호 없이 sudo를 실행할 수 있다면 sudo를 실행하는 데 왜 tty가 필요합니까?

sudo비밀번호 없이 실행되도록 구성했지만 이 작업을 시도하면 ssh 'sudo Foo'여전히 오류 메시지가 나타납니다 sudo: sorry, you must have a tty to run sudo.

왜 이런 일이 발생합니까? 어떻게 해결할 수 있나요?

답변1

/etc/sudoers파일(또는 포함된 파일)에 다음이 포함되어 있기 때문일 수 있습니다 .

Defaults requiretty

... sudoTTY가 필요합니다. 우리 모두 알고 있듯이 Red Hat 시스템(RHEL, Fedora...) sudoers에는 기본 파일에 TTY가 필요합니다. 이는 실질적인 보안 이점을 제공하지 않으며 안전하게 제거할 수 있습니다.

Red Hat은 이 문제를 인정했습니다.그리고 향후 버전에서는 제거될 예정입니다.

서버 구성을 변경할 수 없는 경우 이 잘못된 구성에 대한 해결 방법으로 -t또는 -tt옵션을 사용하여 ssh원격 측에서 의사 터미널을 생성할 수 있지만 여러 가지 부작용이 있다는 점에 유의하세요.

-tt대화형으로 사용하기 위한 것입니다. raw원격 터미널과 상호 작용할 수 있도록 로컬 터미널을 모드로 설정합니다 . 이는 sshI/O가 터미널에서 들어오거나 터미널로 가지 않으면 부작용이 발생한다는 것을 의미합니다 . 예를 들어, 모든 입력은 에코되고, 특수 종결자( ^?, ^C, ^U)는 출력 시 특수 처리를 유발하고 s는 s LF로 변환됩니다 .CRLF이 답변이 바이너리가 변경된 이유는 무엇입니까?자세한 내용은.

영향을 최소화하려면 다음과 같이 호출할 수 있습니다.

ssh -tt host 'stty raw -echo; sudo ...' < <(cat)

이렇게 하면 < <(cat)로컬 터미널이 모드로 설정되는 것을 방지할 수 있습니다(있는 경우) raw. 이것이 발생할 때까지 입력용 콘텐츠를 사용하여 stty raw -echo원격 터미널의 회선 규칙을 설정 합니다 -tt.

원격 명령의 출력은 터미널로 전송되므로 버퍼링(많은 응용 프로그램에서 회선 기반)과 대역폭 효율성이 TCP_NODELAY켜져 있기 때문에 여전히 영향을 미칩니다. 또한 IPQoS를 에 상대적으로 설정 -tt하십시오 . 다음을 통해 두 문제를 모두 해결할 수 있습니다.sshlowdelaythroughput

ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)

또한 이는 원격 명령이 stdin에서 파일 끝을 감지할 수 없으며 원격 명령의 stdout 및 stderr이 단일 스트림으로 병합된다는 것을 의미합니다.

따라서 이는 결국 별로 좋은 해결책이 아닙니다.

원격 호스트에서 의사 터미널을 생성할 수 있는 방법이 있는 경우(예: expect, zsh, socat, perl... 사용 IO::Pty) 이를 사용하여 연결할 의사 터미널을 생성하는 것이 더 좋습니다 sudo(I/O용은 아님). ssh사용하지 마십시오 -t.

예를 들어 다음을 사용합니다 expect.

ssh host 'expect -c "spawn -noecho sh -c {
     exec sudo cmd >&4 2>&5 <&6 4>&- 5>&- 6<&-}
 exit [lindex [wait] 3]" 4>&1 5>&2 6<&0'

또는 다음을 사용하십시오 script(구현이 에서 왔다고 가정함 util-linux).

ssh host 'SHELL=/bin/sh script -qec "
              sudo cmd <&3 >&4 2>&5 3<&- 4>&- 5>&-
            " /dev/null 3<&0 4>&1 5>&2'

(둘 다 원격 사용자의 로그인 쉘이 Bourne과 유사하다고 가정).

답변2

기본적으로 SUDO는 TTY를 요구하도록 구성됩니다. 즉, SUDO는 로그인 셸에서 실행되어야 합니다. -tSSH 호출에 스위치를 추가하면 이 요구 사항을 충족 할 수 있습니다 .

ssh -t someserver sudo somecommand

의사 터미널 강제 -t할당.

이 작업을 전역적으로 수행하려면 수정 /etc/sudoers하여 지정하십시오 !requiretty. 이는 사용자별, 그룹별 또는 모든 수준에서 수행할 수 있습니다.

답변3

tty 할당을 강제하려면 -t플래그를 사용하십시오 .ssh

$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$

답변4

흥미로운 대안은 FreeIPA 또는 IdM을 실행하여 사용자 및 sudoer 규칙을 중앙에서 관리하는 것입니다. 그런 다음 sudo 규칙을 만들고 옵션을 할당할 수 있습니다.

!필요하다

규칙에서. 그러면 명령이 예상대로 실행됩니다. 또한 단일 구성 세트에서 모든 서버와 사용자를 관리하는 이점도 있습니다.

관련 정보