Differences between revisions 1 and 11 (spanning 10 versions)
Revision 1 as of 2007-05-03 00:04:18
Size: 2130
Editor: redondos
Comment:
Revision 11 as of 2015-05-22 17:21:38
Size: 2967
Editor: static-204-15-64-187
Comment: added ssh-copy-id, made ssh-key generation optional (if already exists) and changed example command to illustrate the point that the command ran on a remote host.
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq69)]] <<Anchor(faq69)>>
Line 3: Line 3:
Line 8: Line 7:
If you understand this and still want to continue, then the next thing you need to do is read and understand the man page for {{{ssh-keygen(1)}}}. This will tell you how to generate a public/private key pair (in either RSA or DSA format), and how to use these keys to authenticate to the remote system without sending a password at all. If all you want is for the user to be prompted for a password by `ssh`, simply make sure your script is executed in a terminal and that your `ssh` command is executed in the foreground ("normally"). `ssh` will prompt the user for a password if the remote server requires one for authentication. Your script doesn't need to get involved.
Line 10: Line 9:
Since many of you are too lazy to read man pages, and instead prefer to ask us in #bash to read them for you, I'll even give a brief summary of the procedure here: Specifically, '''do not''' ask the user for their password yourself, store it in a variable, and then try to pass it along to `ssh`. That reduces your security enormously.

If you want to bypass the password authentication entirely, then you should use ''public key authentication'' instead. Read and understand the man page for `ssh-keygen(1)`, or see SshKeys for a brief overview. This will tell you how to generate a public/private key pair (in either RSA or DSA format), and how to use these keys to authenticate to the remote system without sending a password at all.

Here is a brief summary of the procedure:
Line 13: Line 16:
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub | ssh me@remote "cat >> ~/.ssh/authorized_keys"
ssh me@remote date # should not prompt for passWORD,
test -f ~/.ssh/id_rsa || ssh-keygen -t rsa
ssh-copy-id me@remote
ssh me@remote hostname # should not prompt for a passWORD,
Line 19: Line 22:
If your key has a passphrase on it, and you want to avoid typing it every time, look into {{{ssh-agent(1)}}}. It's beyond the scope of this document, though. If your key has a passphrase on it, and you want to avoid typing it every time, look into {{{ssh-agent(1)}}}. It's beyond the scope of this document, though.  If your script has to run unattended, then you may need to remove the passphrase from the key. This reduces your security, because then anyone who grabs the key can log in to the remote server as you (it's equivalent to putting a password in a file). However, sometimes this is deemed an acceptable risk.
Line 21: Line 24:
If you're being prompted for a password even with the public key inserted into the remote {{{authorized_keys}}} file, chances are you have a permissions problem on the remote system. Check '''every single directory''' in the full path leading up to the {{{authorized_keys}}} file and make sure they do '''not''' have world- or group-write privileges.  ''E.g.'', if your home directory is {{{/home/fred}}} and {{{/home}}} has group "staff" write privileges, {{{sshd}}} will refuse to honor your key. If you're being prompted for a password even with the public key inserted into the remote {{{authorized_keys}}} file, chances are you have a permissions problem on the remote system. See SshKeys for a discussion of such problems.
Line 25: Line 28:
If you ''really'' want to use a password instead of public keys, first have your head examined. Then, if you ''still'' want to use a password, use {{{expect(1)}}}. And don't ask us for help with it. If you ''really'' want to store a password in a variable and then pass it to a program, instead of using public keys, first have your head examined. Then, if you ''still'' want to use a password, use [[http://expect.sf.net/|expect(1)]] (or the less classic but maybe more bash friendly [[http://empty.sf.net|empty(1)]]). But don't ask us for help with it.

`expect` also applies to the `telnet` or [[FtpMustDie|FTP]] variations of this question. However, anyone who's still running `telnetd` without a damned good reason needs to be fired and replaced.

I want to automate an ssh (or scp, or sftp) connection, but I don't know how to send the password....

STOP!

First of all, if you actually were to embed your password in a script somewhere, it would be visible to the entire world (or at least, anyone who can read files on your system). This would defeat the entire purpose of having a password on your remote account.

If all you want is for the user to be prompted for a password by ssh, simply make sure your script is executed in a terminal and that your ssh command is executed in the foreground ("normally"). ssh will prompt the user for a password if the remote server requires one for authentication. Your script doesn't need to get involved.

Specifically, do not ask the user for their password yourself, store it in a variable, and then try to pass it along to ssh. That reduces your security enormously.

If you want to bypass the password authentication entirely, then you should use public key authentication instead. Read and understand the man page for ssh-keygen(1), or see SshKeys for a brief overview. This will tell you how to generate a public/private key pair (in either RSA or DSA format), and how to use these keys to authenticate to the remote system without sending a password at all.

Here is a brief summary of the procedure:

test -f ~/.ssh/id_rsa || ssh-keygen -t rsa
ssh-copy-id me@remote
ssh me@remote hostname     # should not prompt for a passWORD,
                       # but your key may have a passPHRASE

If your key has a passphrase on it, and you want to avoid typing it every time, look into ssh-agent(1). It's beyond the scope of this document, though. If your script has to run unattended, then you may need to remove the passphrase from the key. This reduces your security, because then anyone who grabs the key can log in to the remote server as you (it's equivalent to putting a password in a file). However, sometimes this is deemed an acceptable risk.

If you're being prompted for a password even with the public key inserted into the remote authorized_keys file, chances are you have a permissions problem on the remote system. See SshKeys for a discussion of such problems.

If that's not it, then make sure you didn't spell it authorised_keys. SSH uses the US spelling, authorized_keys.

If you really want to store a password in a variable and then pass it to a program, instead of using public keys, first have your head examined. Then, if you still want to use a password, use expect(1) (or the less classic but maybe more bash friendly empty(1)). But don't ask us for help with it.

expect also applies to the telnet or FTP variations of this question. However, anyone who's still running telnetd without a damned good reason needs to be fired and replaced.

BashFAQ/069 (last edited 2019-04-11 12:53:15 by GreyCat)