Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have configured sudo to run without a password, but when I try to ssh 'sudo Foo", I still get sudo: sorry, you must have a tty to run sudo.

Why does this happen and how can I work around it?

share|improve this question

3 Answers 3

up vote 25 down vote accepted

That's because there must be a

Defaults requiretty

in /etc/sudoers or any file it includes.

RedHat systems (RHEL, fedora...) have been known to have that in their default sudoers file. That provides no real security benefit and can be safely removed.

RedHat has acknowledged the problem and it will be removed in future releases.

If changing the configuration of the server is not an option, as a work-around for that mis-configuration, you could use the -t or -tt options to ssh which spawns a pseudo-terminal on the remote side, but beware that it has a number of side effects.

-tt is meant for interactive use. It puts the local terminal in raw mode so that you interact with the remote terminal. That means that if ssh I/O is not from/to a terminal, that will have side effects. For instance, all the input will be echoed back, special terminal characters (^?, ^C, ^U) will cause special processing; on output, LFs will be converted to CRLFs... (see this answer to Why is this binary file being changed? for more details.

To minimise the impact, you could invoke it as:

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

The < <(cat) will avoid the setting of the local terminal (if any) in raw mode. And we're using stty raw -echo to set the line discipline of the remote terminal as pass through (effectively so it behaves like the pipe that would be used instead of a pseudo-terminal without -tt, though that only applies after that command is run, so you need to delay sending something for input until that happens).

Note that since the output of the remote command will go to a terminal, that will still affect its buffering (which will be line-based for many applications) and bandwidth efficiency since TCP_NODELAY is on. Also with -tt, ssh sets the IPQoS to lowdelay as opposed to throughput. You could work around both with:

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

Also, note that it means the remote command cannot detect end-of-file on its stdin and the stdout and stderr of the remote command are merged into a single stream.

So, not so good a work around after all.

If you've a got a way to spawn a pseudo-terminal on the remote host (like with expect, zsh, socat, perl's IO::Pty...), then it would be better to use that to create the pseudo-terminal to attach sudo to (but not for I/O), and use ssh without -t.

For example, with 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'

(here assuming the login shell of the remote user is Bourne-like).

share|improve this answer
    
This is much less helpful than the answers below that indicate how to invoke ssh properly. –  cbmanica Sep 6 at 21:31
    
@cbmanica. No. -t should only be used for interactive use. –  Stéphane Chazelas Sep 7 at 14:22
    
Be that as it may, I'd rather solve the problem now rather than wait for a mythical future RedHat release or reconfigure 25 machines to not be dumb. –  cbmanica Sep 7 at 20:57
    
@cbmanica, see my edit for details. –  Stéphane Chazelas Sep 8 at 7:01
    
Thanks, upvoted. –  cbmanica Sep 8 at 14:17

By default, SUDO is configured to require a TTY. That is, SUDO is expected to be run from a login shell. You can defeat this requirement by adding the -t switch to your the SSH as:

ssh -t someserver sudo somecommand

The -t forces allocation of a pseudo-tty.

If you want to perform this globally, modify /etc/sudoders to specify !requiretty. This can be done a a per user, per group or all-encompassing level.

share|improve this answer
    
No, that's not the default. It's only the redhat distribution of sudo that had requiretty in its default sudoers. It will be fixed in newer releases –  Stéphane Chazelas Apr 1 at 20:28
    
@StephaneChazelas +1 for enlightening me that it's largely indigenous to Red Hat and its siblings and another ++ if I could for the current bug report! –  JRFerguson Apr 1 at 20:38

Use the -t flag to ssh to force tty allocation.

$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.