Knowing how to check open ports in Linux is an essential skill for system administrators, security professionals, and DevOps engineers. Whether you are validating firewall rules, hardening a server, or troubleshooting a network service, scanning for open ports reveals which services are reachable from the network. This guide explains multiple reliable methods to check open ports on a host or across a network using popular tools such as nmap, netcat (nc), built-in utilities like ss and lsof, and the Bash /dev/tcp pseudo-device. Each method includes practical examples and sample output plus actionable tips for interpreting results and avoiding false positives.
What Is an Open Port and Why It Matters
An open port is a TCP or UDP port on a host that will accept incoming packets and possibly establish a network connection. A service “listening” on a port does not necessarily mean the port is reachable from outside the host — a local firewall or network ACL can block access, producing a filtered or closed result when scanned remotely. Open ports are necessary for functionality (HTTP on 80/443, SSH on 22, DNS on 53), but each open port increases the attack surface. Regularly auditing open ports helps you reduce exposed services, apply least privilege, and detect unexpected daemons.
Remote Port Scan with nmap (TCP)
Use nmap for comprehensive remote port scans. The example below scans all TCP ports on the target host and reports state (open/closed/filtered). Replace the IP with your target host or range. Running with sudo improves accuracy (raw sockets), and scanning all 65535 ports uses the -p- option.
sudo nmap -sT -p- 10.10.8.8 Starting Nmap 7.80 ( https://nmap.org ) at 2026-03-04 12:00 UTC Nmap scan report for 10.10.8.8 Host is up (0.0012s latency). Not shown: 65532 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https 8069/tcp open unknown MAC Address: 08:00:27:05:49:23 (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 2.35 seconds
The command runs nmap with flags -sT (TCP connect scan) and -p- (scan all ports). The output lists ports and their state. “open” means a service accepted the TCP connection; “closed” means port reachable but no service; “filtered” means a firewall dropped packets so the scanner cannot determine state.
Remote UDP Scan with nmap
UDP scans are slower and less reliable due to stateless nature and rate limiting, but nmap supports them with -sU. Use when you need to find UDP services such as DNS (53), NTP (123), or custom protocols.
sudo nmap -sU -p- 10.10.8.8 Starting Nmap 7.80 ( https://nmap.org ) at 2026-03-04 12:05 UTC Nmap scan report for 10.10.8.8 Host is up (0.0021s latency). Not shown: 65532 open|filtered ports PORT STATE SERVICE 53/udp open domain 123/udp open ntp 161/udp open snmp Nmap done: 1 IP address (1 host up) scanned in 19.12 seconds
Here -sU tells nmap to scan UDP ports. UDP results can be “open”, “closed”, or “open|filtered” when responses are ambiguous. Expect UDP scans to take longer; consider specifying a range for speed.
Quick TCP Port Checks with netcat (nc)
Netcat is a lightweight tool for simple port checks. Use it for quick checks or scripting. The -z flag makes nc scan without sending data, and -v increases verbosity to report success/failure.
nc -z -v 10.10.8.8 20-90 nc: connect to 10.10.8.8 port 20 (tcp) failed: Connection refused nc: connect to 10.10.8.8 port 21 (tcp) failed: Connection refused Connection to 10.10.8.8 22 port [tcp/ssh] succeeded! Connection to 10.10.8.8 80 port [tcp/http] succeeded! Connection to 10.10.8.8 90 port [tcp] failed: No route to host
The command uses netcat with flags -z (zero-I/O mode) and -v (verbose). The output shows which ports connect successfully. “Connection refused” indicates the target IP responded but no service is listening, whereas “No route to host” suggests network issues or filtering.
UDP Scan with netcat
For UDP, add -u. Note that UDP scans often produce false negatives because many services don't respond unless given valid input.
nc -z -v -u 10.10.8.8 53 123 Connection to 10.10.8.8 53 port [udp/domain] succeeded! Connection to 10.10.8.8 123 port [udp/ntp] failed: Connection refused
Flags: -z (scan only), -v (verbose), -u (use UDP). The “succeeded” line indicates the UDP packet elicited a response; UDP failures may still be open but silent.
Check Listening Ports Locally with ss
Use ss to inspect sockets on the local host. It shows listening ports and the process using the socket. This is the modern replacement for netstat on many distributions.
ss -tuln Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* tcp LISTEN 0 100 127.0.0.1:8069 0.0.0.0:* tcp LISTEN 0 4096 0.0.0.0:80 0.0.0.0:* udp UNCONN 0 0 0.0.0.0:123 0.0.0.0:*
The command uses ss with flags -tuln: -t (TCP), -u (UDP), -l (listening sockets), -n (numeric output). The output lists local listening sockets and their bind addresses. Services bound to 127.0.0.1 are not reachable remotely without port forwarding.
Identify Processes with lsof
lsof maps open network sockets to the owning process and PID. Use it when you need to see which binary is bound to a specific port and for quick remediation (stopping or reconfiguring the service).
sudo lsof -i -P -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1024 root 3u IPv4 12345 0t0 TCP *:22 (LISTEN) nginx 2048 www-data 6u IPv4 23456 0t0 TCP *:80 (LISTEN) odoo 3096 odoo 9u IPv4 34567 0t0 TCP 127.0.0.1:8069 (LISTEN)
The command runs lsof with flags -i (network files), -P (show port numbers), and -n (no DNS lookups). The output maps process name, PID, user, and the address:port. Use the PID to investigate or stop the service.
Check Specific Port Reachability with Bash /dev/tcp
For quick scripted checks without external tools, use Bash's /dev/tcp pseudo-device. The example uses timeout to avoid long hangs. This method attempts a raw TCP connection and is useful for simple, programmatic health checks.
timeout 5 bash -c 'cat < /dev/tcp/kernel.org/443' && echo "Port open" || echo "Port closed" Port open
The command runs timeout 5 to limit the operation, and the Bash /dev/tcp/host/port device attempts a connection. If the connection succeeds, the shell returns a zero exit code and “Port open” is printed. If not, the command times out or fails and prints “Port closed”.
When Remote Scans and Local Listings Differ
It is common to see differences between remote scans (nmap/nc) and local listings (ss/lsof). Common reasons:
– A service is bound only to loopback (127.0.0.1) and not reachable remotely.
– A host-based firewall (iptables/nftables/ufw) or cloud network ACL blocks external access.
– Network devices (load balancers, NAT) alter visibility.
Always correlate local binds (ss/lsof) with firewall rules (iptables/nft, ufw, firewalld) and cloud security groups to understand actual exposure.
Best Practices for Port Scanning and Hardening
Follow these operational and security practices:
– Scan from both internal and external networks to detect differences in exposure.
– Use least privilege: only open ports required by your applications.
– Keep services up-to-date and minimize public-facing management interfaces like SSH by using jump hosts or VPN.
– Implement rate-limiting and IDS/IPS for exposed services.
– Automate periodic scans (safe scan window) and alert on changes.
Conclusion
Checking open ports in Linux is a routine but critical task for ensuring service availability and security. Use nmap for comprehensive remote scans, netcat for quick checks and scripting, ss and lsof to inspect local listening sockets and associated processes, and Bash /dev/tcp for lightweight checks without external binaries. Combine these tools with firewall and network ACL reviews to get an accurate picture of what is exposed. Regular auditing, monitoring, and automation will reduce your attack surface and help detect unexpected services early.