A service can be listening on a Linux server and still be unreachable from your laptop. The quickest way to diagnose a port is to check both sides of that distinction: what the server has bound locally, and whether a client can connect over the network.
Start with ss
On Ubuntu and most current Linux distributions, use ss to inspect sockets:
ss -tuln
The options mean:
-
-t: TCP sockets -
-u: UDP sockets -
-l: listening TCP sockets and unconnected UDP sockets -
-n: numeric addresses and port numbers
Example output might look like this:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 127.0.0.1:631 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
Focus on Local Address:Port: it shows the address and port the socket is bound to. For a TCP-only view, use ss -tln; for UDP, use ss -uln.
If you want to understand the options and other useful filters, see this practical reference to the Linux ss command.
Find the service using a port
Add -p to request process information:
sudo ss -tulpn
Root privileges matter for the process details: without sudo, you may see socket and port information but not the process name or PID for sockets owned by other users.
To check one port, use a port filter instead of grep:
sudo ss -tulpn sport = :2222
Replace 2222 with the port you care about. If there’s no output, no matching socket is listening on that port. Filtering directly avoids accidental matches—for example, searching for :22 can also match :2200.
For a quick check that also identifies the owner, lsof is another option:
sudo lsof -i :2222
No output means lsof found no matching socket. If a service should be listening but neither command shows it, check whether the service is running and configured for the port you expect.
Read the bind address before changing a firewall
The address a service binds to determines which interfaces can accept connections:
-
127.0.0.1and::1are loopback addresses. The service is limited to local connections. -
0.0.0.0listens on all configured IPv4 addresses. -
::listens on IPv6 interfaces; whether that also accepts IPv4 can depend on the system and socket configuration.
A wildcard bind does not guarantee that another machine can connect. It only means the service isn’t restricted to loopback. A host firewall, cloud security rule, router, NAT, or routing issue can still block traffic.
This distinction helps avoid a common mistake: opening a firewall rule for a service that only listens on 127.0.0.1. In that situation, the service’s bind configuration is the first thing to investigate. If the listener is on a network interface but connections still fail, then examine the path between client and server.
Test from the client’s network
To check whether a TCP port is reachable, run nc from the machine that needs to connect—not from the server itself:
nc -zv SERVER_IP 22
-z asks nc to check the connection without sending application data, and -v prints the result. A successful connection means the TCP port was reachable from that client at that moment. It does not prove that an SSH login will succeed or that the application is healthy.
A refusal or timeout means the connection did not succeed, but doesn’t identify the exact cause. Check whether a service is listening, then investigate the bind address, firewall, routing, NAT, and any cloud firewall or security-group rules. A firewall may be the blocker; on Ubuntu, the UFW port rules guide explains how to allow traffic and verify the rule.
For an actual SSH connection test, use the SSH client:
ssh -v -p 22 USER@SERVER_IP
Replace the port if the server uses a nonstandard one. The verbose output can help distinguish a network connection problem from a later authentication problem.
UDP needs extra care. Unlike TCP, it has no connection handshake, so a simple nc check is weaker evidence: no response doesn’t necessarily mean a service is listening. When it matters, confirm with a request appropriate to the UDP protocol.
A quick troubleshooting path
-
No matching entry in
ss: Check the service status and its configured port. -
Listener is on
127.0.0.1or::1: Check the service’s bind or listen-address setting. - Listener uses a wildcard or network address, but remote TCP tests fail: Investigate firewall rules, routing, NAT, cloud rules, and interface or address-family mismatches.
- TCP test succeeds but the application fails: The port is reachable; check the application protocol, service configuration, and authentication separately.
ss answers what is listening on the Linux machine. A test from the intended client answers whether that client can reach it. Using both gives you a much clearer diagnosis than treating “open port” as a single state.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.
Top comments (0)