While key-based authentication is the gold standard for SSH security, real-world scenarios often require password authentication. Common cases include:
- Public SSH servers with restricted command execution
- Systems where you lack permissions to install public keys
- Temporary access to legacy systems
- Accounts without home directories for authorized_keys
Before we explore solutions, it's critical to understand why you should never store passwords directly in .ssh/config
:
# NEVER DO THIS - INSECURE!
Host server1
User tux
Port 2202
HostName xxx.x.xx.x
Password mySecret123
Option 1: Using sshpass (For Testing Only)
For temporary debugging purposes, you can use sshpass:
sudo apt-get install sshpass
sshpass -p 'your_password' ssh user@hostname
Warning: This exposes the password in command history and process listings.
Option 2: SSH Config with sshpass Wrapper
Create a more secure wrapper script:
#!/bin/bash
# ~/.ssh/connect_server1
read -s -p "Enter SSH password: " SSHPASS
export SSHPASS
sshpass -e ssh -p 2202 tux@xxx.x.xx.x
unset SSHPASS
Then make it executable:
chmod +x ~/.ssh/connect_server1
Option 3: Using ssh-agent with Expect
For more robust automation, create an expect script:
#!/usr/bin/expect -f
set timeout 20
spawn ssh -p 2202 tux@xxx.x.xx.x
expect "password:"
send "your_password\r"
interact
Combine sshpass with GPG-encrypted password storage:
#!/bin/bash
PASSWORD=$(gpg --decrypt ~/.ssh/passwords/server1.gpg)
sshpass -p "$PASSWORD" ssh -p 2202 tux@xxx.x.xx.x
To create the encrypted password file:
echo "mySecret123" | gpg --encrypt --recipient your@email.com > ~/.ssh/passwords/server1.gpg
- Always set strict permissions:
chmod 600 ~/.ssh/*
- Use separate password files per server
- Rotate passwords regularly
- Consider using a password manager with CLI integration
- For teams, use SSH certificates instead of passwords
When you can temporarily access a system with your public key:
ssh -A -t gateway.example.com ssh target.server.com
This forwards your local SSH agent through the gateway.
While SSH key-based authentication remains the gold standard, real-world scenarios often require password authentication. Common situations include:
- Public SSH jump hosts with restricted access
- Systems where you can't modify authorized_keys
- Temporary access to vendor-managed systems
- Legacy systems without proper home directories
Before exploring solutions, it's crucial to understand why we shouldn't store passwords in plaintext within .ssh/config:
# NEVER DO THIS - INSECURE!
Host server1
User tux
Port 2202
HostName xxx.x.xx.x
Password mySecret123 # This would be terrible practice
Here's a secure workflow using sshpass with environment variables:
# First install sshpass
sudo apt-get install sshpass
# Create a password helper script
echo '#!/bin/bash' > ~/.ssh/askpass
echo 'echo "your_password_here"' >> ~/.ssh/askpass
chmod 700 ~/.ssh/askpass
# Make it executable
chmod +x ~/.ssh/askpass
# Configure your SSH connection
export SSH_ASKPASS=~/.ssh/askpass
setsid ssh tux@xxx.x.xx.x -p 2202
For automation scripts where you need strict control:
#!/bin/bash
SERVER="xxx.x.xx.x"
PORT="2202"
USER="tux"
PASS="your_secure_password"
sshpass -p "$PASS" ssh -p $PORT $USER@$SERVER
For enterprise environments, consider using gpg-encrypted passwords:
# Store password securely
echo "mySecret123" | gpg --encrypt --recipient your@email.com > ~/.ssh/server1_pass.gpg
# Create a decryption wrapper
echo '#!/bin/bash' > ~/.ssh/get_pass
echo 'gpg --decrypt ~/.ssh/server1_pass.gpg 2>/dev/null' >> ~/.ssh/get_pass
chmod 700 ~/.ssh/get_pass
# Use in your SSH command
SSH_ASKPASS=~/.ssh/get_pass setsid ssh -p 2202 tux@xxx.x.xx.x
- Always set strict permissions (chmod 600) on any password storage files
- Consider using a password manager with CLI integration
- For production systems, implement SSH certificates instead of passwords
- Regularly rotate any stored passwords
- Never commit password files to version control
For complex interactive sessions, expect provides robust automation:
#!/usr/bin/expect -f
set timeout 20
set host "xxx.x.xx.x"
set user "tux"
set port "2202"
set password "your_password"
spawn ssh -p $port $user@$host
expect "*?assword:*"
send "$password\r"
interact