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


2 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/"