Introduction
SSH agent forwarding allows you to use your local SSH key on a remote server without copying the private key there. This is essential when connecting through a jump host (bastion server) to reach backend servers. When agent forwarding fails, the jump host authenticates fine but the backend server rejects the key with Permission denied (publickey) because the forwarded agent socket is not available or properly configured.
Symptoms
- SSH to jump host works, but SSH from jump host to backend fails
ssh-add -lon the jump host showsCould not open a connection to your authentication agentecho $SSH_AUTH_SOCKis empty on the jump hostssh -vshowsAgent forwarding disabledor noAuthAgentline- Backend server logs show no authentication attempt from forwarded agent
Common Causes
ForwardAgentnot enabled in ssh_config or sshd_config- Jump host sshd has
AllowAgentForwarding no - SSH_AUTH_SOCK environment variable not propagated through the connection chain
- Using
sudoon the jump host, which does not inherit the agent socket - SSH multiplexing (ControlMaster) interfering with agent forwarding
Step-by-Step Fix
- 1.Verify agent forwarding is enabled in your SSH config:
- 2.```bash
- 3.cat ~/.ssh/config
- 4.# Should contain:
- 5.Host jumphost
- 6.HostName jump.example.com
- 7.User admin
- 8.ForwardAgent yes
Host backend HostName backend.internal User deploy ProxyJump jumphost ForwardAgent yes ```
- 1.Verify sshd on the jump host allows agent forwarding:
- 2.```bash
- 3.# On the jump host
- 4.sudo grep -i "AllowAgentForwarding|allowagent" /etc/ssh/sshd_config
- 5.# Should be yes or not present (default is yes)
- 6.# If no, change it:
- 7.sudo sed -i 's/AllowAgentForwarding no/AllowAgentForwarding yes/' /etc/ssh/sshd_config
- 8.sudo systemctl restart sshd
- 9.
` - 10.Test agent forwarding step by step:
- 11.```bash
- 12.# Check agent is running locally
- 13.ssh-add -l
- 14.# Should list your keys
# Connect to jump host and verify agent is forwarded ssh jumphost "ssh-add -l" # Should list the same keys
# If that works, test full chain ssh backend "whoami" ```
- 1.Use ProxyJump instead of manual chaining (OpenSSH 7.3+):
- 2.```bash
- 3.# In ~/.ssh/config:
- 4.Host backend
- 5.HostName 10.0.1.50
- 6.User deploy
- 7.ProxyJump jumphost
- 8.ForwardAgent yes
# Then simply: ssh backend ```
- 1.Debug agent forwarding with verbose output:
- 2.```bash
- 3.ssh -v -A jumphost
- 4.# Look for: "Requesting authentication agent forwarding."
- 5.# And: "Authentication agent forwarding enabled."
# On the jump host, check the socket echo $SSH_AUTH_SOCK ls -la $SSH_AUTH_SOCK ```
- 1.Fix sudo not inheriting agent socket:
- 2.```bash
- 3.# On the jump host, configure sudo to preserve SSH_AUTH_SOCK
- 4.sudo visudo
- 5.# Add:
- 6.Defaults env_keep += "SSH_AUTH_SOCK"
- 7.
`
Prevention
- Use
ProxyJumpinstead of manual agent forwarding chains where possible - Disable agent forwarding on servers that do not need it (
AllowAgentForwarding no) - Consider using SSH certificates instead of agent forwarding for better security
- Test agent forwarding as part of jump host deployment validation
- Document the SSH connection chain in runbooks with expected agent forwarding behavior