How to Check Open Ports on a VPS (ss, nmap, and Firewall Basics)
CodexFuse Team · 2026-11-04T04:47:25.942Z · 11 min read min read
Learning how to check open ports on a VPS is the fastest way to answer a question every server owner should ask at least once a month: what is my server actually listening to? A fresh what is VPS hosting plan ships with SSH open and not much else, but every service you install — a web server, a database, a control panel — adds a port. Left unexamined, those ports pile up into attack surface you never chose to have.
This guide walks the complete audit in five methods: ss for the local ground truth, netstat for the legacy systems you will still meet, lsof to name the process behind a port, nmap and nc to verify what the internet can actually reach, and UFW to close what should never have answered in the first place.
How do you check open ports on a VPS?
To check open ports on a VPS, list what the server is listening to with sudo ss -tulnp, then verify what is actually reachable from the internet with a scan from a second machine. Listening and reachable are two different things: ss shows everything the VPS is prepared to answer, while your firewall decides which of those ports the internet can touch.
The full audit runs in five steps:
- Inventory listening sockets with
ss -tuln— your ground truth. - Identify the process behind anything unexpected with
lsof -i :<port>. - Confirm reachability from outside with
nmap(or a quicknc -zvprobe). - Read your firewall rules with
ufw status numberedto see which ports the firewall allows. - Close the exposure you do not need with
ufw deny <port>— and re-check.
What does ss -tuln show you?
ss -tuln is the modern standard for listening-socket inventory — when people ask how to see listening ports in linux, this command is the answer they are really looking for: -t shows TCP, -u shows UDP, -l restricts the output to listening sockets, and -n keeps addresses and ports numeric so no time is wasted on DNS or service-name lookups (Linuxize). Adding -p names the process behind each socket, which turns the output from a mystery list into an actionable one.
The columns read left to right as Netid, State, Recv-Q, Send-Q, Local Address:Port, Peer Address:Port, and Process. A line like tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:* means a web server is accepting HTTPS connections on every IPv4 interface of the VPS. A line bound to 127.0.0.1:3306, by contrast, means MySQL accepts connections only from the VPS itself — local-only listeners like that are fine and should be left alone.
The local address is the most important column in the whole audit. 0.0.0.0:ssh means SSH listens on all IPv4 interfaces, and [::]:ssh is the IPv6 listener (GoLinuxCloud). An application bound to 127.0.0.1:8000 "normally accepts connections only from the same computer" (Sekin). One practical note: -p reveals process names only for sockets you own — for everything else it needs root, so run with sudo or you will see ports without names (Dev.to / mrsaynothing).
What is the difference between a listening port and an open port?
A listening port is a promise: some program has told the kernel it will accept traffic on that port. An open port — in the sense an attacker cares about — is a listening port that is also reachable through your firewall from the network in question. The distinction matters because a VPS commonly listens on far more than it exposes.
The firewall is the gatekeeper between the two: "a firewall makes sure that only the ports you choose are reachable" (Zyvop). The nmap man page uses the same split in its state vocabulary: open means an application is listening, filtered means a firewall or filter is blocking the port (Kerrisk man-pages). A real-world illustration comes from a Coolify troubleshooting write-up, where "the application was listening on port 8000, but my firewall rules did not expose that port publicly" (Medium). One more trap worth knowing: Docker-published ports can bypass UFW, so exposure can be wider than your ss + UFW picture suggests (Zyvop).
Which command replaces netstat?
The replacement for netstat is ss — that is the man page's own verdict, word for word: "This program is mostly obsolete. Replacement for netstat is ss" (manpages.opensuse.org). Netstat belongs to the net-tools collection, which "has had no real maintenance since 2011," and Debian, Ubuntu, RHEL, and Arch have all stopped installing it by default (SSHWorkbench).
Why this matters to you: on the minimal cloud images most VPS hosts ship, netstat -tuln often returns command not found. That is expected — netstat is "absent from many minimal images entirely" (DevCloudLab). You can still install net-tools for the muscle memory, but every guide in this article's arc works with ss, which ships with the iproute2 package already on your system.
How do you find which process is using a port?
lsof -i :<port> names the program listening on a specific port — the fastest answer to "what is this thing on port 8080?" The -i flag selects network files, -n disables hostname lookups, and -P disables port-name conversion so you see real numbers instead of friendly names (Rackspace docs). Running lsof -i :80 prints the command, PID, and user listening on port 80 (LinuxConfig).
Two wider variants cover the common follow-ups: sudo lsof -i -P -n lists every internet connection and listening socket with numeric addresses, and lsof -i TCP:3000 narrows to one protocol. Pair it with ss -tulpn when you want both the socket detail and the process in one pass — between them, no listening port stays anonymous.
What is the fastest way to compare the port-checking tools?
Each tool answers a different question, so the fastest audit uses all of them once, in order:
| Method | Command | What it answers | Runs where |
|---|---|---|---|
ss | sudo ss -tulnp | Which sockets is this server listening on? | On the VPS |
netstat | netstat -tuln | Same, on legacy systems where ss is missing | On the VPS |
lsof | sudo lsof -i :<port> | Which process owns this port? | On the VPS |
nc | nc -zv <host> <port> | Is this one port reachable right now? | From outside |
nmap | nmap -sV -p 1-1000 <vps-ip> | Which ports answer across a whole range? | From outside |
How do you scan a VPS for open ports with nmap?
An nmap scan run from a second machine shows what the internet actually sees — veteran admins call this nmap scan vps ports check, and it is the reality check against your local ss inventory. Install it on the scanner with sudo apt install -y nmap (or dnf), then start targeted: nmap -sV -p 22,80,443 <your-vps-ip> probes just those ports and reports the service and version answering on each (-sV means "probe open ports to determine service/version info" — Kerrisk man-pages).
Four flags carry the rest of the audit. -p 1-65535 scans every TCP port when you need the full sweep; -sS runs the faster SYN scan but needs root ("you need root privileges to build these custom SYN packets... This is the default scan type for privileged users," per the nmap man page — unprivileged users get a connect scan instead); -Pn skips host discovery, which you need when the VPS blocks ping; and --open hides everything except ports that answer. Only ever scan hosts you own or have explicit written permission to test (TechEarl). A full 65,535-port sweep takes a while, so run it inside tmux and let the session survive a dropped connection.
For a single port, nc is quicker: the -z flag "can be used to tell nc to report open ports, rather than initiate a connection," usually with -v for a readable result (Ubuntu nc_openbsd man page). nc -zv your-vps-ip 443 answers with Connection to your-vps-ip 443 port [tcp/https] succeeded! when the port is reachable.
How do you check open ports with UFW?
On Ubuntu and Debian VPSs, sudo ufw status numbered is the firewall's own answer to "what is allowed through?" — whenever you want to ufw check open ports against your ss inventory, start here. The man page documents status [verbose|numbered] for exactly this, and "to see a list of numbered rules, use: ufw status numbered" (manpages.ubuntu.com, noble). Each rule shows its number, action, and port, so the list is the allowlist your scan results should match.
The rule syntax stays readable on purpose. The man page's examples: ufw allow 80/tcp allows all access to TCP port 80, ufw deny 53 denies all access to port 53, and ufw allow 25/tcp opens TCP port 25 to any address on the host. Delete by rule or by number — ufw delete deny 80/tcp or ufw delete 3. For SSH specifically, ufw limit ssh/tcp is the documented hardening shortcut: it denies an IP that "attempts to initiate 6 or more connections within 30 seconds" (Ubuntu ufw man page).
On RHEL-family images (AlmaLinux, Rocky), the equivalent check is sudo firewall-cmd --list-all, which Red Hat documents as giving "a complete overview of the firewalld settings" for the default zone, with firewall-cmd --state confirming the daemon is running.
Which ports should be open on a typical VPS?
After the audit, the question becomes which of the listeners deserve to stay public. The conventional answer for a general-purpose VPS is small: SSH for administration, and HTTP/HTTPS if you serve websites. A widely cited hardening checklist puts it plainly: port 22 for SSH/SFTP should be "open, ideally restricted to your IP," ports 80/443 handle web traffic with "80 only to redirect to 443," and the right posture is "a default-deny firewall that only allows ports 22, 80 and 443" (Custom Web Promotions).
The recognition table below maps what you will commonly see in ss output to whether it should answer the internet:
| Port | Service | Should it answer publicly? | Note |
|---|---|---|---|
| 22 | SSH/SFTP | Yes — restricted to your IP if possible | Rate-limit with ufw limit ssh/tcp |
| 80 | HTTP | Yes, if you serve websites | Ideally only to redirect to 443 |
| 443 | HTTPS | Yes, if you serve websites | Your main public port |
| 53 | DNS | Only if you run a public DNS server | Otherwise it should not answer |
| 25, 465, 587 | SMTP / submission | Only if you run a mail server | Block by default otherwise |
| 3306, 5432 | MySQL / PostgreSQL | No | Bind to 127.0.0.1; "keep databases... closed to the internet" (TechnicalAdda) |
| 6379 | Redis | No | Same treatment as the SQL databases |
| 27017 | MongoDB | No | Historically exposed and attacked when public |
| 8080, 8443 | Alt web / panels | Only if intentionally public | Check what is behind it with lsof -i :8080 |
The database rule deserves the emphasis: "keep databases like MySQL, PostgreSQL, Redis and MongoDB closed to the internet" (TechnicalAdda). If your ss output shows 0.0.0.0:3306, that database is one firewall-rule mistake away from the whole internet — rebind it to 127.0.0.1 or firewall it off now.
How should you lock down a VPS after the audit?
The healthy end state of a port audit is a server where only the ports you chose answer: your SSH port (restricted to your IP or rate-limited), 80 and 443 if you serve websites, and nothing else. On UFW that posture is three commands — ufw default deny incoming, ufw allow 22/tcp, ufw allow 80,443/tcp — followed by ufw status numbered to confirm the allowlist matches your intent.
Then harden the stragglers: rebind databases and caches to 127.0.0.1, delete the UFW rules you do not need with ufw delete <n>, and reconsider whether SSH even needs to face the internet — if you administer the VPS through a tunnel, close 22 to the world and reach the box through a WireGuard VPN guide connection instead. Re-run the whole five-step audit monthly: services creep back in with every install, and a port you never chose is a port you should not keep.
Sources
- Linuxize — "Ss Command in Linux" (ss flags
-t -u -l -p -nsemantics) — https://linuxize.com/post/ss-command-in-linux/ - openSUSE man-pages — netstat(8) ("This program is mostly obsolete. Replacement for netstat is ss") — https://manpages.opensuse.org/
- Rackspace Docs — "Check port use in Linux" (
lsof -i,-n,-Pflags) — https://docs.rackspace.com/docs/check-port-use-in-linux - man7 / Kerrisk — nmap(1) man page (open/filtered states,
-sV,-p,-Pn,--open) — https://man7.org/linux/man-pages/ - Ubuntu manpages (noble) — ufw(8) (
status numbered,allow/deny,limit ssh/tcprate limiting) — https://manpages.ubuntu.com/manpages/noble/man8/ufw.8.html - Red Hat Docs — firewalld (
firewall-cmd --state,--list-all) — https://docs.redhat.com/ - Ubuntu manpages (focal) — nc_openbsd(1) (
-zport-reporting flag) — https://manpages.ubuntu.com/manpages/focal/man1/nc_openbsd.1.html - GoLinuxCloud — ss output bind semantics (
0.0.0.0:sshvs[::]:ssh) — https://www.golinuxcloud.com/ - Zyvop — VPS hardening guide (127.0.0.1 local-only listeners; firewall as gatekeeper; Docker bypassing UFW) — https://www.zyvop.com/
- Sekin — socket binding note ("bound to 127.0.0.1:8000... accepts connections only from the same computer") — https://www.sekin.in/
- Dev.to / mrsaynothing — ss
-pneeds root for others' sockets — https://dev.to/ - SSHWorkbench — net-tools unmaintained since 2011; dropped by Debian/Ubuntu/RHEL/Arch — https://www.sshworkbench.com/
- LinuxConfig —
lsof -i :80example — https://linuxconfig.org/ - Custom Web Promotions — VPS hardening checklist (22/80/443 default-deny posture) — https://www.custom-web-promotions.com/
- TechnicalAdda — VPS hardening (keep MySQL/PostgreSQL/Redis/MongoDB closed to the internet) — https://www.technicaladda.in/
- TechEarl — nmap scanning ethics (only scan hosts you own or have written permission to test) — https://www.techearl.com/
- Medium — Coolify guide (listening on 8000 but not firewall-exposed) — https://medium.com/
Frequently Asked Questions
How do I check open ports on a VPS without installing anything?
Use ss, which ships with every modern Linux distribution as part of iproute2. sudo ss -tuln lists all listening TCP and UDP sockets with numeric addresses — no installs, no rootless surprises. If you need the process behind a socket, sudo ss -tulpn adds it.
What is the difference between ss -tln and ss -tuln?
ss -tln shows listening TCP sockets only, while ss -tuln adds listening UDP sockets. Always include -u in a security audit: DNS resolvers, NTP, and many game and VPN services listen on UDP, and a TCP-only check misses them entirely.
Can I check open ports on a VPS from my laptop instead of SSH?
Yes — an external scan is how you check open ports on vps hosts from your laptop without SSH access. From your laptop run nmap -sV -p 22,80,443 your-vps-ip for the key ports, or a single-port probe with nc -zv your-vps-ip 443. The external scan shows what attackers see, which can differ from what ss reports inside the VPS.
Why does ss show ports that my firewall blocks?
Because ss reads the kernel's socket table, not the firewall ruleset. A program listening on port 8080 appears in ss even if UFW drops every packet to it. That is why the audit has two halves: ss for what listens, ufw status numbered plus an external nmap scan for what actually answers.
Should I close port 22 on my VPS?
Do not close it unless you have another way in — losing SSH means losing the server. Instead, restrict it: limit it to your IP in UFW, rate-limit it with ufw limit ssh/tcp, or hide it behind a VPN so it never answers the public internet at all.

