Skip to content

Listening Ports

A listening port is a door. Every one of them is a program waiting for connections from the network, and each is either something the README requires, something Linux needs, or something that shouldn't be there.

List them

sudo ss -tulpn

-t TCP, -u UDP, -l listening only, -p the process, -n numbers instead of names. The columns that matter are Local Address:Port and the process at the end.

Local Address Meaning
0.0.0.0:22 or *:22 Listening on every interface; reachable from the network
127.0.0.1:3306 Localhost only; not reachable from outside. Fine for a database the web server on the same machine uses.
[::]:80 Every IPv6 interface (and usually IPv4 too)

Ports you'll recognize

Port Service Keep if
22 SSH (sshd) README says remote administration; harden it either way
53 DNS (systemd-resolved on 127.0.0.53 is normal; named on 0.0.0.0 is a DNS server) README says DNS server
80, 443 Apache or nginx README says web server
21 vsftpd or proftpd README says FTP server
25 Postfix or exim README says mail server
139, 445 Samba README says file sharing
3306, 5432 MySQL, PostgreSQL README says database; bind to 127.0.0.1 unless remote clients are named
631 CUPS printing Usually not needed; normally listens on localhost only
5900 VNC Rarely legitimate
4444, 1337, 31337, 6667, high odd ports Backdoors, IRC bots, reverse shells Never; find the process

From port to program

The users:(("name",pid=1234,...)) column names the process. Find where it lives and how it starts:

sudo ss -tulpn | grep 4444
ps -fp 1234
sudo ls -l /proc/1234/exe
systemctl status 1234

systemctl status <pid> tells you which service or unit started it, which is what you need to stop it for good (Services). A process whose executable is in /tmp, /dev/shm, or a home directory is malware (Malware and Persistence).

Verify

sudo ss -tulpn | grep -v '127.0.0' 

Every remaining line is a service the README names, or sshd. This is the benchmark's "only approved services are listening" check (CIS 2.1.23), and it's the one that catches whatever the service list missed.

Example

ss -tulpn shows 0.0.0.0:22 sshd, 0.0.0.0:80 apache2, 0.0.0.0:3306 mysqld, and 0.0.0.0:4444 python3. README: web server with a local database, administered over SSH. Apache and SSH stay and get hardened. MySQL gets bound to 127.0.0.1 (MySQL). The python3 on 4444 runs /tmp/.x/server.py; kill it, delete the file, and find what starts it.

Try it

  1. Run ss -tulpn and account for every line. Start nc -l 4444, find it, kill it by PID.
  2. Bind a service to 127.0.0.1 and confirm it disappears from the network-facing list.

Build it

A ports.sh that prints ss -tulpn without the localhost lines, one row per port with the process name. Run before and after hardening and diff the two.

Next

Services