ssh: connect to host sshd port 22: Connection refused means the client reached the
machine but nothing there accepted a connection on port 22. Check on the server whether
anything listens on 22, and if nothing does, start the SSH server.
In this test the server machine was up and reachable, but sshd had never been
started. Starting it fixed the error without any change on the client.
The error
$ ssh -o BatchMode=yes dev@sshd true
ssh: connect to host sshd port 22: Connection refused
exit=255
Why it happens
The name sshd resolved (otherwise the message would be
Could not resolve hostname) and the connection attempt reached the server, which
answered that no program was listening on port 22. The refusal came before any login step, so
neither the user name nor the key played a part, and the client exited with code 255. On the server side the listening sockets
showed nothing on port 22, and the process list held only the shell and the container's
sleep:
$ ss -ltn
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 4096 127.0.0.11:44595 0.0.0.0:*
exit=0
$ ls /proc/[0-9]*/comm | xargs cat | sort -u
...
bash
sleep
xargs
exit=0
The one listener is at 127.0.0.11, the address the container's
/etc/resolv.conf names as its DNS server, not SSH. A container started from ubuntu:24.04 runs the command it
was given (here sleep infinity); installing openssh-server with apt
inside it did not leave an SSH server running.
The fix
$ /usr/sbin/sshd -t; echo config-ok
config-ok
exit=0
$ /usr/sbin/sshd
exit=0
$ ss -ltn
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 4096 127.0.0.11:44595 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
exit=0
sshd -t checks the configuration first. The server then listened on port 22 on
all interfaces, and the client's next connection went through:
$ ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new dev@sshd hostname
Warning: Permanently added 'sshd' (ED25519) to the list of known hosts.
eed60eb6a2a1
exit=0
The test accepted the host key of its own fresh container with
accept-new; on a real server, compare the fingerprint first, as shown in
SSH: Remote host identification has changed. Before this run a setup script had created the folder /run/sshd with
mkdir -p /run/sshd and host keys with ssh-keygen -A. This test started
the daemon by hand inside a container; an Ubuntu machine that runs systemd was not part of it.
How it was reproduced
Reproduced inside ubuntu:24.04 containers on Docker engine 29.9.3, client and
server on one user-defined Docker network, with OpenSSH_9.6p1 Ubuntu-3ubuntu13.20 installed by
apt-get install -y openssh-client openssh-server (and iproute2 for
ss on the server). The server container had a test user dev with the
client's public key; all keys were generated inside the containers. The containers were removed
afterwards.
Frequently asked
- What does ssh connect to host port 22 Connection refused mean?
- The host answered, but nothing on it accepted connections on port 22. In this test the SSH server had not been started.
- How do I check if sshd is listening on port 22?
- On the server run ss -ltn and look for a line with :22 in the Local Address column. Before the fix there was none; after starting sshd there were lines for 0.0.0.0:22 and [::]:22.
- Why is SSH refused in a Docker container with openssh-server installed?
- In this test installing the package did not start the server. The container ran only its own command until /usr/sbin/sshd was started by hand.
If the name does not resolve at all, see SSH: Could not resolve hostname. More decoded errors in the Fixes category.