1

I need to pipe data through SSH to a command that reads stdin. The command needs to run with sudo so I need to be able enter the sudo password, too. Without ssh, I'd use numbered file descriptors like so:

$ (sudo tee /tmp/test <&3; cat /tmp/test) 3<<< "test"
sudo: password for confus@confusion, running as root: ***********************
test
test

With SSH, this same approach doesn't seem to work:

$ ssh [email protected] -t "sudo tee /tmp/test <&3; cat /tmp/test" 3<<< "test"
Warning: Permanently added 'somehost.com' (ED25519) to the list of known hosts.
bash: line 1: 3: Bad file descriptor
Connection to 10.17.6.12 closed.

Is there some other way to make this work?

Edit: related question

4
  • 1
    Have you considered using expect? or python's pexpect library? or perl's Expect.pm or Net::SSH modules? or equivalents for other languages. Sometimes it's better to procedurally automate (e.g. wait for a specific prompt, then send the appropriate response) the interaction with another program or remote service than to just blindly shove a stream of characters at it. That's what all of these do. Commented Oct 5 at 10:36
  • 2
    another option, if you have root access to /etc/sudoers on the remote host, would be to write a script on the remote host that does the things you need to do as root and configure sudo to allow that script to be run by your user without a password. The script should do the bare minimum of what needs to be done as root, and should either ignore all command line arguments (e.g. hard-coded paths, filenames, values) or rigorously check or sanitise them. everything else that doesn't need root should be done as the user. Commented Oct 5 at 10:42
  • Expect is not really an option because the program doesn't prompt and I can't install it on the host, same goes for changing the sudoers config. Also I find both very inelegant. Commented Oct 5 at 10:54
  • 1
    I don't really understand the need for additional file descriptor in the local case, because sudo should ask for password via /dev/tty, so you can simply use stdin for data (e.g. echo test | sudo tee /tmp/test; cat /tmp/test). With ssh there is a general problem though, explained and solved here: ssh with separate stdin, stdout, stderr AND tty. Is this what you need? Commented Oct 5 at 12:51

2 Answers 2

1
ssh [email protected] -t "sudo tee /tmp/test <&3; cat /tmp/test" 3<<< "test"

There's a network connection between you and the remote host. How is the shell on somehost.com, which executes the string "sudo tee /tmp/test <&3; cat /tmp/test" supposed to have access to file descriptors on your local machine? It can't! They are a local operating system concept, not transportable through a SSH stream. The only thing that is: bytes.

So,

Is there some other way to make this work?

No. You'll have to find a different way to do this. If you want to use a file descriptor handle in bash on the remote host, you need to create it on the remote host, not locally.

But quite frankly, strong feeling of a X/Y problem here: You have a solution, but it's fairly strange and inelegant; you sadly don't actually tell us about the problem, to which a group of experts might come up with a much simpler solution.

For example: The commands you write would be really simple to put in a script, copy over the script (e.g. using scp using the exact same (identical, even) SSH connection), and then run it on the remote host. I however doubt that the commands you write are actually the one you care about (or else, you're already doing something rather complicated for a simple problem).

8
  • Of course it conceivably could forward file descriptors. It does so with stdin. SSH can also forward ports and sockets, There's nothing conceptually stopping other file descriptors to be forwarded. But that's another debate, my question of whether SSH can is answered with a "currently not". Commented Oct 5 at 20:58
  • 1
    no, it could not "conceivably" forward file descriptors. It doesn't forward the stdin file descriptor, it forwards the bytes sent to the stdin file descriptor of ssh. there's no way to transfer, again, the local operating system concept of file descriptors. That's what my answer explains! Commented Oct 5 at 21:05
  • I will probably just scp a file, which I'll have to access manage and then clean up, and which is slightly more code, but I'll live. Thanks so much for taking the time to answer. Commented Oct 5 at 21:05
  • Again, of course it could. Maybe forward is the slightly wrong word but the deamon could create them and then it could fill them with the correct bytes, because the client could distinguish what comes from which descriptor on the client site and forward that info to the server. As I said ssh has socket forwarding functionality. File descriptor forwarding in that sense would have not been an unreasonable or outrageous feature to expect. My advice would also be, to maybe clam down a bit, friend. Commented Oct 5 at 21:09
  • 1
    and that's the thing I've been saying in my answer and repeatedly here in the comments: nope. It does not exist, and it's not likely to exist, because the TCP and UNIX socket transports duplicate that functionality, but reflecting the actual capabilities of the transport more accurately. (you're really by no means passing an fd; you can't close it, ioctl on it, dup it, splice it, …: it's not a file descriptor that gets transported, but a stream of bytes, so if you want that, use a byte stream transport and extract the bytes at the other end :) ) Commented Oct 6 at 17:18
0

sudo has the ability to call another program to get the password. It's normally used for things like GUI front-ends, but we can abuse it.

This is unsafe and possibly against your company's security policy; you have been warned.

$ cat ~/bin/sudoit
SUDO_ASKPASS=/home/user/bin/print_my_password_to_stdout sudo -A "$@"

then /home/user/bin/print_my_password_to_stdout is masked at 0700 and literally does that - echos password to STDOUT. You'll never type that accidentally at the prompt.

sudoit ssh ... and your redirections should work.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.