published
priority 11
20 min. 30 XP.
TCP Ports & Services. ss, netstat, lsof, nmap
Half of all NCAE debugging is 'is this port open and if so who has it?'. `ss` has replaced `netstat` on modern Linux; this lesson covers both plus the view-from-outside (nmap) and who-owns-what (lsof). Students will diagnose 80% of service issues from here.
Objectives
- List open TCP/UDP ports on the local system with `ss`
- Identify which PID owns a port
- Distinguish listening (server) vs established (client-in-use) connections
- Use `lsof` as a fallback when `ss` isn't available
- Use `nmap` to scan from outside. what the scoring engine sees
- Know the well-known ports for NCAE services without looking them up
Quick reference
| Command | Purpose |
|---|---|
| ss -tlnp | TCP listening ports with PID (modern) |
| ss -ulnp | UDP listening ports with PID |
| ss -tnp | Established TCP connections with PID |
| ss -tn 'dport = :445' | Show only connections to port 445 |
| ss -s | Summary by protocol (how many connections total) |
| netstat -tlnp | Older equivalent, still common |
| lsof -i :22 | What's bound to port 22 |
| lsof -i -P -n | All network files, numeric ports/IPs |
| lsof -p <PID> | All files a process has open |
| nmap -Pn -p 22,53,80,443,445,5432 <host> | Quick port scan of the NCAE-relevant ports |
| fuser -n tcp 80 | What process owns TCP port 80 |
Common pitfalls
- `ss -tlnp` needs root (or CAP_NET_ADMIN) to show PIDs. without, you get listings but no `users:` column
- Listening on `127.0.0.1` vs `0.0.0.0`. silent cause of 'port is open but nobody can connect'
- Using `netstat` on systems that don't have it installed (minimal containers). `ss` is in iproute2, more portable
- `nmap` without `-Pn` gives up if ICMP is blocked. always use `-Pn` for NCAE router scans
- Confusing listening (Recv-Q backlog) with established (actually in use) connections
How it works (walkthrough)
# Reading ss -tlnp output:
# State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
# LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=842,fd=3))
# LISTEN 0 511 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=1210,fd=7))
# Key insights from this output:
# sshd listens on 0.0.0.0:22 reachable from any interface
# postgres listens on 127.0.0.1:5432 ONLY localhost. external scoring fails
# fix: set listen_addresses='*' in postgresql.conf, then reload
# NCAE scored port cheat sheet (memorize):
# 22/tcp SSH service: sshd
# 53/udp DNS (query) service: named / bind9
# 53/tcp DNS (zone) service: named / bind9
# 80/tcp HTTP service: apache2 or nginx
# 443/tcp HTTPS service: apache2 or nginx
# 445/tcp SMB service: smbd
# 5432/tcp PostgreSQL service: postgresql
Skill drills
-
1. Command to list all listening TCP ports with PIDs?ss -tlnp
-
2. What does 127.0.0.1:5432 in a LISTEN line mean?Only localhost can connect. external clients fail
-
3. What's the UDP equivalent of ss -tlnp?ss -ulnp
-
4. nmap flag that skips ICMP host-discovery?-Pn
-
5. Which ports should be listening on a healthy NCAE server (beyond the scoring 7)?Usually none externally. audit anything else as suspicious
-
6. Tool to show which process holds a file handle?lsof