I am running a test script where files needs to be copied to the target embedded system.But when this command of copying the files to remote target system is run from the script I was prompted for the administrator password of the Target Board.How can I automate the script in such a way that the script will pick the password by itself(from within the script) and I don't have to put the password manually every-time i run the script.
Snippet form the script is as below :
scp test.file1 <Target ip-address>:/home/bot21/test/.
Password is prompted when the above command is run.
The right way to do this is with key-based authentication.
Read about it here.
If that link ever breaks, just google it: "ssh passwordless" or "ssh key authentication". Despite Toby's comment, I think linking to or instructing how to search it yourself is better than repeating what others can say better and in more depth than I can.
Use the -i option. Manpage says:
-i identity_file
Selects the file from which the identity (private key) for public
key authentication is read. This option is directly passed to
ssh(1).
That is do :
scp -i /path/to/identity_file test.file1 <Target ip-address>:/home/bot21/test/
The process of creating the identity file is well described [ here ].
The access-permissions for the identity file should be configured in such a way that potential users in your system who may access this file should be able to read it. Also mind that these users should be able to traverse the path ie /path/to in our example to reach the file
You can use sshpass to pass the password to the scp. Something like
sshpass -p passw0rd scp test.file1 <Target ip-address>:/home/bot21/test/
But as already mentioned, using the keys is recommended. I added the following notes to SO Documentation before it was retired.
Connecting from script using password
When you really need to script ssh connection, piping the password into the ssh command does not work (echo passw0rd | ssh host). It is because the password is not read from standard input, but directly from TTY (teleprinter, teletypewriter, Teletype for historical reasons).
But there is sshpass tool which works around this problem. It can read the password from parameter, file or environment variable. But note that none of these options does not satisfy the security requirements for a passwords!
$ sshpass -p passw0rd ssh host
$ sshpass -f /secret/filename ssh host
$ SSHPASS=passw0rd sshpass -e ssh host
The command line options can be seen by other users in ps (during runtime it is masked, but not during start time and you can't rely on it):
... 23624 6216 pts/5 Ss Aug30 0:00 \_ /bin/bash
... 12812 1988 pts/5 S+ 08:50 0:00 | \_ sshpass -p passw0rd ssh host
... 45008 5796 pts/15 Ss+ 08:50 0:00 | \_ ssh host
Note, that environemnet variables of a process are also accessible by other processes on the system using /proc/PID/environ file.
Finally, storing the password in the file might look like the best possible idea, but still using keys as described in the other examples is preferred way to use ssh.
Related
I am trying to overcome some limitations in our environment to write up an authorized SSH file for passwordless ssh keys.
I am requiring to perform an ssh as a to a target system, and then run a "sudo su - , and then update the service account authorized_keys with a key"
This eventually has to go onto my ansible scripts.
I am using "ssh -t user#target "sudo su - service-user" - which actually successfully gets me into a shell for service-user. But I am not able to figure out a way to pass along the file modify commands with the above.
Any tips or alternative options?
Note: I need to use "ssh -t" option as the requiretty is not set on target systems.
Cheers!
Depending on what transport you're using you can use ssh_args.
OpenSSH is the default connection type for Ansible on OSes that are new enough to support ControlPersist. (This means basically all operating systems except Enterprise Linux 6 or earlier).
Then you can do something like this in your ansible.cfg:
ssh_args = -t -t
Which will force ansible to connect the same way you do manually.
Then in your playbook or together with the task where you need it specify become and become_user
- name: Some task
debug: msg="this is a test"
become: true
become_user: someuser
su has an option, -c, that allows you to pass along a command to execute instead of launching a new shell.
-c, --command=COMMAND
pass a single COMMAND to the shell with -c
However, you're authenticating with sudo, which already does this by default; you can just cut su out of the command entirely:
ssh -t user#target "sudo -u service-user <your-command>"
To go one step further, you note that you're planning on putting this into an Ansible playbook. If so, you probably shouldn't be spending too much time trying to do this manually - Ansible will handle running commands remotely (that's one of its primary features, after all), and has a module for modifying the authorized_keys file.
How can you make SSH read the password from stdin, which it doesn't do by default?
based on this post you can do:
Create a command which open a ssh session using SSH_ASKPASS (seek SSH_ASKPASS on man ssh)
$ cat > ssh_session <<EOF
export SSH_ASKPASS="/path/to/script_returning_pass"
setsid ssh "your_user"#"your_host"
EOF
NOTE: To avoid ssh to try to ask on tty we use setsid
Create a script which returns your password (note echo "echo)
$ echo "echo your_ssh_password" > /path/to/script_returning_pass
Make them executable
$ chmod +x ssh_session
$ chmod +x /path/to/script_returning_pass
try it
$ ./ssh_session
Keep in mind that ssh stands for secure shell, and if you store your user, host and password in plain text files you are misleading the tool an creating a possible security gap
You can use sshpass which is for example in the offical debian repositories. Example:
$ apt-get install sshpass
$ sshpass -p 'password' ssh username#server
You can't with most SSH clients. You can work around it with by using SSH API's, like Paramiko for Python. Be careful not to overrule all security policies.
Distilling this answer leaves a simple and generic script:
#!/bin/bash
[[ $1 =~ password: ]] && cat || SSH_ASKPASS="$0" DISPLAY=nothing:0 exec setsid "$#"
Save it as pass, do a chmod +x pass and then use it like this:
$ echo mypass | pass ssh user#host ...
If its first argument contains password: then it passes its input to its output (cat) otherwise it launches whatver was presented after setting itself as the SSH_ASKPASS program.
When ssh encounters both SSH_ASKPASS AND DISPLAY set, it will launch the program referred to by SSH_ASKPASS, passing it the prompt user#host's password:
An old post reviving...
I found this one while looking for a solution to the exact same problem, I found something and I hope someone will one day find it useful:
Install ssh-askpass program (apt-get, yum ...)
Set the SSH_ASKPASS variable (export SSH_ASKPASS=/usr/bin/ssh-askpass)
From a terminal open a new ssh connection without an undefined TERMINAL variable (setsid ssh user#host)
This looks simple enough to be secure but did not check yet (just using in a local secure context).
Here we are.
FreeBSD mailing list recommends the expect library.
If you need a programmatic ssh login, you really ought to be using public key logins, however -- obviously there are a lot fewer security holes this way as compared to using an external library to pass a password through stdin.
a better sshpass alternative is :
https://github.com/clarkwang/passh
I got problems with sshpass, if ssh server is not added to my known_hosts sshpass will not show me any message, passh do not have this problem.
I'm not sure the reason you need this functionality but it seems you can get this behavior with ssh-keygen.
It allows you to login to a server without using a password by having a private RSA key on your computer and a public RSA key on the server.
http://www.linuxproblem.org/art_9.html
I want to transfer some files from my local to remote, like github does it. I want to happend it very smooth like in shell script. I tried creating one shell script which automates the process of ssh authentication without password but for first time it exposes my remote server password. I dont want to do it that way. Like in git we can't see their server password. Is there any possible way that we can do ?
I used this article script to automate ssh login. http://www.techpaste.com/2013/04/shell-script-automate-ssh-key-transfer-hosts-linux/
As i mentioned, you can use the scp command, like this:
scp /local_dir/some*.xml remote_user#remote_machine:/var/www/html
This requires that you need connect to the remote machine without password, only with ssh key-authentication.
Here is a link: http://linuxproblem.org/art_9.html to help you.
The important steps: (automatic login from host A / user a to Host B / user b.)
a#A:~> ssh-keygen -t rsa
a#A:~> ssh b#B mkdir -p .ssh
a#A:~> cat .ssh/id_rsa.pub | ssh b#B 'cat >> .ssh/authorized_keys'
Is there a way to try multiple passwords when using sshpass command? I have a txt file named hosts.txt listing multiple system IPaddresses and each system uses different passwords (for example - 'mypasswd', 'newpasswd, nicepasswd'). The script reads the hosts.txt file and execute a set of commands on each system. Since I don't know which system uses which of these given passwords, i wanted to try all these set along with sshpass command and execute the script with the password that works.. Is that possible?
#!/bin/bash
while read host; do
sshpass -p 'mypasswd' ssh -o StrictHostKeyChecking=no -n root#$host 'ls;pwd;useradd test'
done < hosts.txt
Instead of trying to get password based authentication, isn't it an option to setup key based auth? You can then either add your one public key to ll systems or optionally generate different ones and use the -i keyfile option or create an entry in the ssh configuration file as below.
Host a
IdentityFile /home/user/.ssh/host-a-key
trying to ssh to another system then perform db2 commands however using 'su db2admin -c' does not seem to work, although it works for normal system commands ..
#!/bin/bash
sshpass -p 'passw0rd' ssh root#server.com "su db2admin -c 'db2text start'"
this is the output ..
rob#laptop:~/Desktop$ ./script.sh
bash: db2text: command not found
Any ideas?
The PATH is not getting updated to the normal root users PATH. Either specify the full path to db2text or add a dash (-) before the username to reload the environment variables
I'll hazard a guess and say that root doesn't have any of the db2 stuff in hi path.
And since you're using su db2admin rather than su - db2admin db2admin inherits
root's environment. Try with that extra - thrown in.
That all said: why on earth aren't you connecting w/ passwordless keys as db2admin?
Another solution that worked ..
#!/bin/bash
sshpass -p 'passw0rd' ssh root#server.com "su db2admin -c '~/sqllib/bin/db2text start'"
But problem is db2 path may change, better to use Eric's answer.