Blank process column? That is the root question, and there is a way around it
ss -tlnp shows the owning process only for sockets you own unless you are root. Adding -e shows the systemd cgroup that owns every socket, root or not — which is how you find out that the mystery listener on port 3000 is docker-proxy for a container. That trick, /proc/net/tcp by hand, lsof and fuser for the PID, probing one port from inside and outside, and a CSV audit that alerts when a new listener appears are in the full guide: List Open Ports on Linux.
You don't know what your server is listening on until something that shouldn't be externally reachable is. A misconfigured service, a forgotten debug port, a package that auto-started on install — any of them can be sitting on an open port right now. This script maps all of them in one run.
What Does the Open Port Audit Script Look Like?
What each flag does
command -v ss— checks whetherssis available before calling it; falls back tonetstat. Hard-failing on missing tools would make the script useless on older systems.ss -tlnp—-tTCP,-llistening sockets only,-nnumeric ports (no DNS resolution — faster),-pshow process. Requires root for process names.ss -ulnp— same flags but-ufor UDP. DNS (53), NTP (123), and DHCP are expected. Anything else warrants a second look.lsof -i -P -n | grep LISTEN—-inetwork connections,-Pnumeric ports,-nskip hostname resolution. The process-name-first view makes it easier to identify services at a glance.$EUID -ne 0— warns without failing when run without root. The port list still works; only the process column is incomplete.
How Do I Read the ss Output?
The column that determines your exposure is Local Address:Port:
| Address prefix | Meaning |
|---|---|
0.0.0.0:PORT | Listens on all IPv4 interfaces — externally reachable |
:::PORT | Listens on all IPv6 interfaces — may accept IPv4 too |
127.0.0.1:PORT | Localhost only — not reachable from outside |
::1:PORT | IPv6 loopback — localhost only |
Any port in 0.0.0.0 or ::: that you cannot name and justify should be firewalled before the machine is internet-facing.
What Are the Common Variations?
Check one specific port:
Show only ports bound to all interfaces (externally reachable):
Check whether a port is open on a remote host:
How Do I Automate Open Port Monitoring?
Run weekly and diff the output to catch newly opened ports:
New ports appearing between audits
A package update, a misconfigured service, or a developer leaving a debug endpoint running can open a new port without any explicit firewall change. Weekly diffing catches this. If you find an unrecognized LISTEN port, cross-reference the process name against the kill process on port script to terminate it cleanly — SIGTERM first, SIGKILL only if the process ignores it. Pair the port audit with the file permissions security audit to cover both network exposure and filesystem exposure in a single review session.
An audit tells you what is listening. It does not tell you what to do at 3am when the answer is a service nobody remembers installing. The layer that turns a one-off audit into a standing control — locking so the weekly run cannot overlap, a log that proves it ran, an alert path that fails loudly instead of silently — is packaged as a reusable bashlib.sh and script template in The Production Bash Toolkit.
Frequently Asked Questions
What is the difference between ss and netstat?
ss reads from kernel socket tables directly — faster and maintained. netstat reads from /proc and was deprecated when iproute2 replaced net-tools on most distributions around 2016. The information is equivalent; only the format differs slightly.
Why do some entries show no process name?
Process names require root. A port held by a system service or a different user shows the address and port without the owning PID when run unprivileged. Run with sudo for complete output.
What does 0.0.0.0 vs 127.0.0.1 mean?
0.0.0.0 or ::: means the service accepts connections on all network interfaces — external traffic can reach it. 127.0.0.1 or ::1 means localhost only — only processes on the same machine can connect.
How do I check one specific port?
ss -tlnp | grep :8080 is the fastest method. lsof -i :8080 gives the same result with the process name more prominently displayed.
Should I worry about high-numbered ports?
Only LISTEN state entries matter here. Ephemeral ports (32768–60999) used for outgoing connections won't appear in LISTEN. Any LISTEN port you cannot explain and justify should be disabled or firewalled.
Part of the bash snippets collection
Related Scripts
- Kill Process on Port — lsof/ss discovery then SIGTERM with SIGKILL escalation to free a blocked port
- File Permissions Security Audit — find world-writable files and restore safe chmod 644/755 patterns
- SSH Key Setup Script — disable password-based SSH and switch to ed25519 key authentication