Automated SSH-Agent Setup: How to Run ssh-agent and ssh-add on SSH Login


50 views

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