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:
- Disabled Windows Firewall completely → transfers worked
- 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:
- Use port tunneling:
ssh -L 2121:localhost:21 user@gateway
- Switch to alternative ports (2222, 8022, etc.)
- 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:
- Firewall interference with non-standard ports
- TCP stack behavior differences for well-known ports
- 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:
- Impose different TCP window sizes
- Enable different QoS or traffic shaping
- 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 |