Understanding Network Ports
What Is a Network Port in Simple Terms
If an IP address is like a building's street address, a port is the apartment number inside. Two services on the same server can both be reached at 10.0.1.50 — but nginx on port 80 and PostgreSQL on port 5432 are completely separate services on separate ports.
When you type https://razorpay.com, your browser connects to Razorpay's server IP on port 443 (HTTPS). The server knows which service to route the connection to because the port number tells it.
How It Works
+------------------------------------------+| Server at 10.0.1.50 || || Port 22 <- sshd (SSH connections) || Port 80 <- nginx (HTTP traffic) || Port 443 <- nginx (HTTPS traffic) || Port 4000 <- payment-api (Node.js app) || Port 5432 <- postgresql (database) || Port 6379 <- redis (cache) |+------------------------------------------+ Incoming connection: Source: 203.0.113.45:52341 (client IP:ephemeral port) Dest: 10.0.1.50:443 (server IP:HTTPS port) Kernel routes to nginx based on destination portPort ranges:
0-1023 Well-known ports -- require root to bind 22=SSH, 80=HTTP, 443=HTTPS, 25=SMTP, 53=DNS 1024-49151 Registered ports -- standard for many apps 3306=MySQL, 5432=PostgreSQL, 6379=Redis 8080=HTTP alt, 9090=Prometheus 49152-65535 Ephemeral ports -- auto-assigned to clients When your browser makes a connection, the OS picks one of these as the source portPractical Commands
## Show all listening ports and which process owns themss -tulpn## -t TCP -u UDP -l listening -p process -n numeric ## Output:## Netid State Recv-Q Send-Q Local Address:Port Process## tcp LISTEN 0 128 0.0.0.0:22 users:(("sshd",pid=892))## tcp LISTEN 0 511 0.0.0.0:443 users:(("nginx",pid=1100))## tcp LISTEN 0 128 127.0.0.1:5432 users:(("postgres",pid=1350)) ## Find what is using a specific portss -tulpn | grep :8080sudo lsof -i :8080 ## Check if a remote port is opennc -zv 10.0.1.50 5432## Connection to 10.0.1.50 5432 port [tcp/postgresql] succeeded! ## Test connection with timeoutnc -zv -w3 10.0.1.50 5432 ## Check multiple portsfor port in 22 80 443 5432 6379; do nc -zv -w1 10.0.1.50 $port 2>&1 | grep -E 'succeeded|failed'done ## Port forwarding: access remote DB locallyssh -L 5433:localhost:5432 rahul@10.0.1.50## Now connect to localhost:5433 to reach 10.0.1.50:5432 ## Which process is using a port (requires root for other users' processes)sudo ss -tlpn | grep :443sudo fuser 443/tcpTroubleshooting
| Symptom | Command | What to Check |
|---|---|---|
| Port already in use error | `ss -tulpn | grep :PORT` |
| Service unreachable | nc -zv host port |
Firewall blocking or service not running |
| Cannot bind port < 1024 | Run as root or use authbind | Privileged port restriction |
| Connection refused | `ss -tulpn | grep :PORT` |
PLACEMENT PRO TIP**Tip:** `ss -tulpn` is faster and more accurate than `netstat -tulpn`. Both show the same information but `ss` queries the kernel directly without reading `/proc`. On a busy server with thousands of connections, `ss` is noticeably faster.
REMEMBER THIS**Remember:** A service bound to `127.0.0.1:5432` is only accessible from the local machine. A service bound to `0.0.0.0:5432` is accessible from any network interface. PostgreSQL defaults to `127.0.0.1` for security — changing it to `0.0.0.0` exposes the database to the network and requires firewall rules to be safe.