How to non-interactively feed ssh with Time-based One-Time Password? - bash

Some supercomputers require time-based one-time password (OTP) to login via ssh. I want to avoid typing the password every time and automate login/scp/rsync via bash script, in which I generate the one-time password and then pass the one-time password to ssh by using sshpass:
sshpass -p my_password_and_OTP ssh user#hostname
This sshpass works for usual ssh, but my testing indicates it does not work for ssh requiring one-time password. I am wondering whether there is a way to non-interactively feed ssh with Time-based One-Time Password.

Here is my solution using expect+oathtool:
#!/usr/bin/expect -f
set otp [exec oathtool --totp -b my_secrete_key]
set timeout -1
spawn scp a.f90 usrname#cori.nersc.gov:~/
expect "Password + OTP:"
send -- "my_passwd${otp}\r"
expect eof
I use oathtool to generate the one-time-password and store the result in a variable otp.

Related

Running a script that's requires password in between

I'm running a script that copies files from another server.... It's prompting for a password of that server... Every time I need to enter the password manually... So s there any way to automate this?
scp root#ip:file_location destination
Note for security purposes I was not supposed to use password less login, or ssh
You can try to use sshpass which takes the password from an evironment variable named "SSHPASS" if switch -e is provided. So you can use something like:
export SSHPASS=<yourpw>
sshpass -e scp <sourcefile> user#ip:<targetpath/filename>
But of course it still uses ssh underneath, like Sergiy explained in the comment.

ssh in shell script, then execute commands after password

I'm trying to write a simple shell script to execute commands on my server box via ssh.
I'm not trying to pass a password within the shell script, I'm just wondering how I can get it to run commands on that box after the password is entered.
So far, when I execute my script, nothing happens after I enter the password. Or, it executes when I kill the ssh process.
I'm sure it's really easy, but I've been searching for hours and nothing has come up on the net, probably because nobody else needs to ask that.
Is there some way to do this natively within the shell? Thanks!
Look if you want to ssh without prompting password then you need a key authentication rather password authentication.
Else try;
sudo apt-get install sshpass
sshpass -p your_password ssh user#hostname
And to execute command at remote;
ssh user#host 'command'

Using expect to migrate multiple repositories

I have multiple repositories , which I want to convert to git from svn.
I try to write a simple expect script that convert one repo.
#!/usr/bin/expect
spawn svn2git svn://svn-server/repo --username $username --verbose
expect {Password for '$username'}
send "$password\r"
He puts password but then exit by timeout.
Git launches SSH internally to connect to a remote repository, and SSH detects when it is launched from another program, and disallows to enter passwords from scripts as a security feature.
You will need a specialized program like sshpass to enter passwords into SSH from scripts, or set up SSH keys.
I presume svn2git takes more than a few seconds to complete. Add this after your send command
set timeout -1
expect eof

Bash Script to SSH into a machine without prompting password and without using keys

I realize this question has been asked a few times but I could not find a relevant answer anywhere in my searching.
I am working in a development environment where security is not an issue and anyone could just guess the password if the thought for a few seconds.
What I am trying to do is simple. I have created an alias function in my local .bashrc file and I would like this function to automatically log into a machine with a default password.
My current implementation looks something like this:
function s () {
ssh root#192.168.1.$1
}
When I run it I get something like this:
~]s 122
ssh root#192.168.1.122
root#192.168.1.122's password:
Using Bash, and not using RSA keys I would like to get this to use the default password 'password'.
I've tried the following where IP and User have already been set.
Do=$(expect -c "
spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}
expect \"yes/no\"
send \"yes\r\"
expect \"assword\" send \"password\"")
echo $Do
$Do
It gives the follwing error:
Connecting and logging into server using expect
usage: send [args] string
while executing
"send"
invoked from within
"expect "assword" send "password""
Administrator#192.168.1.176's password:
bash: spawn: command not found...
Using the following command I am able to connect a machine. If I remove the interact it just runs the uptime command and closes the connection. With the interact command I am unable to see what I am typing or actually interact with the machine. Any ideas?
Do=$(expect -c "spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}; set timeout 4; expect \"assword\"; send \"password\n\"; expect \"test\"; send \"uptime\n\"; interact;");echo $Do;
You can do this with the expect tool: http://expect.sourceforge.net/
It's widely available, so depending on your system, the equivalent of sudo apt-get install expect or yum install expect will install it.
Here's an example of an expect script with ssh. This logs you in and gives you control of the interactive prompt:
#!/usr/bin/expect
set login "root"
set addr "127.0.0.1"
set pw "password"
spawn ssh $login#$addr
expect "$login#$addr\'s password:"
send "$pw\r"
expect "#"
send "cd /developer\r"
interact
Here's an example of how to use expect as part of a bash script. This logs in with ssh, cd to /var, runs a script, then exits the ssh session.
#!/bin/bash
...
login_via_ssh_and_do_stuff() {
# build the expect script in bash
expect_sh=$(expect -c "
spawn ssh root#127.0.0.1
expect \"password:\"
send \"password\r\"
expect \"#\"
send \"cd /var\r\"
expect \"#\"
send \"chmod +x my_script.sh\r\"
expect \"#\"
send \"./my_script.sh\r\"
expect \"#\"
send \"exit\r\"
")
# run the expect script
echo "$expect_sh"
}
You can leave these snippets in a script on your local system, and then just alias to the scripts.
Also: I know you said security isn't an issue, but I'd like to just note, again, that the "proper" way to ssh without using a password is to use a ssh key-pair =)
Use sshpass which is available in package repositories on major Linux-es.
For example, when password is in password.txt file:
sshpass -fpassword.txt ssh username#hostname
sshpass runs ssh in a dedicated tty, fooling it into thinking it is
getting the password from an interactive user.

Is it possible to automate ssh login WITH passwd (not passphraseless ssh)

Regardless of security issues, I want to automate ssh login by putting password into a script file (in form of plaintext). For example, I tried following, but without success...
echo "mypassword" | ssh -X root#remote_node_address
it still prompt with password inputs...
Edit: I am aware of setting up passphraseless ssh (and actually have done this). What my question really is is how to automate process of setting up passphraseless ssh...
Automate with Expect
You can use Expect to drive password authentication with SSH. For example:
#!/usr/bin/expect -f
set timeout -1
spawn ssh -o PubkeyAuthentication=no host.example.com
expect -exact "Password: "
send -- "secret\r"
expect {\$\s*} { interact }
This script is a very basic example, and not especially robust in the face of failure or when running under a non-standard remote TERM like GNU screen, but it works for the common case. You can also use /usr/bin/autoexpect from the expect-dev package to generate your own custom scripts based on a manual session.
you will need to use public key authentication, see
http://www.ece.uci.edu/~chou/ssh-key.html
in order to add new keys for existing hosts, you will need to automate updating of public keys in ~/.ssh/authorized_keys on remote machine
it is easy to do with
ssh-keygen -t rsa -b 1024 -f ~/.ssh/new-key -P ""
cat ~/.ssh/new-key.pub | ssh root#target-host 'cat >> ~/.ssh/authorized_keys'
then you can use new key to access host with
ssh -i ~/.ssh/new-key root#remote-host
I run into empty recently. I am surprised that it seems not to be well known since it is rarely talked about when problems like "how to automate ssh" arise.
I use it on openwrt, it has a package about 7KB in size without dependency, while tcl package is around 440KB. And you can use it in shell directly.
"empty is an utility that provides an interface to execute and/or interact with processes under pseudo-terminal sessions (PTYs). This tool is definitely useful in programming of shell scripts designed to communicate with interactive programs like telnet, ssh, ftp, etc. In some cases empty can be the simplest replacement for TCL/expect or other similar programming tools "
For example:
#!/bin/sh
empty -f -i in -o out telnet foo.bar.com
empty -w -i out -o in "ogin:" "luser\n"
empty -w -i out -o in "assword:" "TopSecret\n"
empty -s -o in "who am i\n"
empty -s -o in "exit\n"

Resources