Common Linux Network Ports Reference
Learn Linux port ranges, read /etc/services, find what's listening with ss and nmap, and apply solid firewall rules to expose or block the right ports.
Before you start
- ▸A Linux system with a terminal and sudo or root access
- ▸Basic familiarity with running shell commands
- ▸nmap installed for remote port scanning (optional but recommended)
Every network connection on Linux goes through a port — a number from 0 to 65535 that tells the kernel which service should handle incoming traffic. Knowing which ports map to which services, where that mapping lives on disk, how to see what is actually listening on your machine, and how to make sensible firewall decisions will save you hours of troubleshooting.
Port Ranges at a Glance
The Internet Assigned Numbers Authority (IANA) divides port numbers into three bands:
| Range | Name | Who uses them |
|---|---|---|
| 0 – 1023 | Well-known / system ports | Standardised services; binding requires root (or CAP_NET_BIND_SERVICE) |
| 1024 – 49151 | Registered ports | Vendor and application services registered with IANA |
| 49152 – 65535 | Ephemeral / dynamic ports | Assigned by the kernel for outgoing connections; not usually bound by servers |
Common Well-Known Ports
The table below covers services you will encounter on almost every Linux deployment. Both TCP and UDP are listed where relevant.
| Port | Protocol | Service | Notes |
|---|---|---|---|
| 20, 21 | TCP | FTP (data, control) | Unencrypted; prefer SFTP (22) instead |
| 22 | TCP | SSH / SFTP / SCP | Your primary remote-access port; harden it |
| 23 | TCP | Telnet | Plaintext, obsolete; block it |
| 25 | TCP | SMTP | Mail transfer between servers |
| 53 | TCP/UDP | DNS | UDP for queries; TCP for zone transfers and large responses |
| 67, 68 | UDP | DHCP (server, client) | Automatic IP assignment |
| 80 | TCP | HTTP | Unencrypted web; often redirects to 443 |
| 110 | TCP | POP3 | Email retrieval, plaintext variant |
| 123 | UDP | NTP | Time synchronisation; chrony/systemd-timesyncd use this |
| 143 | TCP | IMAP | Email access; plaintext variant |
| 161, 162 | UDP | SNMP | Network monitoring; v1/v2c are insecure |
| 389 | TCP/UDP | LDAP | Directory services |
| 443 | TCP | HTTPS | TLS-encrypted web; also used by HTTP/3 over QUIC (UDP) |
| 465 / 587 | TCP | SMTPS / SMTP Submission | 587 + STARTTLS is the modern standard for mail clients |
| 514 | UDP | Syslog | Remote logging; restrict to trusted hosts |
| 636 | TCP | LDAPS | LDAP over TLS |
| 993 / 995 | TCP | IMAPS / POP3S | Encrypted email retrieval |
| 3306 | TCP | MySQL / MariaDB | Never expose to the internet; bind to 127.0.0.1 |
| 5432 | TCP | PostgreSQL | Same advice as MySQL |
| 6443 | TCP | Kubernetes API server | Secure with mTLS and RBAC |
| 8080 / 8443 | TCP | HTTP/HTTPS alternates | Common for app servers and proxies; not reserved |
The /etc/services File
/etc/services is a plain-text database that maps port numbers and protocols to human-readable service names. Tools like ss, netstat, and nmap consult it when you ask them to show service names instead of raw numbers.
Reading the file
grep -E '^(ssh|http|https|smtp)' /etc/services
Typical output (will vary slightly by distro):
# ssh 22/tcp
# http 80/tcp www
# https 443/tcp
# smtp 25/tcp mail
Looking up a specific port or service
# Port number → service name
grep -w '5432/tcp' /etc/services
# Service name → port number
getent services postgresql
getent services is the cleaner approach because it also queries NSS sources beyond the flat file, so it works correctly in environments that extend /etc/nsswitch.conf.
Checking What Is Actually Listening
The definitive modern tool is ss from the iproute2 package, which is installed on every mainstream distro. It queries kernel socket tables directly.
Show all listening TCP and UDP ports
ss -tulnp
Flag breakdown: -t TCP, -u UDP, -l listening only, -n numeric (skip name lookup), -p show process name and PID. Run as root to see processes owned by other users.
Filter to a single port
ss -tulnp sport = :443
Check a port with nmap (from another host)
# Install if needed:
# Debian/Ubuntu: apt install nmap
# Fedora/RHEL: dnf install nmap
# Arch: pacman -S nmap
nmap -sV -p 22,80,443 192.168.1.10
Running nmap from a remote machine tells you what the firewall actually lets through, not just what the local kernel has bound.
Legacy: netstat
netstat (from the net-tools package) still appears in many scripts but is no longer installed by default on most distros. Prefer ss.
netstat -tulnp # same flags as ss, equivalent output
Which Ports to Expose or Block
The safest baseline is deny all inbound, allow only what you need. The following guidance covers the most common decisions.
Always block from the internet
- 23 (Telnet) — plaintext, no legitimate modern use
- 3306, 5432 (MySQL, PostgreSQL) — bind to
127.0.0.1in the service config; never expose directly - 6379 (Redis), 27017 (MongoDB) — historically breached because left open by default
- 111, 2049 (RPC, NFS) — LAN services only
- 161/162 (SNMP) — at minimum restrict to a management VLAN; disable v1/v2c
Expose only on authenticated channels
- 22 (SSH) — keep open but use key-based auth, disable root login, consider a non-standard port or port knocking on high-exposure servers
- 514 (Syslog) — firewall to specific log aggregation hosts only
Safe to expose publicly (with TLS)
- 80 (HTTP) — acceptable if only used to redirect to 443
- 443 (HTTPS) — your primary public web port
- 587 (SMTP Submission) — for mail servers handling client submissions, with STARTTLS enforced
Quick Firewall Rules
Use whichever firewall frontend your distro ships with. Examples below allow HTTPS and SSH and drop everything else inbound.
ufw (Debian/Ubuntu)
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 443/tcp
ufw enable
firewalld (Fedora/RHEL/Rocky)
firewall-cmd --permanent --set-default-zone=drop
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
nftables (Arch / manual setup)
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport { 22, 443 } accept
Verification
After changing firewall rules, confirm from both sides:
# On the server — confirm the service is listening
ss -tulnp | grep -E ':22|:443'
# From a remote machine — confirm the firewall passes the traffic
nmap -p 22,443 YOUR_SERVER_IP
Troubleshooting
- Port shows as listening but connections are refused externally — the service is bound to
127.0.0.1only. Check the service config (e.g.,ListenAddressin/etc/ssh/sshd_config,bind-addressin MySQL config) and set it to0.0.0.0or a specific interface IP. - Firewall allows the port but traffic still fails — check SELinux or AppArmor:
getenforce(Fedora/RHEL) oraa-status(Ubuntu). SELinux may block a service on a non-standard port; usesemanage port -a -t ssh_port_t -p tcp 2222as an example fix. - ss shows nothing on a port you expect — the service may have failed to start. Check with
systemctl status servicenameandjournalctl -u servicename -n 50. - Port 80/443 already in use on boot — run
ss -tulnp | grep ':80'to find the conflicting process, then decide whether to stop it or reconfigure your new service to use a different port.
Frequently asked questions
- Can I run a service on a port below 1024 without root?
- Yes. Grant the binary the CAP_NET_BIND_SERVICE capability with 'setcap cap_net_bind_service=+ep /path/to/binary', or use systemd's AmbientCapabilities directive. Running the whole service as root just to bind a low port is unnecessary on modern Linux.
- Is it worth changing SSH from port 22 to something like 2222?
- It reduces automated brute-force noise in logs but provides no real security. It's a useful complement to key-based auth and fail2ban, not a replacement. If you change it, update /etc/ssh/sshd_config, open the new port in your firewall, and add a semanage port rule on SELinux systems.
- What is the difference between ss and netstat?
- Both display socket information, but ss queries the kernel's netlink interface directly and is significantly faster on systems with many connections. netstat comes from the legacy net-tools package and is no longer installed by default on most modern distros.
- Why does /etc/services list a port but nothing is listening on it?
- /etc/services is just a reference file — it documents standard assignments but has no effect on what services are running. A port only has traffic if a process has explicitly bound to it, which you can confirm with ss -tulnp.
- My database is listening on 0.0.0.0 — is that a problem?
- It means the database accepts connections on all network interfaces, which is dangerous if your firewall has any gap. Fix it in the service config (bind-address = 127.0.0.1 for MySQL/MariaDB, listen_addresses = 'localhost' for PostgreSQL) so it only accepts local connections, and rely on SSH tunnelling for remote access.
Related guides
Build a Mesh VPN with Nebula
Build a fully self-hosted mesh VPN with Nebula: create a CA, sign node certs, configure lighthouses, enforce group-based firewall rules, and run as a systemd service.
How to Configure a Static IP on Linux
Configure a static IP on Linux using Netplan, NetworkManager (nmcli), or systemd-networkd across Ubuntu, Fedora, Debian, and Arch with verified steps.
Expose a Service with Cloudflare Tunnel
Expose local services to the internet without port-forwarding using Cloudflare Tunnel. Install cloudflared, create a named tunnel, configure ingress rules, and run as a systemd service.
firewalld Zones and Rich Rules in Practice
Assign interfaces to firewalld zones, open services, write rich rules for source-based and rate-limited policies, and manage runtime vs permanent config.