The Apartment Building Model
An IP address gets traffic to the right machine; a port gets it to the right program on that machine. Think of the IP as a building's street address and ports as apartment numbers, 1–65535. Your Proxmox host has one IP but serves the web UI on 8006, SSH on 22, and whatever else you've stacked on it — each a different apartment.
A socket is one live conversation: the combination of IP + port on both ends. 192.168.1.50:52814 → 192.168.1.100:8006 is you in the Proxmox UI. Your side uses a random high "ephemeral" port — that's why a server can hold thousands of simultaneous connections on a single listening port: every client pair is unique.
TCP vs UDP
Two transport protocols carry almost everything. TCP is a phone call: connection established first (the three-way handshake), every byte acknowledged, lost pieces re-sent, order guaranteed. UDP is a thrown paper airplane: no setup, no delivery guarantee, minimal overhead.
TCP → web (80/443), SSH (22), databases — correctness matters
UDP → DNS queries (53), DHCP (67/68), WireGuard (51820),
game/voice traffic — speed matters, a lost packet is no tragedy
# Note the port number alone isn't enough — 53/udp and 53/tcp
# are different doors. Firewall rules must name the protocol.Port Numbers Worth Memorizing
22 SSH 443 HTTPS 53 DNS 445 SMB (Windows/NAS shares) 67/68 DHCP 3306 MySQL / 5432 PostgreSQL 80 HTTP 8006 Proxmox web UI 123 NTP (time) 9090 Prometheus / 3000 Grafana # 0–1023: "well-known" — binding these requires root # 1024–49151: registered — where most apps live # 49152–65535: ephemeral — outbound connection source ports
What's Listening? ss and Friends
A port is only open if a program is listening on it. The modern tool is ss (netstat's replacement) — run it on any lab box and audit what you find:
sudo ss -tulpn → all listening ports + owning process # -t TCP -u UDP -l listening -p process -n numeric # Reading the Local Address column: 0.0.0.0:22 → listening on EVERY interface (reachable from LAN) 127.0.0.1:5432 → loopback only (this machine can reach it, LAN cannot) 192.168.1.120:80 → one specific interface only # Test reachability from another machine nc -zv 192.168.1.100 8006 → "succeeded" = open, listening nc -zv 192.168.1.100 3389 → "refused" = nothing listening there
That 0.0.0.0 vs 127.0.0.1 distinction is the single most useful security habit on this page: databases and internal APIs should bind loopback (or a specific internal IP), not every interface. If ss shows a service on 0.0.0.0 that only local apps use, you've found tomorrow's hardening task.
Debugging "Can't Connect" — In Order
# 1. Is the host even reachable? ping 192.168.1.100 # 2. Is anything listening on that port? (run ON the server) sudo ss -tulpn | grep 8006 # 3. Bound to the right interface? (127.0.0.1 = not reachable from LAN) # 4. Firewall in the way? (run ON the server) sudo ufw status verbose # or: sudo iptables -L -n # 5. Reachable from the client? nc -zv 192.168.1.100 8006 # "connection refused" = host reachable, nothing listening (steps 2-3) # timeout / hang = firewall dropping packets (step 4) or routing
Refused vs timeout is the diagnostic gold: refused means the network path is fine and the service is the problem; a silent timeout means something (usually a firewall) is eating your packets. That one distinction routes you to the right fix immediately.
≈·*•—[ A|S ]—•*·≈