I am having difficulty passing a password through a bash script for an ssh connection. I have everything working, but it still prompts me for the password instead of pulling the stored password. Please take a look at the portion of the script below, and let me know if there is something obvious I'm doing wrong:
#! /bin/bash
echo "Please enter a username:"
read user
echo "please enter a password:"
read password
echo please enter an IP address:"
read ip
ssh "$user"#"$ip"
expect "password:"
send "<password>\r"
interact
I have tried different variations of the "send" line. For instance, I've tried "password\r" and password\r. I've also tried modifying the "expect" line to mirror the exact text returned by the attempted SSH connection.
Thanks for any help that can be provided.
SSH contains code to prevent password theft by redirecting standard I/O.
The correct solution is to generate a private/public key pair with ssh-keygen. Install the public key on the remote side. ssh-copy-id will help.
Then you can use the SSH agent to load the private key into memory and SSH won't ask for a password or key phrase.
Related:
https://askubuntu.com/questions/46930/how-can-i-set-up-password-less-ssh-login
Related
I need to automate an openvpn connection to a server that requires me to enter a password.
I can do this with expect but I don't want to keep the password in plain text in the script.
I found encpass to help encrypt the password which I just need to source and get it to get the encrypted version of the password.
The problem comes when I try to pass the unencrypted password to expect. From what I understand, expect and bash are 2 different environments and bash cannot run expect. What I have so far is the following:
#!/usr/bin/env bash
source encpass.sh
password=$(get_secret)
{
/usr/bin/expect <<EOF
spawn openvpn /home/pi/client.ovpn
expect "Enter Private Key Password:"
send $password
interact
EOF
}
The end result is I run this and it starts the VPN and the script enters the password in the prompt.
If there is a simpler way of doing it, please let me know.
I have tried to automate it with just openvpn and a --auth-user-pass switch pointing to a file with the password in it but I couldn't get that working either.
Two ideas spring to mind:
if you want to embed expect code into a shell script, use the environment
to pass values, and use a quoted heredoc to avoid quoting hell (don't forget
to "hit enter" for the send command)
#!/usr/bin/env bash
source encpass.sh
password=$(get_secret)
export password
/usr/bin/expect <<'EOF'
spawn openvpn /home/pi/client.ovpn
expect "Enter Private Key Password:"
send "$env(password)\r"
interact
EOF
do it all in expect
#!/usr/bin/env expect
set password [exec bash -c {source encpass.sh && get_secret}]
spawn openvpn /home/pi/client.ovpn
expect "Enter Private Key Password:"
send "$password\r"
interact
I want to created .sh file
// Tried to connect to ftp server
ftp name_of_server
//input user name
username
//input password
password
link given below
https://github.com/prokid221/shell-programing.git
Instead of login, it again asked to enter username and password
can any one help with this problem?
If you only need file transfers, you could use curl.
download a file:
curl -O -u user:password ftp://example.com/some-file
upload a file:
curl -T some-file -u user:password ftp://example.com
Note: This method may result in your credentials being saved in your command history.
The best solution is to look at your ftp command manual. It probably provides command line flags or can use environment variables to allow you to specify username and password.
If there is no such thing, an alternate way is to feed ftp standard input. I guess this is what you try to do, but instead here is what your script does:
Run ftp and wait for the command to return. That's where ftp asks about username.
Once ftp returned, run a command named after the username. There is probably no command of that name so it will complain about it.
Then, run a command named after the password. It will fail too, but depending on the special characters in the password, it could become a disaster :-)
So, to really feed stdin, you can use printf(1):
printf "username\npassword\n" | ftp name_of_website
Edit: Another way I forgot is to put those informations in the URL: ftp://username:password#name_of_website.
Try :
#!/bin/sh
HOST='your.ftp.server.net'
USER='yourid'
PASSWD='yourpw'
FILE='file.txt'
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
#put $FILE
#quit
END_SCRIPT
exit 0
If you want to provide hostname from outside the script as commandline, then you can use,
HOST = $1 ,
So if you scriptname is serverftp.sh, you would provide hostname as;
serverftp.sh <ftp_server_name>
how about use expect in shell script?
#!/bin/sh
SERVER="example.com"
ID="toor"
PASSWD="secret"
expect <<EOF
spawn ftp $SERVER
expect ": "
send "$ID\r"
expect "Password:"
send "$PASSWD\r"
expect "ftp>"
send "ls\r
expect "ftp>"
send "quit\r
interact
EOF
I am trying to access remote ssh server from a unix client machine. For this i have used expect script which is calling a bash script to fetch some lines from server log file.
Below is my code:
#!/usr/local/bin/expect -f
set pass "password"
set prompt "(%|$|#)"
spawn ssh deployed#172.16.166.111
expect "password:"
send "$pass\r"
expect -re $prompt
send -- "./access_srvr_log.sh\r"
send -- "exit\r"
code for access_srvr_log.sh file:
#!/usr/local/bin/expect
dir="/home/deployer/Desktop/McKinsey-McKinsey-AdminPanel/log"
tail -n 100 $dir/development.log
echo "hello"
echo >> log.txt
i get this error :
./access_srvr_log.sh
-bash: ./access_srvr_log.sh: No such file or directory
Please help. I have tried lot many changes on the above code and finally reached here.
Thanks.
Friends don't let friends use SSH passwords. It's much less secure.
Use ssh-copy-id to copy your public key to the remote server. (It puts the client ~/.ssh/id_rsa.pub into the server .ssh/authorized_keys) Now you can run "ssh deployer#172.16.144.111 ./access_srvr_log.sh", and it won't prompt for a password. That means you no longer need expect and all the odd problems that come with it.
In fact, it's highly recommended that you disable SSH passwords all together.
To make your script even simpler (maintenance-wise) do this:
1) run ssh-keygen -f ~/.ssh/scriptkey on your client (don't enter a password).
2) Put the public part of your key (~/.ssh/scriptkey.pub on the client) into .ssh/authorized_keys on the server. But this time, put command="/home/deployer/access_srvr_log.sh" just before your new key. This tells the server to run that command for that key.
3) Now your script doesn't even need to specify the command, just the private key. (i.e. scp -i ~/.ssh/scriptkey deployer#172.16.144.111 will run the script). This allows the server to change (i.e. move the script, change the script name) without changing the client. It also means someone stealing your (non-password-protected) key can't log in to the server, but only run your log script.
And there are no guessable passwords laying around in scripts. (You are checking your scripts into version control, right?)
You can simplify it down too
#!/bin/bash
{
/usr/bin/expect <<- EOF
spawn ssh deployer#172.16.144.111 "tail -n 100 /home/deployer/Desktop/McKinsey-McKinsey-AdminPanel/log/development.log"
expect "password:"
send "deployer\r"
expect eof
EOF
} |grep -v "deployer#172.16.144.111's password:">> log.txt
I'm trying to write a shell script (Bash) to log into a SonicWall firewall device and issue a command to perform automated backups of the devices ruleset. I prefer to do this in Bash but I will accept a python, perl, except, or applescript solution. If it cannot be done in bash please mention that.
Problems:
1.) SSH server on firewall is custom, a user name and password has to be specified after issuing a
$ ssh server.com
so no matter what username you issue e.g.
$ ssh admin#server.com
the SSH server still presents a username and password box after
2.) The SSH server is minimal and I cannot use public-keys
I tried using a here-document but it isn't working and it results in an immediate "connection closed by remote host".
The command I need to execute takes the form of this:
export preferences ftp "ftp.server.com" "user1" "mypassword" "output.exp"
Connecting gives me this:
$ ssh admin#server.com
Copyright (c) 2010 SonicWALL, Inc.
User:
After a username is issued it brings up the password prompt:
User:user1
Password:
I tried a here-document to no avail.
$ ssh server <<+
user1
mypassword
export preferences ftp "ftp.server.com" "user1" "mypassword" "output.exp"
exit
+
Pseudo-terminal will not be allocated because stdin is not a terminal.
Connection to 10.1.1.1 closed by remote host.
I tried using echo to pipe in commands too but that doesn't work either.
Typing the commands in manually works just fine.
Any help on this would be greatly appreciated.
As others have suggested, expect is probably what you want to use here.
Here's a short example of how to work with it from bash to get you started:
login=root
IP=127.0.01
password=helloworld
# +whatever variables you need to use
# Run the expect script from bash
expect_sh=$(expect -c "
spawn ssh $login#$IP
expect \"password:\"
send \"$password\r\"
expect \"#\"
send \"cd $dest_dir\r\"
expect \"#\"
send \"chmod +x $server_side_script $other_script\r\"
expect \"#\"
send \"./$device_side_script\r\"
expect \"#\"
send \"cat results_file\r\"
expect \"#\"
send \"exit\r\"
")
# Output or do something with the results
echo "$expect_sh"
You can automate the ssh session using the original expect, here is a nice article discussing it in detail: http://solar1.net/drupal/automating%20SSH%20with%20expect or the Python module pexepect: http://linux.byexamples.com/archives/346/python-how-to-access-ssh-with-pexpect/
I'm not a BASH expert but i had to do something where interactive password prompts was causing me a problem.
Basically your script needs to wait to be asked to enter login credentials, and pass them when prompted in order to login, once logged in you can issue the command.
I recommend looking at spawning "expect" sessions. Basically in your script you use expect to basically say "i expect to see password: in the response, when i do, i need to pass in the following data".
Here's the wiki page which helps explain it http://en.wikipedia.org/wiki/Expect
and if you google around you will find lots of help.
that didn't work for me.
I had to pass the variables to the script at launch.
Example launch script login2.sh, with three arguments:
-bash-4.1$ ./login2.sh Jan2**** HIE_SUPER 10.244.112.182
First post, thanks in advance for any help.
I'm somewhat new to scripting in general but I've managed to build a nice wrapper in bash that's designed to collect some variables and then make some connections to a couple of remote boxes and do some things related to a web statistics system and launch some hadoop processes. Basically a series of tedious tasks that I'm trying to automate. (unnecessary details complete).
The problem I'm running into is finding a way to effectively connect to those remove servers, authenticate as as a regular user, then switch users for various tasks. Here's the relevant code:
#!/bin/sh
#Script's run as root. this asks for the sudoers pass
read -p "Enter password for $SUDO_USER: " -s password
#Defines some testing commands I want to pass to a remote box
CMD="hostname; id; sudo su -; id; pwd;"
#launches an expect script with some defined variables as arguments.
/home/ME/scripts/derp.expect $SUDO_USER $definedremoteserver "$command" "$password"
Now the expect script being used:
#!/usr/bin/expect
#expect script to help with SSH connections for the urchinizer bash script
set arg1 [lindex $argv 0]
set arg2 [lindex $argv 1]
set arg3 [lindex $argv 2]
set arg4 [lindex $argv 3]
spawn ssh -oStrictHostKeyChecking=no $arg1#$arg2 "$arg3"
expect "password:"
send "$arg4\r"
interact
expect "password"
send "$arg4\r"
interact
I'm having trouble determining why this fails. I've researched quite a bit and have tried numerous variations of the code. Basically when I run this, it takes my pass and I'm able to make the initial connection. Then the script tries to switch user and the second expect fails. The first 'id' and 'hostname' output successfully. When the user switch happens, the second expect doesn't work and I'm left with just a password prompt. I enter my pass anyway (which displays in plain text for some reason) and the script just hangs without outputting the second 'id' and 'pwd' commands I'm trying to use to verify that this is working.
If I actually login to that box and do a sudo -i or sudo su - this is what the password prompt looks like:
[sudo] password for my.name:
So for the second (not working) expect, I've tried a few different variations with somewhat different results but no success.
Sorry for the long post. This has been driving be nuts. Is what I'm trying to do possible? Is there a smarter way to handle this? Anyone spot any obvious mistakes? Also, a secondary question... how do wildcards work in those expect lines?
If you can, use some scripting language as Perl, Python or Ruby with some module for SSH.
For instance, using Perl and the Net::OpenSSH module:
use Net::OpenSSH;
my $ssh = Net::OpenSSH->new($host, user => $user, password => $password);
my $output = $ssh->capture({stdin_data => "$sudo_password\n"},
'sudo', '-Sk', '-p', '', '--',
'ls', '/');
You should use "Public Key Authentication" instead of "Password Authentication" in OpenSSH.
1: create the private/public key pair for the user you want to login with this command:
ssh-keygen -t rsa
Do not supply passwords, choose the default path (enter, enter, enter).
This should be done for each of your SSH machines (clients and servers).
2: from each client machine you want to login from, copy your new public key file content to your favourite text editor (notepad, gvim, etc)
cat ~/.ssh/id_rsa.pub
You should now have all your client's public keys pasted into your editor, something like this:
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAt9sGP1PKR1XzpozHQc9ufyzOnePHCnRzUhdfSvfQTzJO28CgnHwhANdaBeOrLq5b+VOoPJFj5NquYXmJ6YikSJCwHlvfewA/5p0IkucsJLxqYQMDRhyeXb9fCk85MoNRJjAd+Cst+gI9Cwpp1ysLMDY77k/a9eT3ExkgbGd6mdtfjAlP/o/rRMcqNwp9Pdhh6kkxrM0v1ceNSTbTeO7XCLvekqtRiwjWImhQs56JVbB/RLySNKtqjbpr7Zhn1m+p6+vmBmgwF3xBBvzziYfMm/vG1ZvvGIsI3dxRDWuSZ8+o63w7Y20M9NQn4QkqV6NFjX3conBiDGtDBKain2zj6Q== dino#blackbigone
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0JR6d9LWgvPCbvBajrbVly3cxX7ZkbH4+MUBu+ak2G5SGLbGBcwdi3JquBAT1+U/hl+TKKUUw1XjjjazdjgYCHWIguDWzmqoyT4bQN2aymNoqD35T+LWAaqwC36m95fRfJh3HSOtx7KXpsBZjvR40rg901f8ReIjBoL7G620rrsRDqaDS08Mm6TjThBrCeTYX2YzugodpUNP2evwFOBMrYw/TIcX5Lza8xRCctm8MRodsx/yvuYuZJSanVLs3Q6sJ/n9o20L8Jt1Fu1cnyxJTs9THiLOnZyrTBXvbKJymit6p3hfDpDlWtO/crNeyt0H8jJcZfiCnhQwfib2VMMqJw== erica#blackbigone
3: paste the ascii armored public keys you have in your text editor into ~/.ssh/authorized_keys file on each SSH server you want to login into. You must be the user you want to login. Create the file if it doesn't exists.
This way you are granting the permission to login to the server where you created the authorized_keys file to all users presenting with the given public keys.
The login is successful if the user have the correct matching private key.
Once logged in on the remote server, you can use sudo (you have to configure /etc/sudoers file first with the visudo command) to execute commands by another user.
To avoid sudo to request for a password (because you are authenticated in /etc/sudoers...) you have to set the NOPASSWD flag, like the line below:
%admin ALL=(ALL) NOPASSWD: ALL