How to pass the password to su/sudo/ssh without overriding the TTY?
Asked Answered
S

22

160

I'm writing a C Shell program that will be doing su or sudo or ssh. They all want their passwords in console input (the TTY) rather than stdin or the command line.

Does anybody know a solution?

Setting up password-less sudo is not an option.

could be an option, but it's not present on my stripped-down system.

Stallings answered 24/10, 2008 at 11:59 Comment(2)
SSH: serverfault.com/questions/241588/…Surrey
krazyworks.com/automating-ssh-and-sudo-with-expectBump
W
235

For sudo there is a -S option for accepting the password from standard input. Here is the man entry:

    -S          The -S (stdin) option causes sudo to read the password from
                the standard input instead of the terminal device.

This will allow you to run a command like:

echo myPassword | sudo -S ls /tmp

As for ssh, I have made many attempts to automate/script it's usage with no success. There doesn't seem to be any build-in way to pass the password into the command without prompting. As others have mentioned, the "expect" utility seems like it is aimed at addressing this dilemma but ultimately, setting up the correct private-key authorization is the correct way to go when attempting to automate this.

Waksman answered 1/12, 2010 at 17:27 Comment(7)
Luckily, Ruby has a built-in SSH client which allows you to specify the password. You could try ruby -e "require 'net/ssh' ; Net::SSH.start('example.com', 'test_user', :password => 'secret') do |ssh| puts 'Logged in successfully' ; while cmd=gets ; puts ssh.exec!(cmd) ; end end"Milena
I hate to be a party pooper here, but doing this can make your password show up in a process list. I was trying to determine a better way and came across this article and was surprised no one had pointed it out. Great solution, but beware of the risks.Ferity
About ssh, have you tried passing password in connection string? like nonroot:[email protected]? Of course things are much easier if you use key auth and key manager.Spectacled
Avoid password showing up in process list or log files by putting it in a file and using cat; 'cat pw | sudo -S <command>, and later rm pw.Sahara
Another way would be to use netcat and deliver the password over a socket - nc -l 12345 | sudo -S <command>. On the sending side; echo myPassord | nc <target> 12345. This just moves the password handling problem, but presumably to a master console where you have more options.Sahara
This solution is working for Linux only, any suggestion to use same with Unix.Tiliaceous
ssh -t -t [email protected] << EOF echo SOMEPASSWORD | sudo -S do something sudo do something else exit EOFEthylethylate
K
38

I wrote some Applescript which prompts for a password via a dialog box and then builds a custom bash command, like this:

echo <password> | sudo -S <command>

I'm not sure if this helps.

It'd be nice if sudo accepted a pre-encrypted password, so I could encrypt it within my script and not worry about echoing clear text passwords around. However this works for me and my situation.

Kieger answered 9/12, 2008 at 6:4 Comment(1)
Pseudo-terminal will not be allocates because stdin is not a terminalGumdrop
S
35

For ssh you can use sshpass: sshpass -p yourpassphrase ssh user@host.

You just need to download sshpass first :)

$ apt-get install sshpass
$ sshpass -p 'password' ssh username@server
Stefanstefanac answered 13/1, 2012 at 12:27 Comment(0)
D
17

For sudo you can do this too:

sudo -S <<< "password" command
Deliberation answered 9/6, 2015 at 14:12 Comment(0)
M
13

Maybe you can use an expect command?:

expect -c 'spawn ssh [email protected];expect password;send "your-password\n";interact

That command gives the password automatically.

Mariken answered 8/5, 2012 at 4:21 Comment(3)
Looks nice, but how can I enable the expect command on a maschine without root permissions ?Coverup
@Coverup An executable may be added to ~/bin if you don't have permissions to install it. If your system does not automatically add ~/bin to your PATH, you may do so manually with export PATH="$PATH:~/bin" or add that command to your profile to do it automatically. If you don't want to change your PATH, you may instead execute the command using its absolute path: ~/bin/expect [arguments] Be sure to remember to set its executable bit: chmod +x ~/bin/expectDressmaker
Very helpful. It can be combined with retrieving password from safe source (rather than typing it literally) using this answer. The final result in my case was MY_PASSWORD=$(some_pipeline_retrieving_password) && expect -c "spawn su - my_user;expect \"Password:\";send \"$MY_PASSWORD\n\";interact" (note the combination of single quotes of expect -c command and double quotes inside didn't work for me).Plexus
A
12

I've got:

ssh user@host bash -c "echo mypass | sudo -S mycommand"

Works for me.

Alcahest answered 7/1, 2011 at 16:36 Comment(2)
Didn't work for me. still ssh prompts for the password.Erzurum
Excellent, finally something I can use! Thanks. I use this within a bash script that starts an ssh session and passes sudo commands to the client. My script has lines the resolve to: ssh -t username@hostname bash -c "sudo echo fartjuice"Swen
K
11

The usual solution to this problem is setuiding a helper app that performs the task requiring superuser access: http://en.wikipedia.org/wiki/Setuid

Sudo is not meant to be used offline.

Later edit: SSH can be used with private-public key authentication. If the private key does not have a passphrase, ssh can be used without prompting for a password.

Kyungkyushu answered 24/10, 2008 at 12:7 Comment(0)
A
10

This can be done by setting up public/private keys on the target hosts you will be connecting to. The first step would be to generate an ssh key for the user running the script on the local host, by executing:

ssh-keygen
Enter file in which to save the key (/home/myuser/.ssh/id_rsa): <Hit enter for default>
Overwrite (y/n)? y

Then enter a blank password. After that, copy your ssh key onto the target host which you will be connecting to.

ssh-copy-id <remote_user>@<other_host>
remote_user@other_host's password: <Enter remote user's password here>

After registering the ssh keys, you would be able to perform a silent ssh remote_user@other_host from you local host.

Aldershot answered 30/7, 2012 at 12:54 Comment(0)
W
8

Take a look at expect linux utility.

It allows you to send output to stdio based on simple pattern matching on stdin.

Went answered 24/10, 2008 at 12:1 Comment(0)
M
8

When there's no better choice (as suggested by others), then man socat can help:

   (sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |
   socat - EXEC:'ssh -l user server',pty,setsid,ctty

          EXEC’utes an ssh session to server. Uses a pty for communication
          between socat and ssh, makes it ssh’s  controlling  tty  (ctty),
          and makes this pty the owner of a new process group (setsid), so
          ssh accepts the password from socat.

All of the pty,setsid,ctty complexity is necessary and, while you might not need to sleep as long, you will need to sleep. The echo=0 option is worth a look too, as is passing the remote command on ssh's command line.

Maestas answered 15/9, 2011 at 21:30 Comment(2)
This will actually work for su as well. su does not have a -S (stdin) option.Ihs
Is it possible to avoid sleeping and use something more reliable instead?Wilen
H
3
echo <password> | su -c <command> <user> 

This is working.

Halfandhalf answered 18/10, 2010 at 14:2 Comment(7)
This is the only one works for me in Fedora. People downvote answers just because they don't work in their situation?Whimper
"su: must be run from a terminal" (RPi1B, Raspbian)Anthracosilicosis
Unfortunately this doesn't in recent versions of su, which reads password from stdio instead.Boucher
More than 12 years later, unfortunately, that trick doesn't work any more, at least on the Suse I'm using now.Cajeput
I have tested this on Ubuntu 20.04 and Arch Linux (so, very latest software) and OpenSuse Leap just now in Docker and it worked great on all. @Cajeput could you please clarify what you mean by "doesn't work"? And which version are you using? Can you post your su --version if it really doesn't work?Anasarca
At the moment, I don't have access to the machine where I had this problem, so I can't tell you which su version is used, unfortunately. However, the distro is a Suse SLES 12; maybe there is some kind of hardening to avoid this behaviour (Suse is kind of weird...)? Nonetheless, using expect worked like a charm.Cajeput
Tried today on a SparkyLinux using SSH.Net library in Windows app console C# Net.Core and worked perfect: I can reboot, poweroff, shutdown.Pipestone
E
2
ssh -t -t [email protected] << EOF
echo SOMEPASSWORD | sudo -S do something
sudo do something else
exit
EOF
Ethylethylate answered 17/2, 2017 at 14:8 Comment(1)
If you can login as user with ssh key, for sudo access is fine: ssh -t user@host "echo mypassword | sudo -S sudocommand"Thalamus
C
1

Set SSH up for Public Key Authentication, with no pasphrase on the Key. Loads of guides on the net. You won't need a password to login then. You can then limit connections for a key based on client hostname. Provides reasonable security and is great for automated logins.

Clincher answered 27/10, 2008 at 15:56 Comment(0)
L
1

a better sshpass alternative is: passh https://github.com/clarkwang/passh

Login to a remote server

 $ passh -p password ssh user@host

Run a command on remote server

 $ passh -p password ssh user@host date

other methods to pass the password

-p The password (Default: `password')

-p env: Read password from env var

-p file: Read password from file

here I explained why it is better than sshpass, and other solutions.

Lengel answered 11/1, 2020 at 23:38 Comment(0)
H
1

You can also pass various parameters as follows:

echo password | echo y | sudo -S pacman -Syu

(Although that's a bad idea, it's just an example)

Hengel answered 11/8, 2021 at 21:17 Comment(0)
K
0

I had the same problem. dialog script to create directory on remote pc. dialog with ssh is easy. I use sshpass (previously installed).

   dialog --inputbox "Enter IP" 8 78 2> /tmp/ip

   IP=$(cat /tmp/ip)


   dialog --inputbox "Please enter username" 8 78 2> /tmp/user

   US=$(cat /tmp/user)


   dialog --passwordbox "enter password for \"$US\" 8 78 2> /tmp/pass

   PASSWORD = $(cat /tmp/pass)


   sshpass -p "$PASSWORD" ssh $US@$IP mkdir -p /home/$US/TARGET-FOLDER


   rm /tmp/ip

   rm /tmp/user

   rm /tmp/pass

greetings from germany

titus

Khedive answered 23/3, 2013 at 11:23 Comment(0)
C
0

Building on @Jahid's answer, this worked for me on macOS 10.13:

ssh <remote_username>@<remote_server> sudo -S <<< <remote_password> cat /etc/sudoers
Camera answered 3/11, 2017 at 23:13 Comment(0)
C
0

I once had a use case where I needed to run Sudo and ssh in the same command without stdin specifying all the variables needed.

This is the command I used

echo sudopassword | sudo -S -u username sshpass -p  extsshpassword ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no  username@ipaddress " CMD on external machine"

Breaking that command into pieces!

This will allow you to run commands through your machine using Superuser:

echo password | sudo -S -u username

This will allow you to pass ssh password and execute commands on external machines:

sshpass -p  sshpassword  ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no  username@ipaddress " CMD on external machine"

make sure you install the sudo and openssh packages on your machine.

Colostrum answered 18/12, 2021 at 23:24 Comment(0)
B
-1

One way would be to use read -s option .. this way the password characters are not echoed back to the screen. I wrote a small script for some use cases and you can see it in my blog: http://www.datauniv.com/blogs/2013/02/21/a-quick-little-expect-script/

Baudoin answered 22/2, 2013 at 1:29 Comment(0)
B
-1

USE:

echo password | sudo command

Example:

echo password | sudo apt-get update; whoami

Hope It Helps..

Bottrop answered 23/3, 2017 at 8:0 Comment(0)
W
-3

You can provide password as parameter to expect script.

Went answered 24/10, 2008 at 12:7 Comment(0)
Z
-12
su -c "Command" < "Password"

Hope it is helpful.

Zincography answered 22/10, 2009 at 14:4 Comment(1)
Its not. "su: must be run from a terminal" is the answer to this.Daggna

© 2022 - 2024 — McMap. All rights reserved.