Updated: 11 October 2026 · Applies to: Ubuntu 26.04 (iproute2 6.19, net-tools 2.10, lsof 4.99, nmap 7.98, netcat-openbsd 1.234) and 24.04, Debian 13, AlmaLinux 10 (iproute 6.17, nmap 7.92, nmap-ncat); the same commands work on AlmaLinux 9 and Rocky Linux
To check open ports on Linux, run sudo ss -tulpn. It lists every TCP and UDP port a program is listening on, with the program’s name. Listening is only half the answer: to check whether a port is really open from the internet, test it from another computer with nc -zv SERVER_IP PORT or nmap SERVER_IP, because a firewall can block a port that the server listens on.
1. List listening ports with ss
sudo ss -tulpn
-t TCP, -u UDP, -l listening only, -p show the process, -n numbers instead of service names. ss comes with iproute2 (iproute on AlmaLinux and Rocky Linux), which is part of every standard server install. Lab example on Ubuntu 26.04 with three test listeners:
$ sudo ss -tulpn
Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
udp UNCONN 0 0 0.0.0.0:5353 0.0.0.0:* users:(("nc",pid=4335,fd=3))
tcp LISTEN 0 1 127.0.0.1:3306 0.0.0.0:* users:(("nc",pid=4334,fd=3))
tcp LISTEN 0 1 0.0.0.0:8080 0.0.0.0:* users:(("nc",pid=4333,fd=3))
Read the Local Address:Port column:
0.0.0.0:8080,[::]:8080or*:8080: listening on all addresses, so reachable from outside unless a firewall blocks it.127.0.0.1:3306or[::1]:3306: local only. Nobody outside the server can connect, which is what you want for a database.127.0.0.53%lo:53and127.0.0.54:53on Ubuntu: the local systemd-resolved DNS stub, also local only.
Run it with sudo. Without root, the Process column stays empty for programs that run as other users.
Check one port:
$ sudo ss -tlnp 'sport = :8080'
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 1 0.0.0.0:8080 0.0.0.0:* users:(("nc",pid=4333,fd=3))
No line under the header means nothing listens on that port. ss -tln | grep :8080 gives the same answer without root.
2. netstat: the older command
ss is the modern replacement for netstat. If you are used to netstat, the same flags work:
$ sudo netstat -tulpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 4334/nc tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 4333/nc udp 0 0 0.0.0.0:5353 0.0.0.0:* 4335/nc
netstat comes from the net-tools package, which minimal installs leave out. If you get command not found, see install net-tools or use ss.
3. lsof: ports by program and user
$ sudo lsof -nP -iTCP -sTCP:LISTEN COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nc 4333 root 3u IPv4 7483414 0t0 TCP *:8080 (LISTEN) nc 4334 root 3u IPv4 7483407 0t0 TCP 127.0.0.1:3306 (LISTEN)
sudo lsof -nP -i :8080 shows only one port, and sudo lsof -nP -iUDP the UDP sockets. It is in Ubuntu’s standard package set; elsewhere install it with sudo apt install lsof or sudo dnf install lsof. To go from a port to the service and stop it, see find which process is using a port.
4. Check if a port is open from another computer
Run these on a different machine (your PC or a second server), with the server’s public IP address. Ubuntu installs netcat by default; elsewhere use sudo apt install netcat-openbsd (Debian) or sudo dnf install nmap-ncat (AlmaLinux and Rocky Linux, where nc is Ncat).
nc -zv -w 3 203.0.113.10 8080
Lab results (netcat-openbsd, run against a test container), one for each case:
Connection to 127.0.0.1 8080 port [tcp/http-alt] succeeded! nc: connect to 127.0.0.1 port 9090 (tcp) failed: Connection refused nc: connect to 127.0.0.1 port 8081 (tcp) timed out: Operation now in progress
- succeeded: the port is open and reachable.
- Connection refused: the server answered, but nothing listens on that port.
- timed out: no answer at all. A firewall is dropping the traffic, or the address is wrong.
No netcat? Bash can test a TCP port by itself: timeout 3 bash -c '</dev/tcp/203.0.113.10/8080' && echo open || echo closed.
To check many ports at once, use nmap (sudo apt install nmap or sudo dnf install nmap). Lab example (shortened), where port 8081 was blocked by a firewall rule:
$ sudo nmap -p 22,80,3306,8080,8081 127.0.0.1 PORT STATE SERVICE 22/tcp closed ssh 80/tcp closed http 3306/tcp open mysql 8080/tcp open http-proxy 8081/tcp filtered blackice-icecap
open means reachable, closed means nothing listens, filtered means a firewall drops the packets. nmap SERVER_IP scans the 1,000 most common ports and nmap -p- SERVER_IP all 65,535 TCP ports. The SERVICE column is only nmap’s guess from the port number. UDP is harder: sudo nmap -sU -p 5353 reported open|filtered for a UDP port that was listening, because a UDP service often sends no reply. Scan only servers you own or may test.
Listening but not reachable?
- Check the address in
ss: a service on127.0.0.1is local only. Change its own listen or bind setting if it must be public. - Check the firewall. On Ubuntu,
sudo ufw show listeningputs both together: each public listening port with the UFW rules that affect it (in our test it skipped the port bound to 127.0.0.1):$ sudo ufw show listening tcp: 8080 * (nc.openbsd) [ 1] allow 8080/tcp
On AlmaLinux and Rocky Linux, runsudo firewall-cmd --list-all. - Test again from outside with
ncornmap.
Open, close or block a port
- Open a port on Ubuntu: open ports with UFW.
- Open a port on AlmaLinux, Rocky Linux and RHEL: open a port with firewalld.
- Close a port: stop the program with
sudo systemctl disable --now SERVICE, or block the port in the firewall. - Keep databases and admin tools on
127.0.0.1, for examplebind-address = 127.0.0.1for MariaDB and MySQL.
Official documentation: ss manual page and nmap reference guide.
Ucartz services for this topic
- KVM VPS hosting: NVMe SSD and full root access, with Free Basic Managed Support.
- Unmanaged dedicated servers: full root access and free IPMI KVM, with Free Basic Managed Support.
- Linux server management: hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.
