Automating SSH Password Authentication in Scripts: Secure Alternatives to Public Key Auth


20 views

When public key authentication isn't an option, automating SSH connections in scripts becomes trickier. Many system administrators face this situation when dealing with legacy systems, locked-down environments, or during transitional periods where key-based auth isn't yet implemented.

Warning: These methods involve storing passwords in some form. Always consider the security implications before implementation.

# Method 1: Using sshpass (Ubuntu/Debian)
# Install first: sudo apt-get install sshpass
sshpass -p "your_password" ssh username@hostname "remote_command"

# Method 2: Using expect script
#!/usr/bin/expect
set timeout 20
spawn ssh username@hostname
expect "password:"
send "your_password\r"
expect "$ "
send "your_command\r"
expect "$ "
send "exit\r"

If you must store credentials:

  • Use environment variables (but beware of process listing)
  • Store in encrypted config files with limited permissions
  • Consider using a credential management system

Here's a more complete script example:

#!/bin/bash
REMOTE_USER="admin"
REMOTE_HOST="example.com"
PASSWORD=$(cat /path/to/secure/password/file)
COMMAND="uptime"

# Using sshpass with stricter options
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
$REMOTE_USER@$REMOTE_HOST "$COMMAND"

Once possible, immediately transition to using SSH keys:

ssh-keygen -t rsa -b 4096
ssh-copy-id username@hostname

Remember to remove any password-automation scripts after migration to key-based authentication.


When you need to automate SSH connections in scripts but can't use public key authentication (due to server constraints), you're left with two main options:

The simplest solution is sshpass, a utility designed specifically for this purpose. First install it:

sudo apt-get install sshpass

Then use it in your script:

sshpass -p 'your_password' ssh username@hostname "remote_command"

For better security (avoiding password in command line):

export SSHPASS='your_password'
sshpass -e ssh username@hostname "remote_command"

For more complex scenarios, you can use Expect:

#!/usr/bin/expect -f
spawn ssh username@hostname
expect "password:"
send "your_password\r"
expect "$ "
send "your_command\r"
expect "$ "
send "exit\r"

While these solutions work, they come with security implications:

  • Passwords may be visible in process listings
  • Scripts containing passwords need strict file permissions
  • Consider using temporary environment variables

If you can establish an initial manual connection, you can maintain it:

# In ~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/control:%h:%p:%r
    ControlPersist 10m

Then subsequent connections won't require authentication.

Here's a complete example for automated backups:

#!/bin/bash
REMOTE_USER="backupuser"
REMOTE_HOST="backup.example.com"
PASSWORD="securepass123"

sshpass -p "$PASSWORD" ssh "$REMOTE_USER@$REMOTE_HOST" \
"tar -czf /tmp/backup-$(date +%Y%m%d).tar.gz /important/data && \
mv /tmp/backup-*.tar.gz /backup_location/"