You attempt an SSH connection and immediately see:

bash
$ ssh user@server.example.com
Connection reset by 192.168.1.100 port 22

This error means the TCP connection was established but then abruptly terminated by the remote host. Unlike "connection refused" (nothing listening), "connection reset" means SSH started but something interrupted it.

Diagnose with Verbose Output

Run SSH with maximum verbosity to see where the reset occurs:

bash
ssh -vvv user@server.example.com 2>&1 | tee ssh_debug.log

Look for where the connection drops. If it resets immediately after the TCP handshake, the issue is likely firewall or TCP wrapper related. If it resets during key exchange, the issue might be MTU or cipher negotiation.

Check for TCP Wrappers

On the server, check if TCP wrappers are blocking the connection:

bash
cat /etc/hosts.deny

Look for lines blocking SSH:

bash
sshd: ALL EXCEPT 10.0.0.0/8
sshd: .example.com: DENY

Check the allow file:

bash
cat /etc/hosts.allow

Add your IP if needed:

bash
echo "sshd: $(echo $SSH_CONNECTION | awk '{print $1}')" | sudo tee -a /etc/hosts.allow

Or allow all SSH connections:

bash
echo "sshd: ALL" | sudo tee -a /etc/hosts.allow

Check Server Firewall

The firewall might be allowing the initial connection but dropping subsequent packets. Check iptables:

bash
sudo iptables -L -v -n --line-numbers

Look for rules that might be dropping ESTABLISHED connections:

bash
sudo iptables -L INPUT -v -n | grep -E "(DROP|REJECT)"

A properly configured firewall should allow established connections:

bash
sudo iptables -I INPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

For firewalld:

bash
sudo firewall-cmd --list-all

Ensure the correct zone is active and SSH is allowed:

bash
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

Investigate MTU Issues

MTU (Maximum Transmission Unit) problems cause mysterious resets during large data transfers like SSH key exchange. The server sends a large packet that gets dropped, and the connection dies.

Test with a smaller MTU:

bash
ssh -o "MTU=1200" user@server.example.com

On Linux, temporarily reduce the interface MTU:

bash
sudo ip link set eth0 mtu 1200

If this fixes the issue, you have an MTU problem. The permanent fix is to enable Path MTU Discovery or configure the correct MTU on your network interface.

Check your current MTU:

bash
ip link show eth0

On the server, enable PMTU in the kernel:

bash
sudo sysctl -w net.ipv4.tcp_mtu_probing=1

Make it permanent:

bash
echo "net.ipv4.tcp_mtu_probing = 1" | sudo tee -a /etc/sysctl.conf

Check SSHD Configuration

Certain SSHD configurations can cause connection resets. Check the main config:

bash
sudo grep -E "^(MaxStartups|MaxSessions|LoginGraceTime)" /etc/ssh/sshd_config

If MaxStartups is too low and you have many concurrent connections:

bash
MaxStartups 2

Increase it:

bash
sudo sed -i 's/^MaxStartups.*/MaxStartups 10:30:60/' /etc/ssh/sshd_config
sudo systemctl restart sshd

Check Server Logs

Examine SSHD logs for the reset reason:

bash
sudo journalctl -u sshd -f

Connect from another terminal and watch for messages:

bash
Apr  3 10:15:22 server sshd[12345]: Connection from 192.168.1.50 port 52341
Apr  3 10:15:22 server sshd[12345]: Connection closed by authenticating user user 192.168.1.50 port 52341 [preauth]

On systems using syslog:

bash
sudo tail -f /var/log/auth.log

Look for patterns like: - Connection closed by - Client or server closed - Did not receive identification string - Timeout during handshake - fatal: no hostkey alg - Key algorithm mismatch

Check for Fail2ban

Fail2ban might be blocking you after failed attempts:

bash
sudo fail2ban-client status sshd

Check if your IP is banned:

bash
sudo fail2ban-client status sshd | grep "Banned IP list"

Unban your IP:

bash
sudo fail2ban-client set sshd unbanip 192.168.1.50

Check the fail2ban logs:

bash
sudo tail -f /var/log/fail2ban.log

Check for Cloud Provider Security Groups

If the server is in AWS, Azure, or GCP, check the security group or network ACL rules. Cloud security groups act as firewalls and can cause resets.

In AWS, verify: - Security group allows inbound TCP 22 from your IP - Network ACLs aren't blocking the connection - No VPC flow logs showing rejected traffic

Check DNS Resolution Issues

Slow or failing DNS can cause connection resets during the authentication phase. On the server, disable DNS lookups:

bash
echo "UseDNS no" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd

This prevents SSHD from trying to resolve the client's hostname.

Test with Different Ciphers

Sometimes cipher negotiation fails. Try forcing a specific cipher:

bash
ssh -c aes256-ctr user@server.example.com

Or specify a key exchange algorithm:

bash
ssh -o KexAlgorithms=diffie-hellman-group14-sha1 user@server.example.com

If this works, update your SSH configuration to prefer working algorithms.

Check Keepalive Settings

If connections reset after idle periods, adjust keepalive:

On the client (~/.ssh/config):

bash
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

On the server (/etc/ssh/sshd_config):

bash
ClientAliveInterval 60
ClientAliveCountMax 3

Quick Resolution Path

  1. 1.Check TCP wrappers: /etc/hosts.deny and /etc/hosts.allow
  2. 2.Check firewall rules: iptables -L or firewall-cmd --list-all
  3. 3.Check fail2ban: fail2ban-client status sshd
  4. 4.Check server logs: journalctl -u sshd
  5. 5.Test with verbose SSH: ssh -vvv user@host
  6. 6.Check MTU if connection resets during heavy data transfer

Connection reset errors usually indicate a firewall or security software interrupting the connection. Start with TCP wrappers and firewall checks for the fastest resolution.