Listing open ports on Linux surfaces which services are reachable over the network, which is essential for hardening firewalls, validating service configuration, and detecting unexpected listeners. The ss utility from the iproute2 suite provides a fast, modern replacement for legacy netstat and reads socket information directly from the kernel.
The ss command queries the kernel’s netlink interface and can display sockets filtered by protocol, address family, state, address, and port. Options such as -t for TCP, -u for UDP, -l for listening sockets, and -n for numeric addresses control which sockets appear and how they are formatted. Additional flags like -p can annotate sockets with the owning process and PID, which simplifies tracing ports back to services.
Running ss without elevated permissions hides process details for sockets owned by other users, and some distributions restrict access to detailed socket metadata. Invoking sudo ss exposes full connection information but may reveal sensitive IP addresses, hostnames, and process paths, so access should be limited to trusted administrators. In virtualized or containerized environments, network namespaces, bridges, and firewall rules affect visibility, so interpreting ss output correctly requires awareness of the system’s network topology.
$ whoami user
Running with sudo privileges reveals process and user columns for sockets owned by other accounts.
$ ss -tuln 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:* udp UNCONN 0 0 127.0.0.54:53 0.0.0.0:* udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* udp UNCONN 0 0 192.0.2.40%eth0:68 0.0.0.0:* tcp LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* tcp LISTEN 0 5 0.0.0.0:8888 0.0.0.0:* tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* tcp LISTEN 0 5 0.0.0.0:8000 0.0.0.0:* tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* tcp LISTEN 0 4096 [::]:22 [::]:*
Options -t and -u restrict output to TCP and UDP, -l limits results to listening sockets, and -n disables DNS and service-name lookups for speed.
$ sudo ss -tulnp
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=9191,fd=3))
udp UNCONN 0 0 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=8515,fd=16))
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=8515,fd=14))
udp UNCONN 0 0 192.0.2.40%eth0:68 0.0.0.0:* users:(("systemd-network",pid=529,fd=18))
tcp LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=8515,fd=17))
tcp LISTEN 0 5 0.0.0.0:8888 0.0.0.0:* users:(("python3",pid=9190,fd=3))
tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=2952,fd=3),("systemd",pid=1,fd=129))
tcp LISTEN 0 5 0.0.0.0:8000 0.0.0.0:* users:(("python3",pid=9189,fd=3))
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=8515,fd=15))
tcp LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=2952,fd=4),("systemd",pid=1,fd=130))
Command ss -p reveals executable details and PIDs, which may expose sensitive process information that should not be shared from production systems.
$ ss -tan State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* LISTEN 0 5 0.0.0.0:8888 0.0.0.0:* LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* LISTEN 0 5 0.0.0.0:8000 0.0.0.0:* LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* FIN-WAIT-1 0 2512792 127.0.0.1:8000 127.0.0.1:59758 ESTAB 0 0 192.0.2.40:22 203.0.113.10:49829 ESTAB 2459753 0 127.0.0.1:59758 127.0.0.1:8000 ESTAB 0 0 192.0.2.40:22 203.0.113.10:52373 LISTEN 0 4096 [::]:22 [::]:*
Omitting -l shows both listening and non-listening sockets, useful for observing active client and server connections.
$ ss -tuln 'sport = :22' Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* tcp LISTEN 0 4096 [::]:22 [::]:*
Filters support expressions like sport = :PORT or dport = :PORT and can be combined with other options to narrow results.
$ sudo ss -tulnp | grep python3
tcp LISTEN 0 5 0.0.0.0:8888 0.0.0.0:* users:(("python3",pid=9190,fd=3))
tcp LISTEN 0 5 0.0.0.0:8000 0.0.0.0:* users:(("python3",pid=9189,fd=3))
Combining ss with tools such as grep or awk produces focused views tailored to individual services.
$ ss -tuln4 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:* udp UNCONN 0 0 127.0.0.54:53 0.0.0.0:* udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* udp UNCONN 0 0 192.0.2.40%eth0:68 0.0.0.0:* tcp LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* tcp LISTEN 0 5 0.0.0.0:8888 0.0.0.0:* tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* tcp LISTEN 0 5 0.0.0.0:8000 0.0.0.0:* tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* $ ss -tuln6 Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess tcp LISTEN 0 4096 [::]:22 [::]:*
Options -4 and -6 constrain results to IPv4 and IPv6 sockets respectively, clarifying whether a service listens on one or both families.
$ sudo ss -tulnp > open-ports-$(date +%F).txt
Stored snapshots may contain IP addresses, hostnames, and process identifiers that should be treated as sensitive operational data.
$ ss -tuln 'sport = :8000' Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
Absence of matching lines indicates no process is listening on the specified port within the inspected network namespace.