Troubleshooting SSH Bastion Host Connection: Fixing “stdio forwarding failed” Error


2 views

When attempting to establish an SSH connection through an AWS bastion host, you might encounter the frustrating "stdio forwarding failed" error followed by "Connection closed by remote host". This typically occurs during the ProxyCommand execution phase of your SSH configuration.

Let's analyze the reported SSH config:

# Bastion Host
Host bastion
User ec2-user
Hostname XX.XX.XX.XXX
IdentityFile ~/.ssh/keys/bastion.pem

# EC2 Instance
Host 172.*
User ec2-user
IdentityFile ~/.ssh/keys/bastion.pem
ProxyCommand ssh bastion -W %h:%p

The error suggests several potential issues:

  1. Key file permissions: The debug output shows SSH can't read the identity file properly
  2. Network connectivity: The "Connection timed out" indicates network-level issues
  3. Security group restrictions: The bastion might not allow outbound connections

1. Verify Key File Permissions:

chmod 600 ~/.ssh/keys/bastion.pem

2. Test Basic Bastion Connectivity:

ssh -i ~/.ssh/keys/bastion.pem ec2-user@XX.XX.XX.XXX

3. Alternative ProxyCommand Syntax:

Try this more explicit version in your config:

ProxyCommand ssh -i ~/.ssh/keys/bastion.pem ec2-user@XX.XX.XX.XXX -W %h:%p

For persistent issues, add these debugging flags:

ssh -vvv 172.xx.x.xx

Check AWS security groups for:

  • Bastion inbound: Port 22 from your IP
  • Bastion outbound: Port 22 to private subnet
  • Private instance: Port 22 from bastion security group

Some users find success with netcat-based forwarding:

Host 172.*
  ProxyCommand ssh bastion nc %h %p

Or using SSH jump host syntax (OpenSSH 7.3+):

ssh -J bastion ec2-user@172.xx.x.xx

Remember that different AWS instance types might require different approaches based on their network configuration.


When configuring SSH access through an AWS bastion host, the "stdio forwarding failed" error typically indicates a breakdown in the ProxyCommand communication between your local machine and the target EC2 instance. The verbose output shows two critical failure points:

channel 0: open failed: connect failed: Connection timed out
stdio forwarding failed
ssh_exchange_identification: Connection closed by remote host

Before diving into solutions, let's verify some fundamental requirements:

# Verify bastion connectivity
ssh -i ~/.ssh/keys/bastion.pem ec2-user@XX.XX.XX.XXX

# Test direct connection to target (from bastion)
ssh -i ~/.ssh/keys/bastion.pem ec2-user@172.xx.x.xx

The original configuration has several potential improvement areas:

# Improved bastion host configuration
Host bastion-host
  HostName XX.XX.XX.XXX
  User ec2-user
  IdentityFile ~/.ssh/keys/bastion.pem
  ForwardAgent yes
  ControlMaster auto
  ControlPath ~/.ssh/control-%r@%h:%p
  ControlPersist 10m

# Target instances configuration
Host 172.*
  User ec2-user
  IdentityFile ~/.ssh/keys/target.pem  # Different key for targets
  ProxyCommand ssh -W %h:%p bastion-host
  ServerAliveInterval 60
  TCPKeepAlive yes

1. Network Connectivity: Verify security group rules allow SSH traffic (port 22) from the bastion to target instances.

2. Key Permissions: Ensure proper permissions:

chmod 600 ~/.ssh/keys/bastion.pem
chmod 700 ~/.ssh/keys/

3. SSH Agent Forwarding: Consider adding these to your ~/.ssh/config:

AddKeysToAgent yes
UseKeychain yes

If the -W flag method fails, try these alternatives:

# Using netcat
ProxyCommand ssh bastion-host nc %h %p

# Using SSH jump host syntax (OpenSSH 7.3+)
ssh -J bastion-host ec2-user@172.xx.x.xx

From the bastion host, verify routing:

# Check route to target
ip route get 172.xx.x.xx

# Test basic connectivity
ping -c 4 172.xx.x.xx
telnet 172.xx.x.xx 22

For complex environments, consider multiplexing:

Host *
  ControlMaster auto
  ControlPath ~/.ssh/control-%r@%h:%p
  ControlPersist 1h