Diagnosing and Fixing “Connection Reset by Peer” in SSH/SFTP Transfers on Non-Standard Ports


2 views

After days of troubleshooting, I discovered a bizarre scenario where SSH/SFTP connections would consistently fail after transferring exactly 48KB of data when using port 21, while working perfectly on port 22. The error message:

Read error from remote host: Connection reset by peer

This manifested in multiple ways:

  • SFTP transfers failing mid-file
  • SSH sessions dying during cat operations
  • Even repeated ls -l commands would eventually trigger the disconnect

Through systematic testing, I verified:

# Working scenario
ssh -p 22 user@server  # No issues
cat large_file.sql     # Completes successfully

# Failing scenario  
ssh -p 21 user@server  # Connects fine
cat large_file.sql     # Dies after ~48KB

The problem was specific to my Windows XP workstation - other devices (MacBook, Linux boxes) worked fine with port 21.

Here's the smoking gun:

netsh firewall show portopening | find "21"
# Shows port 21 as "enabled" but still problematic

The solution emerged when I:

  1. Disabled Windows Firewall completely → transfers worked
  2. Re-enabled firewall but added explicit rules → continued working

Windows Firewall has special handling for port 21 (traditionally FTP) that interferes with SSH:

  • Stateful inspection treats port 21 traffic differently
  • SSH encryption triggers false positive as malicious traffic
  • The 48KB limit matches Windows' packet inspection buffer size

Option 1: Firewall Rule Modification

# Create dedicated rule for SSH on port 21
netsh advfirewall firewall add rule name="SSH Port 21" dir=in action=allow protocol=TCP localport=21

Option 2: SSH Configuration Tuning

# In /etc/ssh/sshd_config
ClientAliveInterval 30
ClientAliveCountMax 3
TCPKeepAlive yes

Option 3: Packet Size Limitation

# For PuTTY users, adjust packet size
# In Connection → SSH → Remote command:
ssh -o "ServerAliveInterval 30" -o "IPQoS=throughput" user@host

If firewall changes aren't possible:

  1. Use port tunneling: ssh -L 2121:localhost:21 user@gateway
  2. Switch to alternative ports (2222, 8022, etc.)
  3. Implement chunked transfers:
# For file transfers
split -b 40k largefile.sql
for chunk in x*; do scp -P 21 $chunk user@server:/tmp/; done

To confirm the fix works:

# Test with large packet transmission
dd if=/dev/zero bs=1024 count=100 | ssh -p 21 user@server "cat > /dev/null"

# Monitor firewall logs simultaneously
Get-EventLog -LogName "Windows Firewall with Advanced Security" -After (Get-Date).AddMinutes(-1)

When working with SSH file transfers on non-standard ports, you might encounter a frustrating scenario where connections consistently reset after transferring approximately 48KB of data. This behavior typically manifests as:

Read error from remote host [IP]: Connection reset by peer
debug1: do_cleanup

From the debugging logs, we can see the session establishes correctly but fails during data transfer. Key observations include:

  • Successful initial connection (authentication works)
  • Session creation completes (channel 0 allocated)
  • PTY allocation succeeds (/dev/pts/2 in this case)
  • Failure occurs during actual data transfer

The critical discovery was that this behavior only occurred when using port 21 for SSH, while port 22 worked perfectly. This points to either:

  1. Firewall interference with non-standard ports
  2. TCP stack behavior differences for well-known ports
  3. Application-layer inspection mechanisms

Testing methodology to isolate the issue:

# Test with standard port
ssh -p 22 user@server
cat largefile.txt  # Works

# Test with alternative port
ssh -p 21 user@server
cat largefile.txt  # Fails after ~48KB

Despite having port 21 explicitly allowed in Windows Firewall rules, the connection resets persisted. This suggests the firewall was performing deeper packet inspection for well-known service ports. The solution pattern:

  • Disable Windows Firewall (temporary solution)
  • Create more specific inbound/outbound rules
  • Modify firewall advanced settings

For permanent resolution, this PowerShell command adjusts firewall behavior:

New-NetFirewallRule -DisplayName "Allow Alternative SSH" -Direction Inbound -LocalPort 21 -Protocol TCP -Action Allow -Program "System" -Profile Any

When using port 21 (traditionally FTP), some systems may:

  1. Impose different TCP window sizes
  2. Enable different QoS or traffic shaping
  3. Trigger application-layer gateways

To diagnose these issues, consider these commands:

# Check TCP window scaling
cat /proc/sys/net/ipv4/tcp_window_scaling

# Verify MTU settings
ip link show

# Monitor TCP retransmits
ss -ti

If changing ports isn't feasible, consider these workarounds:

# Use compression to reduce packet counts
ssh -C -p 21 user@server

# Limit transfer chunk sizes
rsync --bwlimit=100 -avz -e 'ssh -p 21' src/ user@server:dest/

# Use different encryption cipher
ssh -c aes128-ctr -p 21 user@server

For system administrators, adjusting these sysctl parameters may help:

# Increase TCP buffer sizes
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# Disable TCP selective ACK
net.ipv4.tcp_sack = 0

When facing similar issues, verify these aspects:

Component Check
Firewall Rules for both ports 21 and 22
Router PAT/NAT configuration
SSH Server Port-specific config in sshd_config
Client MTU, TCP stack parameters
Network QoS or traffic shaping policies