ByteScope

22

Port 22 · SSH

TCPIANA assignedRemote access

The port sshd listens on — and behind it `scp`, `rsync`, `git` over SSH, tunnels and SFTP, which is why one refused connection here breaks five different things at once.

Find what is using port 22

Run the line for your platform. Each one names the process holding the port and the address it bound to, which is usually the whole answer.

Check it from outside the machine

`nmap -Pn -p 22 host.example.com` reports what the port looks like from outside the machine, and `-Pn` treats the target as online so a host that drops pings still gets scanned. Nmap's definitions are precise: `open` means an application is actively accepting connections there; `closed` means the port is reachable and answered but nothing is listening on it, which is the shape of a stopped sshd; `filtered` means packet filtering kept the probe from reaching the port, so nmap cannot tell open from closed — and that is the same firewall that made your client hang instead of failing fast. `--reason` prints what actually came back, `syn-ack` for open and `conn-refused` for closed. `-sV` reads the version banner, which for SSH is the plaintext identification string the protocol sends before any encryption, something like `SSH-2.0-OpenSSH_9.6`. That string is also exactly what internet-wide scanners collect, so treat its contents as public. Scan only hosts you are responsible for.

Why a connection to 22 fails

What you seeWhat it means
ssh: connect to host host.example.com port 22: Connection refusedThe host is up and answered — its kernel sent a reset because no process holds port 22. sshd is stopped or failed to start, it is bound to an address that does not include the one you dialled, or it now listens on a different port after a config change. This failure is instant, and that speed is the useful signal: the network path works and only the service is missing. Run the probe for the platform on a console or another route into that machine.
ssh: connect to host host.example.com port 22: Connection timed outThe opposite diagnosis, and the reason the two are worth telling apart. Nothing came back at all: a firewall, a cloud security group or a network ACL is dropping the SYN silently, or you are dialling an address that no longer belongs to that machine. macOS phrases the same thing as `Operation timed out`. The tens of seconds you waited are the giveaway — a refusal returns immediately, a drop makes you sit through the connect timeout. Confirm with `nmap --reason`: `filtered` is the drop.
Permission denied (publickey).TCP, the port and the daemon are all fine — you reached authentication and it failed, and the message names the only method the server was willing to try. Work in order. Run `ssh -v` and read the `Offering public key` lines to see which key the client actually sent: an agent holding many keys can exhaust the server's attempt limit before it reaches the right one, so pin it with `-i` and `IdentitiesOnly=yes`. Then check the server side, where the key must sit in that account's `~/.ssh/authorized_keys`. OpenSSH's `StrictModes` defaults to yes, so a group- or world-writable home directory, `.ssh` or `authorized_keys` makes sshd ignore the file without telling the client anything — `~/.ssh` at 700 and `authorized_keys` at 600, owned by that user. The server log states the real reason in one line; the client never will.
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! ... Host key verification failed.The key the server presented is not the one recorded for that name in `known_hosts`, and this is the one error where the reflex answer is the wrong one. Do not start with `ssh-keygen -R`: that deletes the only record you have of what the host used to be. There are innocent causes — the machine was rebuilt, a cloud address was released and reassigned to somebody else's instance, the name now resolves to a different backend, or you are reaching a different host through a forwarded port — and one that is not, which is somebody sitting between you and the server. Establish which first: compare the fingerprint ssh printed against one taken on the console with `ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key`, or against the fingerprint in the instance's boot log. `ssh-keygen -F host` shows the stored entry and where it lives. Only once the new fingerprint is confirmed does `ssh-keygen -R host` become the right command.
error: Bind to port 22 on 0.0.0.0 failed: Address already in use.sshd cannot start because something already holds the socket. Usually the old sshd is still running — a restart that raced its own shutdown, or a hand-built install competing with the packaged service — and sometimes a socket unit holds 22 while you also start the service unit. Name the owner with the probe above rather than guessing, and never stop the running sshd from inside a session that depends on it without a console or a second way in.
ssh_exchange_identification: Connection closed by remote hostThe TCP connection succeeded and sshd hung up before the protocol banner, so the port, the route and the firewall are all fine. The usual causes are a ban on your source address from fail2ban or an equivalent, `MaxStartups` shedding connections while the machine is under load or out of file descriptors, and an access rule such as `AllowUsers`, `DenyUsers` or a TCP wrappers entry. This is a server-side decision about you, not a network fault, and the server's log says which.

What runs on port 22

IANA assigns 22 to `ssh`, the Secure Shell protocol, over TCP, UDP and SCTP; in practice only TCP is used. A single listener on this port carries much more than an interactive shell: `scp`, `rsync` run over SSH, `git clone git@host:repo`, `ssh -L` and `-D` tunnels, `ProxyJump` bastion hops, and the SFTP subsystem — which is all that SFTP is, and which has nothing whatsoever to do with FTP on port 21. OpenSSH's documented default is `Port 22` in `sshd_config`, and `ListenAddress` decides which interfaces it binds; both directives may appear more than once, so a server can legitimately answer on 22 and on a second port at the same time. Before you go hunting for a process, know that several distributions now ship a systemd socket unit for SSH: where `ssh.socket` is the enabled unit, the process holding port 22 is `systemd` and an `sshd` only exists once a connection arrives. That is normal, and it is not evidence that something else took the port. Moving SSH off 22 is also more than one line. Change `Port` in `sshd_config`, open the new port in the host firewall, and on a SELinux system register it as well with `semanage port -a -t ssh_port_t -p tcp 2222` — skip that last step and sshd starts, logs a bind failure, and you are locked out of a machine that looks perfectly healthy from every other angle. Always test a new port from a second session while the first one is still open.

Should port 22 face the internet?

Port 22 is one of the few management ports it is defensible to expose, because the transport is encrypted and the client checks the server's host key before it sends anything secret. That is not the same as safe. A listener on 22 is discovered within hours and then receives a constant, dull stream of credential guesses against `root`, `admin`, `ubuntu`, `git` and a few hundred other names. The controls that change the outcome are: keys only, with `PasswordAuthentication no` — OpenSSH's own documented default for that option is `yes` and distributions override it in both directions, so read the running configuration instead of assuming; `PermitRootLogin` at `prohibit-password`, which is the documented default, or `no`; and a rate limiter such as fail2ban, which bans a source address after a handful of failures and mostly buys you readable logs. Moving the daemon to a high port cuts the noise dramatically and cuts the risk barely at all, because a targeted scan finds it in seconds. The reductions that count are restricting source addresses at the firewall, putting the whole fleet behind one bastion reached with `ProxyJump` so only that host answers on 22, or requiring a VPN first. Whichever you pick, verify it from a second session that is already logged in — every lockout starts with a change tested only by reconnecting.

Service
SSH
Transport
TCP
Registry
IANA assigned
Category
Remote access

Tools on this site

All of these run in your browser — nothing is uploaded.

Related ports

Ports people usually end up checking in the same session as 22.

Frequently asked questions

Why does the command show nothing when the port is clearly in use?

Almost always permissions. lsof and ss list the socket but hide the owning process when it belongs to another user, so a server started by a system account, by a container runtime or by launchd shows up as an anonymous listener until you re-run the command with sudo. On Windows the opposite happens: netstat shows nothing at all, yet a bind still fails, which means the port sits inside a range that Hyper-V, WSL2 or Docker Desktop reserved at boot.

Is it safe to kill whatever is holding the port?

Look at what it is first. An orphaned dev server is safe to kill; a database with a write in flight is not, and neither is a system service that something else depends on. If the owner is a container, stop the container instead — killing the process the host sees only makes the runtime restart it. When the process is something you need, moving your own service to another port is the faster fix.

Why can I reach the port locally but not from another machine?

The listener bound to 127.0.0.1 rather than 0.0.0.0. The probes on every page print the bound address next to the process for exactly this reason: a loopback bind is reachable from the machine itself and from nowhere else, no matter how the firewall is configured. Many frameworks made that the default deliberately, so it is usually a flag rather than a bug. If the address is already 0.0.0.0 and it still fails, the next suspect is a host firewall or a cloud security group.

Does moving a service to an unusual port make it safer?

Barely. Internet-wide scanners sweep the whole port range continuously, so an unusual number buys hours, not safety, and it costs you every colleague who now has to remember it. It does cut the noise in your logs from opportunistic scans of the default port, which is a real if modest benefit. Authentication, a firewall that restricts source addresses, and not exposing the service at all are the measures that actually change the outcome.

Still stuck on port 22? browse every port in the reference — or go back to the failure message you actually got, above.