I won't go into specific cases in this blog post. This is a general guide on how to gather the necessary information that will help you to get your problem fixed.
In this post, I'll use a Linux client and server as a reference.
Get the verbose logging with the
-v flag. This normally is enough, but if you need even more information, use
You can find the logs for your SSH Server here
For troubleshooting sessions, it is recommended to increase the log level from the default
LogLevel INFO to
LogLevel DEBUG1 in your SSH server configuration
sshd_config. This will gives you all the necessary information. The following log levels are available:
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. Remember to restart the SSH server after changing this setting.
Another method is to check
journalctl if you use systemd. The logs should be available via
sudo journalctl -r -u ssh -u sshd.
As mentioned, there are many more, but the following list will give you a great starting point.
Hostname resolution #
error output ssh: Could not resolve hostname example.com: Name or service not known
This error message implies a problem with the DNS.
- check that the hostname is correct
- use the IP instead to test general connectivity
- check hostname resolution with
nslookupor other tools
Connection timeout #
Error output ssh: connect to host 10.10.10.10 port 22: connection timed out
This error tells you that you can't reach the server at all.
- Wrong destination IP:
- verify that the destination IP is correct
- can the client reach the destination? Check the routing table and use ICMP to double-check (ping and traceroute). Consider that ICMP sometimes is blocked by network firewalls!
- check the firewalls on the client, server, and network firewalls and make sure that the connection is allowed.
Connection refused #
Error output ssh: connect to host 10.10.10.10 port 22: connection refused
You can reach the server, but the server refuses the connection
- Wrong destination IP:
- verify that the destination IP is correct
- Listening SSH server port:
- is the default SSH port
22used? You can check it with the
Port 22in the
/etc/ssh/sshd_conffile on the server.
- is the server listening on the communicated port? Check on the server with
ss -tulpen | grep -i :22(use
netstaton older Linux versions) or use tools like
nmapto find the listening port (disclaimer: do not scan server you do not have the permission for)
- SSH server running:
- make sure that the SSH server is running, e.x. with
systemctl status sshd
Permission denied #
Permission denied (publickey,password)
Most likely a problem with the authentication.
- Wrong user credentials:
- make sure that you use the correct username and password or private key.
- as a side note: the login as
rootis often forbidden by common security measures.
- Missing permissions on the server:
- make sure that the user is allowed to log in via SSH.
- Wrong authentication method:
- most commonly, you'd log in via password or public key authentication.
- use the
-von the client to look for the following entry:
debug1: Authentications that can continue: password,publickey. This gives you information on what the server accepts.
- to force an authentication option on the client, you could use the
-oflag with SSH options. To force the login via password you could use something like this:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no email@example.com.
- if the desired option is unavailable, it must be configured on the server.
PasswordAuthentication yes. It is recommended to use public key authentication only.
- Wrong permission and/or ownership of SSH-related files:
- most SSH servers check how permissive e.x. the SSH keys are, and can deny access if they are too permissive.
sudo chmod 700 ~/.ssh sudo chmod 644 ~/.ssh/authorized_keys sudo chmod 644 ~/.ssh/known_hosts sudo chmod 644 ~/.ssh/config sudo chmod 600 ~/.ssh/nameofthekey # private key sudo chmod 644 ~/.ssh/nameofthekey.pub # public key
- Public key is missing in the
- the public key must be added to the a.m. file. A how-to can be found in this post.
- Private key no longer accepted on the server:
- some private keys are no longer considered secure, so the server could refuse the login with those keys.
- the best solution would be to update the SSH applications and generate new keys.
- a workaround would be to add the insecure key algorithm to the SSH server config to the accepted keys
SSH protocol version #
Protocol major versions differ: 1 vs. 2
The client and server do not work with the same protocol version. That said that you should only use SSHv2 and disable SSHv1.
- With the
-vflag you can see what the server offers:
debug1: Remote protocol version 2.0 [...]
With the flags
-2 you can decide whether the client should use SSH protocol version 1 or 2, respectivly.
- On the server, you can check the provided SSH protocol version in the configuration file:
grep Protocol /etc/ssh/sshd_config
Protocol 1# SSHv1
Protocol 2# SSHv2
Protocol 1,2# SSHv1 + SSHv2
If this option is missing, the mordern SSH server will use SSHv2 by default. It is worth adding it just to be sure and have it documented.
Failed host key verification #
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed.
Clearing the host key from
~/.ssh/known_hosts our use
ssh-keygen -R <ip-of-destination. You should be able to connect normally.
If you were not informed about any changes, please contact the SSH server administrator to verify that everything is still secure.
Unable to negotiate ciphers, MACs, or KexAlgorithms #
Unable to negotiate with 10.10.10.10: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
-vv flag on the client to output the necessary information. On the server, you can see the information with the
LogLevel DEBUG2 and check with the following commands what is accepted by the server.
Most commonly old SSH software is the reason for those errors. They still support old and insecure methods, which are no longer supported by modern applications.
There are workarounds with the
-o flag to set temporary options, but I am not too familiar with it.
ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 firstname.lastname@example.org
Connect without startup file #
This is not that common but there are ways to lock you out after changes to the startup files like
.profile, and so on. You simply can avoid loading those profile files with the following command.
ssh -t user@host bash --norc --noprofile
Handling SSH sessions with escape sequences #
SSH provides some escape sequences with which you can kill the session on the client.
Supported escape sequences: ~. - terminate connection (and any multiplexed sessions) ~B - send a BREAK to the remote system ~C - open a command line ~R - request rekey ~V/v - decrease/increase verbosity (LogLevel) ~^Z - suspend ssh ~# - list forwarded connections ~& - background ssh (when waiting for connections to terminate) ~? - this message ~~ - send the escape character by typing it twice (Note that escapes are only recognized immediately after newline.)
Side note: Start with a
RETURN and keep
SHIFT pressed while typing
~ and e.x.
? to get this message. This depends on your keyboard layout.
You can send the sequence through one or more SSH tunnel by adding
~ in front of the sequence.
E-Mail hello @itta vern. com
- 05.01.2023 SSH - run script or command at login
- 01.01.2023 Visual guide to SSH tunneling and port forwarding
- 14.12.2022 SSH - How to use public key authentication on Linux
- 22.11.2022 SSH server hardening