Why people keep saying "expose as little beyond 443"
When setting up a server, the most common security advice is "only open 80/443 if you can". The reason is simple: the more ports you open, the larger your attack surface—every open port is a potential entry point. To put that advice into action you first need to understand ports themselves.
What a port is, and why 65535 of them
A machine runs web, database, SSH and more at once. How does the OS hand each network packet to the right app? Via port numbers: the destination port in a TCP/UDP header decides which app handles the connection.
TCP header: [source port][destination port][sequence]…
destination port = which app on this machine handles this connection
0–65535 is 65536 numbers: 1–1023 are well-known ports (often needing privileged binding), 1024–49151 are registered ports, and 49152–65535 are dynamic/private.
Common ports by purpose
Web and encryption
| Port | Service | Notes |
|---|---|---|
| 80 | HTTP | often 301 → 443 |
| 443 | HTTPS | encrypted, a must-open |
| 8443 | HTTPS alt | web admin / backup |
Remote admin & ops
| Port | Service | Notes |
|---|---|---|
| 22 | SSH | suggest changing default / keys / source IP |
| 3389 | RDP (Windows) | strongly discourage public exposure |
| 21 | FTP | plaintext; prefer SFTP/SCP |
File transfer
| Port | Service | Notes |
|---|---|---|
| 21 | FTP | plaintext |
| 22 | SFTP/SCP | over SSH, recommended |
| 990 | FTPS (implicit) | encrypted FTP |
Databases
| Port | Service | Notes |
|---|---|---|
| 3306 | MySQL/MariaDB | usually internal only |
| 5432 | PostgreSQL | internal only |
| 6379 | Redis | never expose publicly |
| 27017 | MongoDB | never expose publicly |
Dev & debug
| Port | Service | Notes |
|---|---|---|
| 3000 | Node/Vite dev | local binding is fine |
| 3300 | common dev service | local use |
| 5000/8000 | Flask / generic | bind to localhost |
| 53 | DNS | UDP, service-private |
Mail and more
| Port | Service | Notes |
|---|---|---|
| 25 / 587 | SMTP / submission | 25 often blocked by clouds |
| 110 / 143 | POP3 / IMAP | plaintext; prefer encrypted |
| 993 / 995 | IMAPS / POP3S | encrypted, recommended |
| 443/993 | web / encrypted mail |
Source vs destination port (in one line)
- Destination port = the service's "doorplate" the client connects to;
- Source port = a random high port the client picks when initiating, so the server can reply to the right flow.
Outbound source ports are random and rarely need to be opened; you only care about inbound "which destination port to expose".
How services are discovered (port scanning)
The port-service mapping isn't magic: a service answers on the port it listens on, so probing whether a given IP has a live service on a port can be checked. That's one technique shared by both self-audits and attackers' reconnaissance—the difference is you scan yourself, they scan you. So minimal exposure + only necessary inbound ports is the most direct way to shrink your scannable surface.
Security baseline checklist
- [ ] Inbound only: 80/443 + the app ports you need,
denyeverything else; - [ ] SSH: non-default port / key-based login / source-IP limits (at least one);
- [ ] Databases, Redis, Docker and debug ports: bind to internal/localhost only, never public;
- [ ] Enforce rules with cloud security groups/host firewalls rather than "open everything and fix later";
- [ ] Periodically scan your own public IP and confirm no admin management port is accidentally open.
Self-check
On a server you manage, use an online port/IP lookup to list what it currently exposes, then trim against the baseline above and ask yourself once: "does this port really need to be reachable from the public internet?" More often than not the answer is no—removing one port removes one attack surface.