Many developers try adding ssh-agent initialization to their .bashrc file, only to encounter issues with nested shells. Here's why it fails:
# This in .bashrc creates problems:
ssh-agent /bin/bash
ssh-add ~/.ssh/id_rsa
When you SSH into your server, this creates an infinite loop of new bash sessions because each SSH connection executes .bashrc, which spawns another shell.
The most elegant solution involves using your existing ssh-agent from your local machine:
# In ~/.ssh/config on your LOCAL machine
Host *
ForwardAgent yes
AddKeysToAgent yes
This forwards your local SSH keys to the remote server, eliminating the need to manage keys remotely.
If you must run ssh-agent on the remote server, use this modified .bashrc approach:
# In ~/.bashrc
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa 2>/dev/null
fi
The condition checks if an agent is already running, preventing nested shells.
For Ubuntu systems with systemd, create a persistent ssh-agent service:
# Create ~/.config/systemd/user/ssh-agent.service
[Unit]
Description=SSH key agent
[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
[Install]
WantedBy=default.target
Then enable it:
systemctl --user enable --now ssh-agent.service
Consider using the keychain wrapper for better management:
sudo apt install keychain
# Add to ~/.bashrc
eval $(keychain --eval --agents ssh id_rsa)
Keychain will prompt for your passphrase only once per session and maintain the agent between logins.
If things go wrong:
# Check if agent is running
ps aux | grep ssh-agent
# List loaded keys
ssh-add -l
# Kill existing agent
pkill ssh-agent
Many developers stumble when trying to automate SSH key management during remote sessions. The naive approach of putting these commands in .bashrc fails because:
# This creates an infinite loop of bash sessions
ssh-agent /bin/bash
ssh-add ~/.ssh/id_rsa
The correct way involves checking for existing SSH agent and only starting one when needed:
# Add to ~/.bash_profile
if [ -z "$SSH_AUTH_SOCK" ]; then
# Start ssh-agent and set environment variables
eval "$(ssh-agent -s)"
# Add keys only if running interactively
if [ -n "$PS1" ]; then
ssh-add ~/.ssh/id_rsa
fi
fi
For better security when jumping between servers:
# ~/.ssh/config
Host *
AddKeysToAgent yes
IdentityFile ~/.ssh/id_rsa
ForwardAgent yes
When working with different repositories/services:
ssh-add ~/.ssh/id_rsa_work
ssh-add ~/.ssh/id_rsa_personal
Debug agent status with:
ssh-add -l
echo $SSH_AUTH_SOCK
ps aux | grep ssh-agent