99

I'm using Ubuntu 11.10. I'm using ssh for connecting to many servers daily, so I put their parameters in the .ssh/config file like this:

Host Home
User netmoon
Port 22
HostName test.com

Is there a way to put passwords for each connection in this file, so that, when the server asks for the password, the terminal enters its password and sends it to the server?

I need this because sometimes I stand away from the PC and when I go back, type a password and press Enter the terminal says CONNECTION CLOSED.

P.S. I don't want to use a public/private key pair.

  • 1
    I'm in the same situation and I cannot upload my public key because I have ssh access only for svn. That is if I try ssh svnhost I get "( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops partial-replay ) ) )" svnserve response and not the shell – Uberto Oct 25 '12 at 14:27
  • See unix.stackexchange.com/a/83991/26493 and andre.frimberger.de/index.php/linux/… for a way by utilizing SSH_ASKPASS. – Olaf Dietsche Jun 27 '15 at 9:41

13 Answers 13

55

Trading off security for convenience never ends well...

Could you use ssh-copy-id from the openssh-client package?

From man ssh-copy-id:

ssh-copy-id is a script that uses ssh to log into a remote machine and append the indicated identity file to that machine's ~/.ssh/authorized_keys file.

| improve this answer | |
  • 13
    This doesn't work if the remote admin insists on disabling public key authorization... – tomasz Sep 25 '14 at 21:36
  • 2
    Yes, but being realistic on systems under your entire direct supervision and control is not making a compromise. Say, for example, on a vagrant virtual machine with no outside connections used solely for development purposes on a single seat. – Scott Oct 30 '14 at 18:29
  • 42
    Insisting on draconian security without cause also never ends well. – cwallenpoole Dec 23 '14 at 17:22
  • 6
    Sometimes it ends well. – devth Sep 22 '15 at 0:26
  • 3
    IMHO, the insistence of passwords for authentication is more risk than not. I oftentimes set often used passwords for ssh as environment variables as I am loath to remember a set of arbitrary strings. By demanding users enter them is simply asking them to be poorly stored. – eggmatters Feb 16 '16 at 17:32
26

If you don't really want to use a public/private key pair, you can write an expect script to enter the password for you automatically depending on the destination address.

Edit: What I mean is that you can have a script that, on one hand, uses expect to enter the password for you and, on the other hand, reads the password for a given user and host from a configuration file. For example, the following python script will work for the sunny day scenario:

#!/usr/bin/python                                                                                                                        
import argparse
from ConfigParser import ConfigParser
import pexpect

def main(args):
    url = args.url
    user, host = url.split('@', 1)

    cfg_file = 'ssh.cfg'
    cfg = ConfigParser()
    cfg.read(cfg_file)
    passwd = cfg.get(user, host)

    child = pexpect.spawn('ssh {0}'.format(url))
    child.expect('password:')
    child.sendline(passwd)
    child.interact()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Run ssh through pexpect')
    parser.add_argument('url')
    args = parser.parse_args()
    main(args)

and the configuration file format would be as follows:

[user_1]
host1 = passwd_1
host2 = passwd_2

[user_2]
host1 = passwd_1
host2 = passwd_2

Note: As explained, the python script would need to be much more complex to handle all the possible errors and question messages from ssh and all the possible URLs (in the example it's assumed that it will be something like user@host, but the user part isn't used most of the times), but the basic idea would still be the same. Regarding the configuration file, you may use a different configuration file or use .ssh/config and write your own code to parse that file and get the password for a given user and host.

| improve this answer | |
  • can you explain further? – Netmoon Dec 16 '11 at 6:29
  • @Netmoon I added a small example to my answer to my it clearer. – jcollado Dec 18 '11 at 13:14
  • This doesn't answer the question of how to put the password in the .ssh/config file – Eric Woodruff Mar 18 '16 at 18:20
  • 1
    Indeed, it does not answer that question. But it solves the problem: avoid having to type passwords manually and store them in a file. Which is pretty what OP requires. – Arcesilas Apr 30 '17 at 20:19
20

How about ProxyCommand:

Host Home-raw
    HostName test.com
Host Home
   User netmoon
   Port 22
   ProxyCommand sshpass -pmypass ssh netmoon@%h-raw nc localhost %p

You can use ssh -W instead of nc as well:

ProxyCommand sshpass -pmypass ssh netmoon@%h-raw -W localhost:%p
| improve this answer | |
  • It will not work as expected with -W option. Do you have any workaround? – Toan Nguyen May 9 '17 at 7:24
  • 2
    It still asks me for the password with this proxy command... – Victor Pudeyev Nov 3 '17 at 23:34
  • 1
    I also find it still asks for a password. All this seems to do is move the problem from test.com requiring a password to Home requiring a password. What's the point? What's the trick to get it to work? – Martin Bramwell Feb 26 '19 at 18:48
19

There also is sshpass program for that. How to use: sshpass -p MyPa55word ssh me@myservor.com

| improve this answer | |
  • 29
    Unless you preface your command with a space, (sshpass instead of sshpass), you have just stored your password ("MyPa55word") in your shell's history file. – waltinator Jun 29 '16 at 18:27
  • 1
    @waltinator good point – igor Sep 16 '16 at 15:25
  • 3
    Well the question asker was fine with it being in .ssh/config, why not in shell history too? – Darth Egregious Nov 23 '17 at 18:48
  • It's not officially on Homebrew but you can install from a third-party repo with brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb. More: gist.github.com/arunoda/7790979 – Jacob Ford Jan 18 '18 at 4:04
  • read -s password; sshpass -p "$password" ssh me@myservor.com. This will prevent password from showing in history – Alexander Bird Aug 21 '18 at 13:55
16

No. This is not possible I'm afraid.

The only real alternative is to use private keys but you've said you don't want to (why not?).

| improve this answer | |
  • 9
    because i don't have permission to put another key on server. – Netmoon Dec 15 '11 at 11:42
  • 2
    @Netmoon: If you can log in, you can add a key, right? You only need write access to your home directory, unless the sysadmin set things up strangely. – Scott Severance Dec 20 '11 at 4:07
  • 4
    @ScottSeverance I think that is the situation this question refers to. Not having the ability to add a key. Yes it is strange, but it often happens. – user239558 May 16 '13 at 15:16
  • 5
    I've had the very common experience of shared hosting environments where public key access is disabled, so even though you can add keys, they are not used. it goes against reason yes, but that's the way many hosting providers set up their servers – billynoah Jun 9 '14 at 14:01
  • 1
    There are answers that show it is possible – Eric Woodruff Mar 18 '16 at 18:18
8

You can create a simple ssh script replacement in /usr/local/bin:

#!/bin/bash

host=$1
password=`awk "/#Password/ && inhost { print \\\$2 } /Host/ { inhost=0 } /Host $host/ { inhost=1 }" ~/.ssh/config`

if [[ -z "$password" ]]; then
  /usr/bin/ssh $*
else
  sshpass -p $password /usr/bin/ssh $*
fi

And then in your ~/.ssh/config file you can use

Host foohost
    User baruser
    #Password foobarpassword
| improve this answer | |
4

I use an application from VanDyke Software called SecureCRT.

http://www.vandyke.com/products/securecrt/

It is not free, but very reasonably priced. I have used it for years (running on Windows, or using Wine) for remote access, terminal emulation, and (dispersed) network management. They finally released a native Linux version of this at the beginning of 2011.

It has support for complex login settings (or scripts), stored passwords (or certificates), tabbed multiple sessions, etc.

At startup you can choose which remote target (and protocol) from a structured list (tree view) of stored remote (or local) machines, or just create a connection (which is then stored).

I have found it particularly useful for remote sites with advanced authentication, non-standard ports, or firewall-access negotiation.

If you are doing remote access a lot (part of your main role), then this application will justify its expense in the first month of use.

| improve this answer | |
  • sorry, i don't understand. can you explain ? – Netmoon Dec 16 '11 at 6:38
  • 1
    reworded for you .. – david6 Dec 16 '11 at 9:13
  • 2
    Since posting of the above response there has been several iterations of SecureCRT, including the latest one VanDyke just released in early December 2013. Each iteration has been improving the program making it even more versatile. It also has a rich API that allows the program to be controlled/interfaced with Python/VB scripts. SecureCRT has been part of my core toolkit for a good decade, and I highly recommend it. – Ville Dec 19 '13 at 21:15
  • Agreed. I continue to beta-test each new release, and was heavily involved in early testing for porting to Ubuntu. – david6 Dec 19 '13 at 22:36
2

Answering the question you asked, no it's not possible to configure a default password in an ssh config file.

But if indeed, as you say, it's "because sometimes I stand away from the PC and when I go back, type a password and press Enter the terminal says CONNECTION CLOSED", then why not prevent closing the session instead? SSH can keep connections alive for you.

Host Home
  User netmoon
  Port 22
  HostName test.com
  ServerAliveInterval 300
  ServerAliveCountMax 2
| improve this answer | |
1

The answer of @BrunoPereira to this question shows an alternative method to connect without explicitly entering a password and avoiding ssh keys.

You could create a script, an alias or a function in your ~/.bashrc to quickly execute that command.

Obviously, there are security considerations you should take into account with this approach.

| improve this answer | |
  • It's great that you link to a solution - however, it's also good practice to go ahead and post the solution here. That way, if the link is ever removed (as happens on stack exchange occasionally) there is still a usable answer here. – Paul Sep 14 '18 at 19:57
1

Thanks, Arek for the inspiration...

Rather than running another shell process, this is just a function running in the current bash shell. It runs a single awk command to parse the config file and figure out if it should take the password from a shell variable or from the password written cleartext into the ssh config file (with awk in an eval instead of describe due to issues I hit using describe).

I tried so many ways of using sshpass directly in an ssh config file using ProxyCommand, but nothing seemed to work as expected, except when I could log in to a box via RSA and then I needed to send a password to open my encrypted directory. However, my function below seems to work for me in all cases, even for Cygwin.

# In your .bash_profile
function ssh(){
    host=$1;
    unset PASSWORD
    unset PASSVAR
    eval $(awk "/ *#[Pp]assvar / && inhost { printf \"PASSVAR=%s\",\$2; exit 1 } / *#[Pp]assword / && inhost { printf \"PASSWORD=%s\",\$2; } /^#?[Hh][oO][sS][tT] / && inhost { inhost=0; exit 1 } /^[Hh][oO][sS][tT] $host\$/ { inhost=1 }" ~/.ssh/config)
    if [[ -z "$PASSWORD" ]] && [[ -z "$PASSVAR" ]]; then
        /usr/bin/ssh -q $* 2>/dev/null
    else
       if [[ -n "$PASSVAR" ]]; then
          PASSWORD=$(TMP=${!PASSVAR-*};echo ${TMP##*-})
       fi
       /usr/local/bin/sshpass -p"$PASSWORD" /usr/bin/ssh -q $* 2>/dev/null
    fi
}
# and setup your passwords (perhaps in .bashrc instead...)
MYPASS_ENVVAR=SomePassword
MYPASSWD_FROM_FILE=$(</home/me/.passwd_in_file)

Then a ~/.ssh/config section looks like this:

Host MyHostname
 Port 22
 Hostname 2.1.2.2
 User merrydan
 #Passvar MYPASS_ENVVAR
 #Password Some!Password

If a #Passvar exists in the config section this overrides the #Password.
$MYPASS_ENVVAR is the environment variable holding your password.

Enjoy!

| improve this answer | |
0

Here's my elaborate variation on @ArekBurdach's answer. It offers the following extensions:

  • the host can be anywhere in the ssh command-line; i.e. it also supports the ssh <args> <host> <commands> syntax
  • does not hard-code the path to ssh
  • more robust parsing of ssh_config
  • Bonus: wrapper for scp, too

ssh-wrapper

#!/bin/bash

password=$(awk '
BEGIN {
    # Collect the SSH arguments as keys of a dictionary, so that we can easily
    # check for inclusion.
    for (i = 2; i < ARGC; i++) {
        sshArgs[ARGV[i]] = 1
    }

    # Only process the first argument; all others are the command-line arguments
    # given to ssh.
    ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
    if ($2 in sshArgs)
        inhost=1
    else
        inhost=0
}
' ~/.ssh/config "$@")


if [ "$password" ]; then
    sshpass -p "$password" "$(which ssh)" "$@"
else
    "$(which ssh)" "$@"
fi

scp-wrapper

#!/bin/bash

password=$(awk '
BEGIN {
    # Collect the SCP arguments as keys of a dictionary, so that we can easily
    # check for inclusion.
    for (i = 2; i < ARGC; i++) {
        colonIdx = index(ARGV[i], ":")
        if (colonIdx > 0) {
            scpArgs[substr(ARGV[i], 1, colonIdx - 1)] = 1
        }
    }

    # Only process the first argument; all others are the command-line arguments
    # given to scp.
    ARGC = 2
}
$1 == "Password" && inhost { print $2 }
/^\s*Host\s/ {
    if ($2 in scpArgs)
        inhost=1
    else
        inhost=0
}
' ~/.ssh/config "$@")


if [ "$password" ]; then
    sshpass -p "$password" "$(which scp)" "$@"
else
    "$(which scp)" "$@"
fi

Installation

Define aliases in your ~/.bashrc:

alias ssh=ssh-wrapper
alias scp=scp-wrapper

Configuration

With the IgnoreUnknown directive, ssh does not complain about a newly introduced Password directive, so (in contrast to @ArekBurdach's answer), we can make this appear as a "real" configuration. If you don't like this, it's trivial to change the script back to the commented-out one.

# Allow specifying passwords for Host entries, to be parsed by ssh-wrapper.
IgnoreUnknown Password

Host foohost
    User baruser
    Password foobarpassword
| improve this answer | |
  • I like your solution more, but it's not working for me. $password is always empty. – Ric0 Oct 31 '19 at 13:24
0

If you don't have direct access to key-pair, you could encrypt password on your local machine.

The way to do it is encrypt your password using key in addition to @Eric Woodruff 's ProxyCommand.

A way to combine is using pipe:

openssl rsautl -decrypt -inkey /path/to/decrypt_key -in /path/to/encrypted_password  | sshpass ssh real-destination -tt

where

Host real-destination
    Hostname test.com
    User netmoon
| improve this answer | |
0

There is a slight variant of a way described in the blog on how to use sshpass which can be found here. Given that you have a gpg encrypted password (how ot do this is described in the blog) file you could do something like this:

 sshpass -p $(echo $(gpg -d -q .sshpasswd.gpg)) ssh your_desination.xyz

and simply save that command as an alias in your .bashrc .

If you want to tunnel through that connection you could do something like

 Host actual_dest
      Hostname actual.dest.xyz
      User username
      ProxyCommand sshpass -p $(echo $(gpg -d -q ~/.sshpasswd.gpg)) \ 
                   ssh your_destination.xyz nc %h %p
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.