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