When a service won't accept connections, or you're hardening a server and want to know exactly what is exposed, the first question is always the same: which ports are actually open, and what is listening on them? Linux gives you several tools for this, and they answer slightly different questions. This guide walks through the four you'll reach for most often.
What an "open port" really means
There are two different ideas people lump together as "open":
A listening socket — a process on the machine is bound to a port and waiting for connections (for example nginx on port 443).
A port reachable from outside — the listening socket is also allowed through any firewall and reachable across the network.
A port can be listening locally but still blocked by a firewall, so it looks closed from another machine. Keep that distinction in mind — it explains most "but the service is running!" confusion.
1. ss — the modern standard
ss (socket statistics) has replaced netstat on most distributions. It is fast and ships with the iproute2 package. The flags you'll use almost every time:
ss -tulnpReading the flags: -t TCP, -u UDP, -l only listening sockets, -n show numeric ports (don't resolve names), -p show the owning process (needs sudo to see processes you don't own).
To check a single port, pipe through grep or use a filter:
ss -tulnp | grep ':443'
ss -tlnp 'sport = :22'If a port shows 0.0.0.0 (or [::] for IPv6) it is listening on all interfaces — potentially reachable from the network. If it shows 127.0.0.1 it is bound to localhost only and not exposed externally. That single detail is one of the most useful things to check when securing a server.
2. lsof — which process owns a port
When you just need to know "what is using port 8080?", lsof is the most direct answer:
sudo lsof -i :8080
sudo lsof -iTCP -sTCP:LISTEN -P -nThe second command lists every TCP socket in the LISTEN state with numeric ports and addresses. This is the fastest way to track down a process you need to stop before another service can bind to the same port.
3. netstat — the classic
netstat is older and may not be installed by default (it lives in the net-tools package), but you'll still see it everywhere in documentation:
sudo netstat -tulnpThe flags mirror ss almost exactly, which is no accident — ss was designed as a drop-in replacement. If you're writing new scripts, prefer ss; if you're following an old guide, netstat will still work once installed.
4. nmap — scanning from the outside
Everything above checks ports from the machine itself. To see what is actually reachable across the network — the view an attacker or a remote client gets — scan from a different machine with nmap:
nmap -p 1-1000 192.168.1.50
nmap -sV 192.168.1.50The -sV flag attempts to identify the service and version behind each open port. Only scan hosts you own or have explicit permission to test — port scanning other people's systems can be against the law and against most providers' terms.
Listening locally vs. allowed through the firewall
If ss shows a port listening on 0.0.0.0 but a remote nmap reports it filtered or closed, a firewall is blocking it. Check your rules:
sudo ufw status
sudo iptables -L -nThis combination — confirm the service is listening locally with ss, then confirm it's reachable with nmap, then check the firewall if the two disagree — will diagnose the large majority of connectivity problems.
Quick reference
What's listening on this box? →
ss -tulnpWhat process owns a port? →
sudo lsof -i :PORTWhat's reachable from outside? →
nmapfrom another machineWhy is it blocked? → check
ufw/iptables
Keep these four in your toolkit and you'll be able to answer almost any "is this port open?" question with confidence.
