2

I'm trying to write a bash script that calls an expect script to establish a master SSH connection to be used for the remaining SSH commands in the bash script.

~/.ssh/config:

ControlMaster auto
ControlPath ~/.ssh/control-%r@%h:%p

upload.sh:

#!/usr/bin/bash

expect -f /home/Dave/bin/ssh.exp

scp /home/Dave/bin/test [email protected]:/root/test

ssh [email protected] "echo 'Test' >> /root/test"

ssh -O exit [email protected]

ssh.exp:

#!/usr/bin/expect -f

# Enable some diagnostic output
exp_internal 1

spawn /usr/bin/ssh -M -N [email protected]

expect {
    -re ".*yes.*no.*" {
        exp_send "yes\r"
        exp_continue
    }
    -re ".*password.*" {
        exp_send "OMGSECRET\r"
    }
}

$ bin/upload.sh
spawn /usr/bin/ssh -M -N [email protected]
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {5212}
Gate keeper glob pattern for '.*yes.*no.*' is ''. Not usable, disabling the performance booster.
Gate keeper glob pattern for '.*password.*' is '*password*'. Activating booster.

expect: does "" (spawn_id exp4) match regular expression ".*yes.*no.*"? (No Gate, RE only) gate=yes re=no
".*password.*"? Gate "*password*"? gate=no
[email protected]'s password:
expect: does "[email protected]'s password: " (spawn_id exp4) match regular expression ".*yes.*no.*"? (No Gate, RE only) gate=yes re=no
".*password.*"? Gate "*password*"? gate=yes re=yes
expect: set expect_out(0,string) "[email protected]'s password: "
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "[email protected]'s password: "
send: sending "OMGSECRET\r" to { exp4 }
mux_client_request_session: read from master failed: Connection reset by peer
[email protected]'s password:
[email protected]'s password:

The SSH connection is being established, but it craps out when I try to reuse it for the SCP command. Why?

Possible final sad edit: Alas it appears cygwin doesn't support multiplexing.

5
  • Are you sure that the password is correct and that the server accepts root login with a password? Does it work if you aren't using the expect script? Commented Jan 1, 2014 at 23:21
  • Where will the user be typing the password? Why not run the master ssh command in a terminal and make the user enter the password there? Commented Jan 1, 2014 at 23:22
  • Do not the password on the command line. It can be snooped by other users if they run ps at the right time. It's safe to pass the password in an environment variable ($::env(PASSWORD) in Tcl). Commented Jan 1, 2014 at 23:24
  • I'm sure the password is correct and I can log in from terminal with those credentials. The user enters the password in a web form (PHP), then the server passes the password to the bash script. Since the user doesn't see the terminal window, I can't have them enter the password there. Commented Jan 1, 2014 at 23:43
  • @Gilles I removed all mention of PHP from the question. For now, I just want to get this to work from the console. Commented Jan 9, 2014 at 6:32

2 Answers 2

4

Using an Expect script to send a hard-coded plaintext password is generally a Very Bad Idea. If you needs scriptable, passwordless SSH connections, it's far better to use key-pair authentication:

ssh-keygen # and then follow the prompts; don't set a passphrase
ssh-copy-id [email protected]

After doing so, you can ssh [email protected] without needing to key in your password.

You can still use the control connection muxing set up with the Control directives in ~/.ssh/config, and close the master connection with ssh -O exit [email protected].

You ought also to use ssh's utility of simply running commands remotely - once you have key-pair authentication set up, you can have:

ssh [email protected] /etc/init.d/dnsmasq restart

in your script and be all set to go.

7
  • Who said password was hard coded? It's prompted from the user (which is btw a requirement). Commented Jan 1, 2014 at 20:00
  • In the example bash script, it's metasyntactically set on the first line after the shebang: # Set $user, $addr, $pass, $source and $dest ...
    – DopeGhoti
    Commented Jan 1, 2014 at 20:01
  • It's an argument passed to the script though. Is that okay? Commented Jan 1, 2014 at 20:01
  • It's still exposing the password in plain text to anyone who manages to read your bash script. Private keys are never set group- or world-readable and allow many layers of additional security. For example, if your key is compromised, you can remove it from the remote host's authorized-keys file and generate a new keypair without having to worry about resetting your password.
    – DopeGhoti
    Commented Jan 1, 2014 at 20:04
  • Maybe I should clarify: this script is called from an app that prompts the user for a password. I don't understand at what point it becomes plain text, unless the expect -f upload.exp "$user" "$addr" "$pass" part is logged somewhere with the actual password? Commented Jan 1, 2014 at 20:06
0

if this is still your question:

"The SSH connection is being established, but it craps out when I try to reuse it for the SCP command. Why?"

This happens because you are starting a seperate shell with your expect script. Your ssh session is bound to this shell and if your script ends the shell also end and your ssh session dies.

Sorry but I don't have a solution in a nutshell for this problem.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .