An IP address finds a machine. A port number finds the program on that machine. Think of the address as a building and the port as a door number. A server can run a website, a mail system, an SSH service and a database at once, and each listens on its own port.
Some numbers are conventions that everyone has agreed on. Plain HTTP uses 80 and HTTPS uses 443, which is why you never type them. SSH is 22. Mail has a small family: 25 for servers handing mail to each other, 587 for your mail program submitting a message, 993 for reading mail over IMAP with encryption. MySQL uses 3306 and DNS uses 53.
Ports explain a surprising share of the "it's down" tickets a hosting support team sees. The site is fine, the server is fine, and one particular door is shut. Once you can picture the doors, a lot of vague symptoms turn into specific questions with quick answers.
What a port actually is
A port is a 16-bit number, so it runs from 0 to 65535. It exists purely so that one machine with one IP address can carry on many conversations at once. When your browser connects to a website, the connection is identified by four things: your address, your source port, the server's address and the server's port. Your source port is chosen at random from a high range for each connection, which is why you can open twenty tabs to the same site without them getting tangled. The server side is the fixed one, and that is the number people mean when they say "the port".
The numbers are loosely divided into three bands.
- 0 to 1023 are the well-known ports, assigned by convention to standard services. On Linux, only a privileged process may listen here, which is why web servers start as root and then drop their rights.
- 1024 to 49151 are registered ports, used by applications that asked for a number. MySQL's 3306 lives here, as does PostgreSQL's 5432.
- 49152 to 65535 are dynamic, used mostly for the temporary source side of outgoing connections.
There are two transport protocols that use ports, TCP and UDP. Almost everything in this article is TCP, which sets up a connection and guarantees delivery in order. DNS is the notable exception: it uses UDP port 53 for most queries, and switches to TCP for large answers. HTTP/3 also runs over UDP, on port 443, which is why firewalls that only open TCP 443 can block it while HTTP/2 carries on working.
The ones you will meet most often
| Port | Protocol | Used for | Who should reach it |
|---|---|---|---|
| 80 | HTTP | Plain web, usually just a redirect to HTTPS | Everyone |
| 443 | HTTPS | Encrypted web traffic, including HTTP/2 over TCP and HTTP/3 over UDP | Everyone |
| 22 | SSH, SFTP | Remote command line and secure file transfer | You, ideally from known addresses or with keys only |
| 25 | SMTP | Mail passing between servers | Other mail servers; many hosts block it outbound for customers |
| 465 and 587 | SMTP submission | Your mail program sending a message | Authenticated users |
| 993 | IMAP over TLS | Reading mail on several devices | Authenticated users |
| 53 | DNS | Name lookups, UDP and TCP | Everyone, if the server runs authoritative DNS |
| 3306 | MySQL | Database connections | The application itself, almost never the public internet |
Port 21, plain FTP, still shows up in older documentation. It sends passwords unencrypted, and the SSH and SFTP piece in this series explains the better alternative.
What a firewall actually does with them
Most of what a basic firewall does is decide which ports are reachable from where. A web server should answer on 80 and 443 from anywhere. SSH on 22 is better limited to your own address or protected with keys. A database port open to the whole internet is one of the classic ways to lose data, and it still happens. If you run your own server, ask what is listening with ss -tlnp and check that every entry is something you intended.
$ ss -tlnp
State Recv-Q Send-Q Local Address:Port Process
LISTEN 0 511 0.0.0.0:80 users:(("nginx",pid=912,fd=6))
LISTEN 0 511 0.0.0.0:443 users:(("nginx",pid=912,fd=7))
LISTEN 0 128 0.0.0.0:22 users:(("sshd",pid=701,fd=3))
LISTEN 0 80 127.0.0.1:3306 users:(("mysqld",pid=845,fd=21))
Read the Local Address column. 0.0.0.0 means "on every interface", so anyone who can reach the machine can reach that port unless a firewall stops them. 127.0.0.1 means "loopback only": MySQL here is listening, but only programs on the same machine can talk to it. That is exactly what you want. If you see 0.0.0.0:3306 on a server you did not deliberately set up that way, treat it as a to-do for today.
It helps to remember that there are two separate layers. The program must be listening, and the firewall must permit the traffic. Both have to say yes. A listening program with a blocking firewall is unreachable, and an open firewall with nothing listening gets an immediate refusal.
Why a service can be up and unreachable
When someone says "the site is down", a port is often the story. The web server may have crashed, so nothing is listening on 443. A firewall rule may block it. Your host may block outgoing mail on port 25 to fight spam, which makes a contact form silently fail. A quick test from another computer, such as nc -vz example.com 443, tells you whether the door is open before you start digging into the application.
The three results of such a test mean different things, and learning to read them saves a lot of time.
- Connection succeeded. The door is open and something answered. If the site still misbehaves, the problem is above this layer: the application, the certificate or the configuration.
- Connection refused. The machine replied immediately that nothing is listening. The service has stopped, crashed, or is bound to a different port or address.
- Timed out. Nothing came back at all. Typically a firewall is silently dropping the packets, or the machine is unreachable altogether.
The outgoing mail trap
Port 25 deserves its own warning. Most hosts and home internet providers block outgoing connections on it from ordinary customers, because compromised machines used to spray spam through it. If a contact form on your site uses the server's own mail function, it works for the host's trusted relay. If you point it at an outside server on port 25 from a VPS, the connection may simply time out.
The fix is almost always to use submission, port 587 with STARTTLS or 465 with implicit TLS, with a real username and password. That is also what modern mailbox providers expect, since an authenticated message is far easier to trust than an anonymous one.
Walkthrough: opening only what you need on a VPS
On a fresh VPS the safest starting position is that everything is closed and you open doors one at a time. On Ubuntu and Debian systems, ufw is the friendly front end to the firewall. A cautious sequence looks like this.
- Set the defaults:
sudo ufw default deny incomingandsudo ufw default allow outgoing. - Allow SSH before you enable anything, or you will lock yourself out:
sudo ufw allow 22/tcp. If your home address is fixed,sudo ufw allow from 198.51.100.7 to any port 22 proto tcpis tighter. - Allow the web:
sudo ufw allow 80/tcpandsudo ufw allow 443/tcp. If you serve HTTP/3, addsudo ufw allow 443/udp. - Turn the firewall on with
sudo ufw enable, then read the result withsudo ufw status verbose. - From a different computer, run
nc -vz 203.0.113.10 22, then 443, then 3306. The first two should connect, and the last should time out.
Keep your existing SSH session open while you test, and open a second one before you close the first. If the new rules have broken something, the old session is your way back in. Many providers also have a firewall in front of the machine, in their own control panel. If a port is open in ufw and still unreachable, check that outer layer as well.
Choosing the right mail port
Mail causes more port confusion than anything else, mostly because there are so many of them and old guides disagree. For a mailbox you read and send from your own devices, the modern answer is short.
- Incoming: IMAP on 993 with TLS. Plain IMAP on 143 and POP3 on 110 exist, but there is rarely a reason to use them.
- Outgoing: submission on 587 with STARTTLS, or 465 with TLS from the first byte. Both are fine, and most programs offer both.
- Port 25 is for server-to-server delivery. Your own mail program should not be using it.
When a mail program says it cannot connect, the quickest check is whether the port opens at all, using nc -vz mail.example.com 587 from the same network. A refusal or timeout there means no amount of password retyping will help.
Non-standard ports
You will see addresses like example.com:8080 for test sites and control panels. They work the same way. Moving a service to an odd port reduces the noise from automated scanners, but it is not a security measure by itself. Real protection comes from keys, updates and firewall rules.
There are good reasons for odd ports all the same. Two web applications cannot both listen on 443 of the same address, so a developer running a Node app locally will use 3000 or 8080 and put a proper web server in front of it as a reverse proxy. A control panel often uses a high port so that it does not collide with your site. The costs are that corporate networks sometimes block unusual outbound ports, and that people have to remember to type the number.
Verifying it
nc -vz example.com 443tests one port. On Windows,Test-NetConnection example.com -Port 443does the same in PowerShell.curl -v https://example.com/shows the connection stage, the certificate handshake and the response, so you can see exactly where it fails.ss -tlnpon the server lists what is listening, andsudo ss -tulpnadds UDP.- Test from a second network, such as a phone on mobile data, to rule out a block on your own side.
- For mail,
openssl s_client -connect mail.example.com:993confirms that the encrypted IMAP door is open and shows its certificate.
If the port is open and the symptom remains, the troubleshooting guide is the next stop.
Smaller questions
Why do I never type :443?
Because the browser fills in the default for the scheme. https:// implies 443 and http:// implies 80. Typing them changes nothing.
Can I run my site on a different port to hide it?
You can, and visitors would then have to type the port. Scanners test every port anyway, so it hides nothing that matters.
Is it safe to open port 3306 so my developer can connect?
It is far better to connect through an SSH tunnel, or to allow one specific address in the firewall. Open to the whole internet, it invites constant password guessing.
Why can I reach the site but not send mail?
They use different ports. Web on 443 can be fine while 587 or 465 is blocked by your network, or the server's mail service has stopped.
What happens if two programs want the same port?
The second one fails to start, usually with an "address already in use" error. It is a common cause of a web server refusing to restart after a configuration change: an old process is still holding 80 or 443. Run sudo ss -tlnp | grep :443 to see which process owns the port, then stop that one rather than guessing.
Does closing a port stop attacks?
It removes one route in. The sites that get compromised are mostly compromised through the application on an open port, such as an outdated plugin on 443, so closing unused doors is necessary hygiene and not the whole job. Updates, strong passwords and backups carry the rest of the load.