Guides

Common ports: TCP and UDP port numbers every server admin meets, and which to expose

A list of common TCP and UDP ports (SSH 22, HTTPS 443, DNS 53, MySQL 3306, RDP 3389) with what each one does and whether to expose it to the internet.

Published ~8 min read

Short answer: the ports a server admin meets most are 22 (SSH), 80 and 443 (HTTP and HTTPS), 25, 465 and 587 (mail), 53 (DNS), 3306 and 5432 (MySQL and PostgreSQL) and 3389 (RDP). The table below lists the common ones with their transport and, the part most lists skip, whether the port should be reachable from the internet at all. Ports 0 to 1023 are the well-known ports, 1024 to 49151 registered ports, and 49152 to 65535 dynamic ports that no service owns.

List of common ports

“Yes” means the port exists to be public. “Allowlist” means reachable only from your own addresses or through a VPN. “Never” means the service should listen on 127.0.0.1 or a private network and nothing on the internet should reach it.

PortTransportServiceExpose to the internet?
20, 21TCPFTP data and control (990 for implicit FTPS)Avoid: use SFTP on 22. If FTP must stay, FTPS with an allowlist
22TCPSSH, and SFTP, scp and rsync inside itYes, with key-only login. Allowlist if your addresses are fixed
23TCPTelnetNever: logins cross the network unencrypted
25TCPSMTP between mail serversYes on a mail server (incoming mail), closed everywhere else
53UDP + TCPDNSOnly on an authoritative name server. Never as an open resolver
67, 68UDPDHCP server, DHCP clientNever: a DHCP server belongs on a private network, and a DHCP client needs no rule of your own
80TCPHTTPYes on a web server, to redirect to HTTPS
110, 995TCPPOP3, POP3 over TLS995 yes on a mail server that offers POP3; leave 110 closed
111, 2049TCP + UDPrpcbind, NFSNever
123UDPNTPNot needed unless the server is a time server: syncing its own clock is outbound
135, 137–139, 445TCP + UDPWindows RPC, NetBIOS, SMB file sharing (and Samba)Never
143, 993TCPIMAP, IMAP over TLS993 yes on a mail server; leave 143 closed
161, 162UDPSNMP, SNMP trapsNever, or allowlist your monitoring host
389, 636TCPLDAP, LDAP over TLSAllowlist
443TCP + UDPHTTPS; UDP for HTTP/3 (QUIC)Yes on a web server
465TCPMail submission over implicit TLSYes on a mail server, for your users' mail clients
500, 4500UDPIPsec IKE and NAT traversal (IKEv2 VPNs such as strongSwan)Yes on a VPN server
587TCPMail submission with STARTTLSYes on a mail server, for your users' mail clients
873TCPrsync daemonAllowlist. rsync over SSH needs no extra port
1194UDP (TCP possible)OpenVPNYes on a VPN server
1433TCPMicrosoft SQL ServerNever: allowlist or tunnel
2083, 2087TCPcPanel and WHM over HTTPS (2096 for webmail)2083 and 2096 for your users; WHM on 2087 allowlisted where you can
2375, 2376TCPDocker API, plain and TLS2375 never: it is root on the host. 2376 only with client certificates and an allowlist
3000, 5000, 8000TCPApp and dev servers (Grafana, Node.js apps, Flask, Django runserver)Never directly: put nginx in front
3306TCPMySQL, MariaDBNever: keep it on 127.0.0.1
3389TCP + UDPRDP (Windows Remote Desktop)Allowlist, or reach it through a VPN
5432TCPPostgreSQLNever: keep it on localhost
5900 and upTCPVNC (display :0 is 5900, :1 is 5901)Never: tunnel it over SSH
5985, 5986TCPWinRM over HTTP, over HTTPSAllowlist
6379TCPRedisNever
8006TCPProxmox VE web interfaceAllowlist
8080, 8443TCPHTTP and HTTPS alternates; 8443 is also Plesk's panelOnly if a service needs it; usually behind a reverse proxy instead
9000TCPPHP-FPM (its upstream default; Debian and Ubuntu use a Unix socket instead)Never: an open FastCGI port lets anyone run PHP on the server
9090, 10000TCPCockpit and Webmin web consolesAllowlist
9200TCPElasticsearch, OpenSearch HTTP APINever
11211TCPMemcached (UDP is off by default since 1.5.6)Never
25565 / 19132TCP / UDPMinecraft Java / BedrockYes on a game server
27017TCPMongoDBNever
51820UDPWireGuard (a convention, not an IANA assignment)Yes on a VPN server

Mail ports have one catch: many hosting providers restrict outgoing connections on port 25, so check your provider’s acceptable use policy or ask support before you build a mail server. Many numbers in the table are conventions rather than IANA assignments: 51820 (WireGuard), 25565 and 19132 (Minecraft) are not registered at all, and IANA lists 8443, 9000, 9200 and the cPanel ports under other services, yet these are the ports the software uses out of the box.

Which ports does my server need open?

Fewer than the table suggests. Most servers have one job, and the job decides the ports; everything else stays closed. Your own way in, SSH or RDP, belongs in the right-hand column whenever your addresses allow it.

Server roleOpen to everyoneOpen to your addresses only
Web server or reverse proxy80/TCP, 443/TCP, 443/UDP if you serve HTTP/322/TCP
Mail server25/TCP, 465/TCP, 587/TCP, 993/TCP22/TCP
Authoritative DNS server53/UDP, 53/TCP22/TCP
VPN server51820/UDP (WireGuard), 1194/UDP (OpenVPN) or 500 and 4500/UDP (IPsec)22/TCP, or nothing else once the VPN is up
Windows server you use over RDPNothing3389/TCP and 3389/UDP
Game serverThe game's port, e.g. 25565/TCP for Minecraft Java22/TCP, RCON ports
Database server for your other serversNothing22/TCP, and the database port from your app servers' addresses

Why the “never” ports are never

Databases, caches and admin APIs were built for trusted networks. Some have no password by default, all of them are scanned for constantly, and an exposed one tends to end as a ransom note in place of your data. Most of them already start safe:

  • MariaDB on Debian has bind-address = 127.0.0.1 in /etc/mysql/mariadb.conf.d/50-server.cnf.
  • PostgreSQL defaults to listen_addresses = 'localhost'.
  • Redis ships with bind 127.0.0.1 -::1 and protected-mode yes.
  • MongoDB binds to localhost by default.

The risk is the one line you change to make a remote client work. Leave the bind address alone and reach the database through an SSH tunnel instead; replace YOUR_USER and YOUR_SERVER_IP with your login and the server’s address, and use another local port on the left, such as 15432, if PostgreSQL also runs on your own computer:

your computer · Linux, macOS, Windows
ssh -N -L 5432:127.0.0.1:5432 YOUR_USER@YOUR_SERVER_IP

Your client then connects to 127.0.0.1:5432 on your own machine, and port 5432 stays closed on the server.

Port number ranges: well-known, registered and dynamic

Port numbers are 16 bits, so they run from 0 to 65535, separately for TCP and UDP. RFC 6335 splits them into three ranges:

RangeNameWhat it means
0–1023System ports (well-known)Assigned by IANA to core services: 22, 25, 53, 80, 443
1024–49151User ports (registered)Assigned by IANA on request: 3306, 3389, 5432
49152–65535Dynamic ports (private, ephemeral)Never assigned; free for temporary client ports

Operating systems do not follow that last line exactly. When your server opens an outgoing connection, the kernel picks a temporary source port from its own ephemeral range: on Linux that is 32768–60999 by default, on Windows 49152–65535. On Linux, ports below 1024 also need root or the CAP_NET_BIND_SERVICE capability to listen on.

Debian · Ubuntu
sysctl net.ipv4.ip_local_port_range net.ipv4.ip_unprivileged_port_start
Example output
net.ipv4.ip_local_port_range = 32768	60999
net.ipv4.ip_unprivileged_port_start = 1024
Windows cmd
netsh int ipv4 show dynamicport tcp
Example output
Protocol tcp Dynamic Port Range
---------------------------------
Start Port      : 49152
Number of Ports : 16384

That has a practical consequence when you pick a port for your own service on Linux: choose one between 1024 and 32767 that nothing else uses. Linux’s ephemeral range overlaps the top of the registered range, so a service on, say, 45000 can find its port already taken by an outgoing connection at startup and fail with Address already in use. If a service must live in that range, list its port in net.ipv4.ip_local_reserved_ports so the kernel stops handing it out.

TCP, UDP or both?

The Transport column matters for two reasons. A firewall rule is per protocol, so a service listed as TCP + UDP needs both rules: DNS answers large replies and zone transfers over TCP, and RDP adds UDP for a faster picture. And the two behave differently when you test them. TCP starts with a handshake, so a test either connects, is refused or times out. UDP has no handshake: a silent UDP port looks the same whether it is open or filtered, unless the test speaks the service’s own protocol, such as dig for DNS or the game client for a game server. Ping is neither: it uses ICMP, which has no ports at all, so a server that ignores ping can still have every port in this table open.

How to see which ports are open on your server

Ask the kernel which sockets are listening, with the process behind each:

Debian · Ubuntu · Rocky
sudo ss -tulpn
Example output (shortened)
Netid State  Recv-Q Send-Q  Local Address:Port  Peer Address:Port Process
udp   UNCONN 0      0       127.0.0.53%lo:53         0.0.0.0:*     users:(("systemd-resolve",pid=402,fd=13))
udp   UNCONN 0      0             0.0.0.0:51820      0.0.0.0:*
tcp   LISTEN 0      4096    127.0.0.53%lo:53         0.0.0.0:*     users:(("systemd-resolve",pid=402,fd=14))
tcp   LISTEN 0      128           0.0.0.0:22         0.0.0.0:*     users:(("sshd",pid=611,fd=3))
tcp   LISTEN 0      511           0.0.0.0:443        0.0.0.0:*     users:(("nginx",pid=902,fd=7))
tcp   LISTEN 0      151         127.0.0.1:3306       0.0.0.0:*     users:(("mariadbd",pid=755,fd=20))
tcp   LISTEN 0      511         127.0.0.1:6379       0.0.0.0:*     users:(("redis-server",pid=698,fd=6))

Read the Local Address column. 0.0.0.0 or [::] is every address, so the service is reachable from outside unless a firewall stops it. 127.0.0.1 and 127.0.0.53 are loopback, unreachable from the network whatever the firewall says, which is where MariaDB and Redis belong. The UDP line on 51820 without a process is WireGuard, which runs in the kernel. Checking open ports on Linux explains every flag and the lsof and netstat equivalents.

On Windows Server, the same in PowerShell:

PowerShell
Get-NetTCPConnection -State Listen | Sort-Object LocalPort | Select-Object LocalAddress, LocalPort, OwningProcess
Get-NetUDPEndpoint | Sort-Object LocalPort | Select-Object LocalAddress, LocalPort, OwningProcess

How to check a port from outside

Listening is half the answer; the firewall, the provider’s network and the bind address decide the rest. Test from a machine outside the server. Replace YOUR_SERVER_IP and PORT:

Linux (netcat-openbsd)
nc -vz -w 5 YOUR_SERVER_IP PORT
macOS Terminal
nc -vz -G 5 YOUR_SERVER_IP PORT
Windows PowerShell
Test-NetConnection YOUR_SERVER_IP -Port PORT

Or use the open port checker, which opens one TCP connection from our server in Amsterdam to any public IP address and port and tells you whether it was accepted, refused or got no answer. It tests TCP only, for the reason above, one port per check, and its rate limits are sized for testing your own services, not for sweeping a network.

Turn the table into firewall rules

Start from “deny everything incoming” and open only the rows you need. With UFW on Debian or Ubuntu, a web server with SSH restricted to your office address looks like this. Replace YOUR_IP with your own public address, which the what is my IP page shows. Debian does not ship UFW; install it with sudo apt install ufw first.

UFW (Debian · Ubuntu)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from YOUR_IP to any port 22 proto tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

ufw enable asks for confirmation, which is why it comes last: pasted as a block, any line after it would be read as the answer. Then check the result with sudo ufw status numbered.

The “never” rows need no rule at all: under a deny default they stay closed, and bound to 127.0.0.1 they are unreachable even without a firewall. The full walkthrough, with rate limits and source-restricted rules, is the UFW firewall guide.

On Rocky Linux and AlmaLinux with firewalld running (sudo firewall-cmd --state says so), the default zone already allows SSH and Cockpit on 9090. Open the web ports and drop Cockpit if you do not use it:

firewalld (Rocky · Alma)
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --permanent --remove-service=cockpit
sudo firewall-cmd --reload

Guides to individual ports

  • SSH port 22: checking, testing and connecting on another port with ssh, scp and rsync.
  • RDP port 3389: TCP and UDP, RD Gateway, and the ports Remote Desktop does not need.
  • Ports 443 and 80: HTTP, HTTPS, HTTP/3 on UDP, redirects and Cloudflare’s port list.
  • DNS port 53: why DNS needs UDP and TCP, how to test it, and how to free it from systemd-resolved.
  • SMTP ports 25, 465, 587 and 2525: which one delivers, which one submits, and how to test them.
  • FTP port 21: the data ports, passive mode, FTPS and why SFTP on 22 is simpler.

On a Standard KVM VPS at VMHeaven the firewall on the server is yours to configure, the panel has packet rules of its own, and always-on DDoS protection is included. The VNC console in the panel still reaches the server when a rule goes wrong.

Frequently asked

What are the most common ports?

22 for SSH, 80 and 443 for HTTP and HTTPS, 25, 465 and 587 for mail, 53 for DNS, 3306 for MySQL, 5432 for PostgreSQL and 3389 for Remote Desktop. Which of them to open depends on the server's job: web ports on a web server, mail ports on a mail server, while database ports stay closed to the internet.

What is the difference between well-known, registered and dynamic ports?

Under RFC 6335, ports 0-1023 are system (well-known) ports for core services, 1024-49151 are user (registered) ports assigned on request, and 49152-65535 are dynamic ports that are never assigned. Linux itself picks temporary client ports from 32768-60999 by default.

Which ports should never be open to the internet?

Database and cache ports such as 3306, 5432, 6379, 27017 and 9200, the Docker API on 2375, SMB on 445 and VNC on 5900. Keep those services on 127.0.0.1 or a private network and reach them through an SSH tunnel or a VPN; Telnet on 23 should not run at all.

Related articles

All guides