Skonfigurowałem sudo
działanie bez hasła, ale gdy próbuję ssh 'sudo Foo'
, nadal pojawia się komunikat o błędzie sudo: sorry, you must have a tty to run sudo
.
Dlaczego tak się dzieje i jak mogę to obejść?
Skonfigurowałem sudo
działanie bez hasła, ale gdy próbuję ssh 'sudo Foo'
, nadal pojawia się komunikat o błędzie sudo: sorry, you must have a tty to run sudo
.
Dlaczego tak się dzieje i jak mogę to obejść?
Odpowiedzi:
Prawdopodobnie dlatego, że Twój /etc/sudoers
plik (lub dowolny plik, który zawiera) ma:
Defaults requiretty
... co sudo
wymaga TTY. Systemy Red Hat (RHEL, Fedora ...) wymagają TTY w domyślnym sudoers
pliku. Nie zapewnia to rzeczywistych korzyści bezpieczeństwa i można je bezpiecznie usunąć.
Red Hat uznał problem i zostanie on usunięty w przyszłych wydaniach.
Jeśli zmiana konfiguracji serwera nie jest opcją, w celu obejścia tej błędnej konfiguracji można użyć opcji -t
lub, -tt
w ssh
których spawnuje się pseudo-terminal po stronie zdalnej, ale należy pamiętać, że ma on wiele stron efekty.
-tt
jest przeznaczony do użytku interaktywnego. Przełącza lokalny terminal w raw
tryb umożliwiający interakcję ze zdalnym terminalem. Oznacza to, że jeśli ssh
I / O nie jest od / do terminala, będzie to miało skutki uboczne. Na przykład, wszystkie wejścia zostanie echo specjalne postacie końcowe ( ^?
, ^C
, ^U
) spowoduje specjalnego przetwarzania; na wyjściu, LF
będzie s być konwertowane do CRLF
s ... (zobacz tę odpowiedź Dlaczego jest to plik binarny zmieniane? więcej szczegółów.
Aby zminimalizować wpływ, możesz wywołać go jako:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
< <(cat)
Uniknie ustawienie lokalnego terminala (jeśli w ogóle) w raw
trybie. Używamy, stty raw -echo
aby ustawić dyscyplinę liniową zdalnego terminala jako przechodzącą (skutecznie, więc zachowuje się jak potok, który byłby używany zamiast pseudo-terminalu bez -tt
, chociaż ma to zastosowanie tylko po uruchomieniu tego polecenia, więc potrzebujesz opóźnić przesłanie czegoś do wprowadzenia, dopóki tak się nie stanie).
Zauważ, że ponieważ dane wyjściowe polecenia zdalnego trafią do terminala, nadal będzie to miało wpływ na jego buforowanie (które będzie oparte na linii dla wielu aplikacji) i wydajność przepustowości, ponieważ TCP_NODELAY
jest włączony. Również -tt
, ssh
ustawia IPQoS to lowdelay
w przeciwieństwie do throughput
. Możesz obejść oba z:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
Zauważ też, że oznacza to, że zdalne polecenie nie może wykryć końca pliku na swoim standardowym wejściu, a standardowe wyjście i standardowe polecenie zdalne są scalone w jeden strumień.
W końcu nie jest to tak dobre rozwiązanie.
Jeśli ve got sposób na tarło pseudo-terminal na zdalnym hostem (jak z expect
, zsh
, socat
, perl
„s IO::Pty
...), to byłoby lepiej używać, aby utworzyć pseudo-terminal, aby dołączyć sudo
do (ale nie dla I / O) i używaj ssh
bez -t
.
Na przykład z 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'
Lub z script
(tutaj przy założeniu implementacji od 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'
(zakładając (dla obu), że powłoka logowania zdalnego użytkownika jest podobna do Bourne'a).
Domyślnie SUDO jest skonfigurowane tak, aby wymagać TTY. Oznacza to, że SUDO powinien być uruchamiany z powłoki logowania. Możesz pokonać ten wymóg, dodając -t
przełącznik do wywołania SSH:
ssh -t someserver sudo somecommand
-t
Podział siły pseudo-TTY.
Jeśli chcesz to zrobić globalnie, zmodyfikuj, /etc/sudoers
aby określić !requiretty
. Można to zrobić na poziomie użytkownika, grupy lub wszechstronnego poziomu.
Użyj -t
flagi, ssh
aby wymusić przydział tty.
$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$
-t
aby wymusić przydział, gdyPseudo-terminal will not be allocated because stdin is not a terminal.
Wystąpił ten problem przy użyciu Dockera i Centos 7. W końcu wykonałem następujące czynności:
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
Znalazłem ten hack na https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile
Ciekawą alternatywą jest uruchomienie FreeIPA lub IdM w celu centralnego zarządzania użytkownikami i regułami sudoer. Następnie możesz utworzyć reguły sudo i przypisać opcję
!
z reguły. Polecenie zostanie uruchomione zgodnie z oczekiwaniami. Będziesz także miał korzyści z zarządzania wszystkimi serwerami i użytkownikami z jednego zestawu konfiguracji.
Miałem ten sam problem. W moim przypadku rozwiązaniem były dwie linie
myscript=$(cat ssh_test.sh)
ssh -t user@host "$myscript"
Wyjaśnienie:
Umieść polecenia, które chcesz uruchomić (w tym polecenia sudo) w skrypcie, np. „Ssh_test.sh”.
Przeczytaj cały skrypt w zmiennej o nazwie „myscript”.
Wywołaj ssh tylko jednym -t i podaj zmienną zamiast polecenia.
Wcześniej napotkałem problemy, używając kombinacji czytania ze standardowego wejścia i używania heredoków
requiretty
w domyślnych sudoers. Zostanie to naprawione w nowszych wersjach