SSH Tunneling from A to C via B Using Private Key Forwarding Without Local Storage on Intermediate Host


2 views

When working with bastion hosts or jump servers, we often encounter scenarios where:

  • Host C exists in a private network only accessible through Host B
  • Security policies prevent storing private keys on intermediate hosts
  • Traditional SSH agent forwarding presents security risks

The modern approach utilizes SSH's ProxyJump directive combined with temporary key forwarding:

ssh -J user@B user@C -i ~/.ssh/id_rsa

For persistent configurations, add this to your ~/.ssh/config:

Host C
  HostName C.internal.example.com
  User remote_user
  IdentityFile ~/.ssh/id_rsa
  ProxyJump user@B.example.com

For environments requiring strict non-persistent key handling:

# On Host A:
mkfifo /tmp/ssh_key_fifo
cat ~/.ssh/id_rsa > /tmp/ssh_key_fifo &

# SSH command using the named pipe:
ssh -o "ProxyCommand=ssh -W %h:%p user@B" user@C -i /tmp/ssh_key_fifo

# Cleanup afterward:
rm /tmp/ssh_key_fifo
  • Always use encrypted RAM disks for temporary key storage when possible
  • Set appropriate file permissions (600 for private keys)
  • Consider using certificate-based authentication for better revocation control
  • Implement session timeouts with ServerAliveInterval

If encountering authentication failures:

ssh -vvv -J user@B user@C

Key permission problems often manifest with errors like:

Permissions 0644 for '/tmp/ssh_key_fifo' are too open

Fix with:

chmod 600 /tmp/ssh_key_fifo

When dealing with multi-hop SSH connections, we often face a security dilemma: how to access Host C through Host B without compromising private key security on intermediate hosts. The traditional approach of storing private keys on Host B creates unacceptable security risks.

The proper method uses SSH agent forwarding combined with ProxyJump:

ssh -J user@B user@C

But this requires proper setup:

  1. On Host A: Ensure ssh-agent is running and your key is added
  2. On Host B: Allow agent forwarding in sshd_config (AllowAgentForwarding yes)

Here's the full implementation:

# On Host A:
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa

# Then connect:
ssh -A -J userB@hostB userC@hostC

While convenient, agent forwarding has risks:

  • Any root user on Host B can access the forwarded agent
  • Use SSH certificates for better security
  • Consider ProxyCommand as an alternative

For more control, configure your ~/.ssh/config:

Host hostC
  HostName hostC.internal
  ProxyCommand ssh -W %h:%p userB@hostB
  IdentityFile ~/.ssh/id_rsa

Common issues and fixes:

  • Ensure HostB's sshd_config has 'AllowTcpForwarding yes'
  • Verify both hosts have your public key in authorized_keys
  • Check permissions: ~/.ssh should be 700, keys 600