Ports & Firewalls
We’ve gotten a request all the way to a machine. But a machine runs many programs — a web server, a database, an SSH daemon — and they all share one IP address. Ports are how the machine knows which program a connection is for, and firewalls are how it decides whether to let that connection in at all. This page is where networking turns into security: every open port is a door, and the whole game is opening as few as possible.
Ports: which process gets the bytes
Section titled “Ports: which process gets the bytes”Recall from the network stack that the transport layer adds a port
number to every connection. An IP address gets you to the machine; the port gets you to the process
on it. The full coordinate is IP:port — 93.184.216.34:443 means “the HTTPS server on that host.”
Some port numbers are conventions everyone agrees on:
22 SSH 443 HTTPS 5432 PostgreSQL 53 DNS 3306 MySQL 6379 Redis 80 HTTP 8080 common dev 27017 MongoDBPorts 0–1023 are well-known (binding them usually needs root, a small privilege guard). Above that is
fair game for your apps. None of these are magic — they’re just defaults; you can run HTTPS on 8443.
But conventions are why curl example.com knows to try port 80 without being told.
Binding and listening sockets
Section titled “Binding and listening sockets”For a program to receive connections, it must bind to a port and start listening. “Bind” means
“reserve this port; route its traffic to me.” Only one process can listen on a given port at a time —
which is the source of the famous Address already in use error when you start a server and an old copy
is still holding the port.
A subtle, security-relevant detail is which address a process binds to:
bind 0.0.0.0:8080 -> listen on ALL interfaces — reachable from the network bind 127.0.0.1:8080 -> listen on loopback ONLY — reachable only from this machineBinding a database to 0.0.0.0 exposes it to the whole network; binding it to 127.0.0.1 keeps it
private to the host. Getting this wrong is how databases end up on the public internet. Your first tool
here is ss:
ss -tlnp # every TCP port being listened on, and the process behind itss -tlnp | grep :5432 # is anything listening on the Postgres port — and bound where?That single command answers “is my service even up, and is it exposed?” — the first question in countless incidents.
NAT: many machines, one public IP
Section titled “NAT: many machines, one public IP”There aren’t enough IPv4 addresses for every device to have a public one (the scarcity from the stack
page). NAT (Network Address Translation) solves this: a router gives devices private addresses
(192.168.x.x) and translates them to its single public address on the way out, remembering which
internal machine each connection belongs to so replies come back to the right place.
laptop 192.168.1.5 ----+ phone 192.168.1.6 ----+--> [ Router / NAT ] --> public IP 203.0.113.7 --> internet TV 192.168.1.7 ----+ (rewrites source address, tracks the mapping)NAT is why your home devices can reach the internet but the internet can’t reach them unbidden — there’s no inbound mapping until an outbound connection creates one. That’s accidental security, and it’s why exposing a service from behind NAT requires explicit port forwarding. In the cloud the same idea appears as private subnets with a NAT gateway: instances reach out for updates, but nothing reaches in.
Firewalls: default deny
Section titled “Firewalls: default deny”A firewall is a rule set deciding which traffic is allowed. The single most important principle in all of network security fits in two words: default deny. Block everything, then open only the specific ports you’ve decided to expose. The opposite — allow everything, then try to block the bad stuff — is unwinnable, because you can’t enumerate every threat in advance.
DEFAULT ALLOW (wrong) DEFAULT DENY (right) open: everything closed: everything then: block known-bad -> then: open 443 (and maybe 22) you must predict every attack attacker must find your one open doorThe mindset: a port that isn’t open can’t be attacked. So expose 443 to the world, perhaps 22
(SSH) to your office IP only, and nothing else — your database and internal services stay reachable
only from inside the network.
Security groups vs iptables
Section titled “Security groups vs iptables”You’ll meet firewalls at two levels:
- Cloud security groups (AWS), NSGs (Azure), firewall rules (GCP) — stateful, default-deny rules attached to instances or networks, managed through the cloud API or Infrastructure as Code. This is the modern, primary control: declarative, auditable, and applied before traffic ever reaches the host.
iptables/nftables— the Linux kernel’s own packet filter, configured per host. Lower-level and powerful, but per-machine and easy to drift. Containers use it heavily under the hood, and tools likeufware friendly front-ends to it.
# A security group rule (conceptual): allow HTTPS from anywhere, SSH from the office only# inbound tcp 443 from 0.0.0.0/0 (HTTPS — the public internet)# inbound tcp 22 from 203.0.113.0/24 (SSH — office network only)# (everything else: implicitly denied)
# The host-level equivalent with ufw:sudo ufw default deny incomingsudo ufw allow 443/tcpsudo ufw allow from 203.0.113.0/24 to any port 22Prefer security groups as the primary boundary — they’re declarative and version-controlled — and treat host firewalls as defense-in-depth, not your only line.
The architect’s lens
Section titled “The architect’s lens”Step back from ss -tlnp and reason about ports and firewalls as the security boundary they are:
- Why do they exist? A port exists because one machine runs many programs sharing one IP, so the
full coordinate
IP:portsays which process a connection is for. A firewall exists because every open port is a door, and someone has to decide which doors open at all. - What problem do they solve? Ports disambiguate processes and let a service
bindto claim traffic; the bind address (0.0.0.0= all interfaces vs127.0.0.1= loopback only) is what keeps a database private. Firewalls solve attack surface via default-deny: block everything, then open only443and maybe22from your office. - What are the trade-offs? Default-deny is more friction than default-allow — every new exposure needs
a deliberate rule — but the alternative is unwinnable, because you can’t enumerate every threat in
advance. Security groups are declarative and applied before traffic reaches the host;
iptables/ufware per-host and easy to drift. - When should I avoid it? You don’t avoid the firewall — you choose its layer. Prefer cloud
security groups as the primary, version-controlled boundary via IaC; treat
host-level
iptables/ufwas defense-in-depth, not your only line. - What breaks if I remove it? Remove default-deny and your attack surface becomes everything someone ever opened “to test it” and forgot — the GitHub 1.35 Tbps memcached flood happened because port 11211 sat open to the internet. A port that isn’t open can’t be attacked; remove the firewall and they all are.
Check your understanding
Section titled “Check your understanding”- An IP address gets you to a machine. What does a port add, and why does one machine need many of them?
- What’s the difference between binding to
0.0.0.0and127.0.0.1, and how could the wrong choice expose a database to the internet? - Explain NAT in one or two sentences. Why does it mean the internet can’t reach your laptop unbidden?
- State the default-deny principle and explain why “allow everything, then block bad traffic” is a losing strategy.
- When would you use a cloud security group versus host-level
iptables/ufw, and why are security groups usually the preferred primary control?
Show answers
- A port identifies which process on the machine a connection is for. One machine runs many
programs sharing one IP (web server, database, SSH daemon), so the port disambiguates them — the full
coordinate is
IP:port. - Binding to
0.0.0.0listens on all interfaces, making the service reachable from the whole network; binding to127.0.0.1listens on loopback only, reachable just from the host. Bind a database to0.0.0.0(instead of127.0.0.1) and it can end up exposed on the public internet. - NAT lets many private-addressed devices share one public IP: the router rewrites the source address on the way out and tracks the mapping so replies return to the right device. The internet can’t reach your laptop unbidden because there’s no inbound mapping until an outbound connection creates one.
- Default deny means block everything, then open only the specific ports you’ve chosen to expose. “Allow everything, then block bad traffic” is losing because you can’t enumerate every threat in advance — the attacker only needs one gap you didn’t predict.
- Use a cloud security group as the primary boundary: it’s stateful, declarative, version-controllable
via IaC, auditable, and applied before traffic reaches the host. Use host-level
iptables/ufwas defense-in-depth, since per-host rules are lower-level and easy to let drift.