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¶
- Run
ss -tulpnand account for every line. Startnc -l 4444, find it, kill it by PID. - Bind a service to
127.0.0.1and 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.