Ho configurato sudo per eseguire senza una password, ma quando provo a ssh 'sudo Foo' , ricevo ancora il messaggio di errore sudo: sorry, you must have a tty to run sudo .
Perché succede e come posso aggirarlo?
Risposta accettata:
Probabilmente è perché il tuo /etc/sudoers file (o qualsiasi file che include) ha:
Defaults requiretty
...che rende sudo richiedono un TTY. È noto che i sistemi Red Hat (RHEL, Fedora...) richiedono un TTY nei sudoers predefiniti file. Ciò non fornisce alcun reale vantaggio in termini di sicurezza e può essere rimosso in sicurezza.
Red Hat ha riconosciuto il problema e verrà rimosso nelle versioni future.
Se la modifica della configurazione del server non è un'opzione, come soluzione per quella configurazione errata, potresti usare il -t o -tt opzioni per ssh che genera uno pseudo-terminale sul lato remoto, ma attenzione che ha una serie di effetti collaterali.
-tt è pensato per un uso interattivo. Mette il terminale locale in raw modalità in modo da interagire con il terminale remoto. Ciò significa che se ssh L'I/O non è da/verso un terminale, che avrà effetti collaterali. Ad esempio, tutto l'input verrà ripreso, caratteri speciali del terminale (^? , ^C , ^U ) comporterà un trattamento speciale; in uscita, LF I messaggi verranno convertiti in CRLF s... (vedi questa risposta a Perché questo file binario viene modificato? per maggiori dettagli.
Per ridurre al minimo l'impatto, puoi invocarlo come:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
Il < <(cat) eviterà l'impostazione del terminale locale (se presente) in raw modalità. E stiamo usando stty raw -echo per impostare la disciplina di linea del terminale remoto come pass-through (di fatto si comporta come la pipe che verrebbe utilizzata al posto di uno pseudo-terminale senza -tt , sebbene ciò si applichi solo dopo l'esecuzione del comando, quindi è necessario ritardare l'invio di qualcosa per l'input fino a quando ciò non accade).
Nota che poiché l'output del comando remoto andrà a un terminale, ciò influenzerà comunque il suo buffering (che sarà basato sulla linea per molte applicazioni) e l'efficienza della larghezza di banda poiché TCP_NODELAY è acceso. Anche con -tt , ssh imposta l'IPQoS su lowdelay al contrario di throughput . Potresti aggirare entrambi con:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
Inoltre, nota che significa che il comando remoto non può rilevare la fine del file sul suo stdin e lo stdout e lo stderr del comando remoto sono uniti in un unico flusso.
Correlati:Debian – Rimuovere utente e password all'accesso in Debian 9 Stretch?Quindi, dopotutto, non è una buona soluzione.
Se hai un modo per generare uno pseudo-terminale sull'host remoto (come con expect , zsh , socat , perl 's IO::Pty …), allora sarebbe meglio usarlo per creare lo pseudo-terminale per allegare sudo a (ma non per I/O) e usa ssh senza -t .
Ad esempio, con 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'
Oppure con script (qui assumendo l'implementazione da 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'
(supponendo (per entrambi) che la shell di accesso dell'utente remoto sia simile a Bourne).