Well-known ports
Introduction to ports and protocols split the 0–65535 port space into three ranges. The first and most heavily relied-upon of the three is well-known ports — 0 through 1023 — reserved for the internet's oldest and most fundamental services.
What makes a port "well-known"
Ports 0 through 1023 are assigned by IANA to the internet's foundational protocols — the ones so widely used that hardcoding their port numbers into client software makes sense. When your browser connects to https://example.com without you specifying a port, it connects to port 443 because HTTPS's well-known port is baked into the browser's defaults, not because port 443 is technically special at the protocol level.
On most Unix-like systems, including Linux, binding a service to a port below 1024 requires root or an equivalent elevated privilege. This is a security convention rather than a networking requirement — the idea being that a random unprivileged user shouldn't be able to impersonate the machine's SSH or web server — but it's one you'll bump into directly the first time you try running a plain web server on port 80 as a non-root user and get a permission error rather than a network error.
The privileged-port rule is enforced by the operating system's kernel, not by IANA and not by the protocol. IANA's registry is documentation; the 0–1023 privilege check is actual code in the Linux networking stack (
CAP_NET_BIND_SERVICE), which is why it's the one rule in this whole three-range system you can't talk your way around with a firewall change.
The ports worth memorizing
Some port numbers come up often enough in this course, and in daily engineering work, that they're worth committing to memory outright.
| Port | Protocol | Transport | Notes |
|---|---|---|---|
| 20/21 | FTP (data/control) | TCP | Two ports, not one — see below |
| 22 | SSH | TCP | Encrypted remote shell and file transfer |
| 23 | Telnet | TCP | Legacy remote access, entirely unencrypted — do not use |
| 25 | SMTP | TCP | Mail transfer between servers |
| 53 | DNS | UDP and TCP | Both transports, for the reason below |
| 67/68 | DHCP (server/client) | UDP | Automatic address assignment |
| 80 | HTTP | TCP | Unencrypted web traffic |
| 110 | POP3 | TCP | Mail retrieval, downloads and typically deletes |
| 143 | IMAP | TCP | Mail retrieval, keeps mail on the server |
| 443 | HTTPS | TCP, and UDP for HTTP/3 | Encrypted web traffic |
Two rows on that table deserve more than a one-line note.
Port 53 appears twice because DNS genuinely uses both transports. Ordinary lookups go over UDP, which is fast and avoids setting up a connection for what is usually a single small question and a single small answer. But UDP responses have a practical size limit, so when an answer is too large to fit — or when two DNS servers copy a whole zone between themselves — DNS switches to TCP for that exchange. A firewall that allows UDP 53 but blocks TCP 53 produces one of the more confusing failure modes in networking: most lookups work, and a few specific ones mysteriously don't.
Port 443 has the same dual nature, for a different reason. HTTP/3 doesn't run on TCP at all; it runs on QUIC, which is built on UDP. So a modern web server may be listening on TCP 443 and UDP 443 simultaneously, serving the same site over two different transports depending on what the client supports. It's a real exception to the reflex that "HTTPS means TCP."
FTP and the two-port problem
FTP is worth a specific mention because it's the odd one out. It uses port 21 for control commands — logging in, listing and changing directories — and a separate connection for the actual file data. In the original design, called active mode, the server opens that data connection back to the client from port 20. That worked in 1971 and breaks constantly today, because a connection initiated from the server toward the client is exactly what home routers and firewalls block by default.
The workaround is passive mode, now the default in essentially every FTP client: the client opens the data connection too, to a high-numbered port the server nominates. So port 20 shows up in the tables and rarely in real traffic. The deeper lesson is worth carrying forward — a protocol that uses a second, dynamically chosen port is awkward for firewalls to handle, and that awkwardness has shaped protocol design ever since.
Well-known doesn't mean mandatory
Nothing at the protocol level actually requires a web server to run on port 80, or SSH to run on port 22 — these are strong, universally followed conventions, not technical constraints. A server administrator can configure SSH to listen on port 2222 instead of 22, and it will work exactly the same way, as long as clients are told to connect to the non-default port explicitly.
Doing so is a common, legitimate practice, but be precise about what it buys you: automated tools that sweep the internet hitting port 22 on every address they can find will miss a server listening elsewhere, which meaningfully reduces log noise and low-effort attack attempts. It does nothing against anyone who scans your host's full port range, which takes seconds. Moving the port is log hygiene, not a security control, and it's no substitute for key-based authentication and keeping the service patched.
Confirming what's listening
ss shows which well-known ports a machine is actively listening on. Output below is abridged to the columns that matter here:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=901,fd=3))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1204,fd=6))
LISTEN 0 244 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=1533,fd=5))
SSH (port 22) and a web server (port 80) are both listening on 0.0.0.0, so they're reachable from anywhere the host itself is reachable. PostgreSQL, on port 5432, is listening only on 127.0.0.1 — the loopback address covered in IP addressing — so it accepts connections only from processes on the same machine.
That last distinction matters enormously for security, and it's stronger than a firewall rule: a service bound to loopback cannot be reached from the network at all, because the kernel will not deliver externally arriving traffic to a loopback socket. There's no rule to misconfigure and no rule to accidentally remove.
Practical scenario: moving SSH off port 22
Say you've decided to move SSH to port 2222 on a remote server to cut down on scan noise. The port change itself is one line of configuration. The risk is entirely operational: if you close port 22 before confirming that port 2222 works, and something in the configuration is wrong, you have locked yourself out of a machine you can only reach over SSH.
Never close your current access path before the new one is proven
Do this on a lab VM or a machine with out-of-band access (a cloud provider's serial console or web terminal) before you do it on anything you care about. Keep your existing SSH session open for the entire procedure — an open session survives a service reload, and it is your way back in if the new configuration is broken.
A safe order of operations:
1. Read the current state first: sudo sshd -T | grep -i '^port'
2. Back up the config: sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
3. Allow the NEW port in the firewall, while leaving 22 open.
4. Configure sshd to listen on BOTH 22 and 2222.
5. Validate the config before applying: sudo sshd -t
6. Reload the service (do not close your current session).
7. From a SECOND terminal, connect on the new port: ssh -p 2222 <user>@<host>
8. Only after step 7 succeeds, remove port 22 from the config and the firewall.
Step 5 is the one people skip. sshd -t parses the configuration and reports syntax errors without touching the running service, which turns a lockout into a corrected typo. And if anything goes wrong after the reload, rolling back is restoring the backup from step 2 and reloading again — from the session you deliberately kept open.
The wider point: a port convention is useful because every client knows the default. Changing it means every client, firewall rule, monitoring probe, CI job, and runbook has to learn the new number, and each one you forget is a future outage.
Common mistakes
- Assuming a non-standard port hides a service. It reduces noise from broad automated sweeps. Any scan of your host's full port range finds it immediately.
- Trying to bind a well-known port without sufficient privileges and misreading the resulting error. "Permission denied" when binding port 80 as a non-root user is an operating-system restriction, not a connectivity problem — no amount of firewall or routing debugging will fix it.
- Forgetting that a port number doesn't guarantee what protocol is actually running there. Port 443 is conventionally HTTPS, but nothing stops something else from listening on it. Verify with
curl -vor a packet capture rather than inferring from the number.
Practice exercises
- Without looking back at the table, write down the port numbers for SSH, HTTP, HTTPS, and DNS, and note which of those uses more than one transport protocol.
- Run
sudo ss -tlnpon a Linux machine and identify at least one well-known port in use along with its process. If any service is bound to127.0.0.1, explain what that means for reaching it from another machine. - Look up, in IANA's registry, what service is conventionally assigned to port 3306, and explain why it sits in a different range than the ports in this article's table.
Worth checking before you move on: you should be able to say why binding to port 80 needs elevated privileges while port 8080 doesn't — and the answer should name the boundary, not just assert that one is special.
That boundary is the real subject of the next article. Port 8080 isn't lower-security or less official than port 80; it simply sits above 1023, in a range with looser rules, no privilege requirement, and a completely different registration culture. That's where nearly every database, cache, message queue, and development server you'll ever run actually lives: Registered ports.
Sources
- IANA, Service Name and Transport Protocol Port Number Registry
- IETF, RFC 6335 – IANA Procedures for the Management of the Service Name and Transport Protocol Port Number Registry
- IETF, RFC 959 – File Transfer Protocol — the original two-port FTP design.
- IETF, RFC 1123 – Requirements for Internet Hosts: Application and Support — specifies DNS's use of both UDP and TCP on port 53.