Check Open Ports in Linux: nmap, netcat, and Bash

By 

Updated on

11 min read

Checking open ports on a Linux system from the command line

Whether you are troubleshooting network connectivity issues or configuring a firewall, one of the first things to check is what ports are actually open on your system.

This guide covers the command-line tools for checking open ports on a Linux system: nmap, netcat, telnet, and the Bash /dev/tcp pseudo-device. It also shows how to distinguish a closed port from traffic filtered by a firewall or another network device.

What Is an Open Port

A listening port is a network port that an application listens on. You can get a list of the listening ports on your system by querying the network stack with commands such as ss or netstat . A listening port can still appear filtered to a remote scanner when a firewall or another network device blocks the probes.

An open port is a network port that accepts incoming packets from remote locations. When nothing listens on a port, or a firewall rejects the request outright, the client is refused immediately, which is what produces errors such as SSH connection refused .

For example, if you are running a web server that listens on ports 80 and 443 and those ports are open on your firewall, anyone (except blocked IPs) will be able to access websites hosted on your web server using their browser. In this case, both 80 and 443 are open ports.

Open ports may pose a security risk because each one can be used by attackers to exploit a vulnerability. You should expose only the ports needed for your application and close all others.

Check Open Ports with nmap

Nmap is a powerful network scanning tool that can scan single hosts and large networks. It is mainly used for security audits and penetration testing.

If available, nmap is usually the most complete tool for port scanning. Beyond basic port discovery, it can also perform service detection, version probing, and host discovery.

Warning
Scan only hosts that you own or have written authorization to test. Unauthorized scans can trigger abuse reports and may violate provider policies or applicable law.

The following command scans for all TCP ports on a remote host:

Terminal
nmap -sT -p- 10.10.8.8

The -sT flag tells nmap to scan for TCP connections and -p- scans all 65535 ports. Without -p-, nmap scans only the 1000 most common ports.

output
Starting Nmap 7.95 ( https://nmap.org ) at 2026-03-01 21:00 CET
Nmap scan report for 10.10.8.8
Host is up (0.0012s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 0.41 seconds

The output above shows that only ports 22 and 80 are open on the target system.

To scan for UDP ports, use -sU instead of -sT:

Terminal
sudo nmap -sU -p- 10.10.8.8

Scanning all 65535 ports takes a while, and most of the time you only care about one of them. Pass the port number to -p to check a single port:

Terminal
nmap -p 80 10.10.8.8
output
Starting Nmap 7.95 ( https://nmap.org ) at 2026-09-01 14:12 CEST
Nmap scan report for 10.10.8.8
Host is up (0.0011s latency).

PORT   STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds

The STATE column is the part to read. open means a service accepted the connection, and closed means the host answered but nothing is listening on that port. A filtered result means a firewall, router rule, or another network obstacle prevented nmap from determining whether the port is open or closed.

For more information, visit the nmap man page to read about all available options.

Check Open Ports with netcat

netcat (or nc) is a command-line tool that can read and write data across network connections using the TCP or UDP protocols.

With netcat you can scan a single port or a port range. To scan for open TCP ports on a remote machine with IP address 10.10.8.8 in the range 20-80, run:

Terminal
nc -z -v 10.10.8.8 20-80

The -z option tells nc to scan only for open ports without sending any data, and -v enables verbose output.

The output will look something like this:

output
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!

To print only the open ports, filter the results with the grep command :

Terminal
nc -z -v 10.10.8.8 20-80 2>&1 | grep succeeded
output
Connection to 10.10.8.8 22 port [tcp/ssh] succeeded!
Connection to 10.10.8.8 80 port [tcp/http] succeeded!

To scan for UDP ports, pass the -u flag:

Terminal
nc -z -v -u 10.10.8.8 20-80 2>&1 | grep succeeded

Because UDP has no connection handshake, a probe that returns no error does not prove that a service is listening. Treat this as a preliminary check and confirm the result with a protocol-specific request or an nmap -sU -sV scan.

Info
The 2>&1 construct redirects standard error to standard output, which is necessary here because nc writes connection status to stderr.

Check a Single Port on a Remote Server with telnet

When you need to test a single TCP port on a remote server, telnet can open the connection without scan options. Provide the host and port as arguments:

Terminal
telnet 10.10.8.8 22

If the port is open, telnet completes the connection and hands you the raw session, which is why you can see the SSH banner in the output below:

output
Trying 10.10.8.8...
Connected to 10.10.8.8.
Escape character is '^]'.
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5

Press Ctrl+] to get back to the telnet> prompt, then type quit to close the session.

When nothing listens on the port, or the firewall rejects the packet outright, the attempt fails right away:

output
Trying 10.10.8.8...
telnet: Unable to connect to remote host: Connection refused

If telnet remains on the Trying line until it times out, no TCP connection was established. A firewall that drops packets can cause this behavior, but so can a routing problem, an unavailable host, packet loss, or an upstream network filter. Check host reachability and the network path before deciding where the connection was blocked.

Two limits are worth knowing before you rely on this method. telnet speaks only TCP, so it cannot test UDP ports, and it is no longer installed by default on most current distributions. Install it with sudo apt install telnet on Ubuntu, Debian, and Derivatives, or sudo dnf install telnet on Fedora, RHEL, and Derivatives.

Check Open Ports with Bash /dev/tcp

Another way to check whether a specific TCP port is open is to use the Bash /dev/tcp/HOST/PORT pseudo-device.

When you open this pseudo-device, Bash attempts a TCP connection to the specified host and port. If the connection succeeds, the remote host accepted the connection.

Bash also supports /dev/udp/HOST/PORT, but opening a UDP socket alone does not show whether a service is listening. UDP has no connection handshake, so use a protocol-specific request or a UDP-aware scanner when you need to test a UDP service.

The following if..else statement checks whether port 443 on kernel.org is open:

sh
if timeout 5 bash -c '</dev/tcp/kernel.org/443 &>/dev/null'
then
  echo "Port is open"
else
  echo "Port is closed"
fi
output
Port is open

The default connection timeout for pseudo-devices is very long, so the timeout command is used to abort the attempt after 5 seconds. If the connection to kernel.org port 443 succeeds, the test returns true.

To check a range of ports, use a for loop :

sh
for PORT in {20..80}; do
  timeout 1 bash -c "</dev/tcp/10.10.8.8/$PORT &>/dev/null" && echo "port $PORT is open"
done
output
port 22 is open
port 80 is open

Check Which Ports the Firewall Allows

Scanning tells you what a client can reach, but it does not identify the device that blocked a probe. When a port comes back as filtered, check the firewall on the target host as well as any cloud firewall, router, or other filter along the network path.

On Ubuntu and other systems configured with ufw , display its status and rules with:

Terminal
sudo ufw status

When firewalld is active, find the zone attached to the incoming interface before listing its rules:

Terminal
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --list-all

Replace public with the active zone shown on your system. Read both the services and ports lines because a named service such as ssh can allow a port without listing its number under ports.

If nftables manages the firewall directly, inspect the complete ruleset:

Terminal
sudo nft list ruleset

Use iptables only when maintaining a legacy iptables ruleset. The iptables command covers IPv4, while IPv6 rules require ip6tables.

Firewall rules alone do not prove that a port is reachable because the service must also be listening on the correct address. When you need to add a rule, opening a port in the firewall covers ufw, firewalld, nftables, and legacy iptables, along with local and remote verification.

Troubleshooting

nmap: command not found
nmap is not installed by default on all distributions. Install it with sudo apt install nmap on Ubuntu, Debian, and Derivatives, or sudo dnf install nmap on Fedora, RHEL, and Derivatives.

nc is not available or behaves differently
Some distributions ship ncat (from the nmap project) instead of the traditional netcat. The flags are similar but not identical. On systems without either, use the Bash /dev/tcp method instead.

nmap shows a port as filtered instead of open or closed
A filtered state means packet filtering or another network obstacle prevents nmap from determining whether the port is open or closed. The service may be listening, but its host firewall, a router, or an upstream filter can block the probes. Check each filtering layer along the network path.

UDP scan results are unreliable
UDP scanning is inherently less reliable than TCP scanning because UDP has no handshake. nmap marks ports as open|filtered when there is no response. Use -sV to attempt service detection and get a more definitive result.

nc -z shows a port as open but the service is unreachable
The port is listening but the application may require TLS, authentication, or a specific protocol. Use nmap -sV to probe the service version and confirm what is running.

Quick Reference

For a printable quick reference, see the nmap cheatsheet and the netcat cheatsheet .

CommandDescription
nmap -sT -p- HOSTScan all TCP ports on a host
sudo nmap -sU -p- HOSTScan all UDP ports on a host
nmap -p PORT HOSTCheck the state of a single TCP port
nc -z -v HOST PORT_RANGEScan a TCP port range with netcat
nc -z -v -u HOST PORT_RANGEProbe a UDP port range with netcat
nc -z -v HOST PORT_RANGE 2>&1 | grep succeededShow only open ports
telnet HOST PORTTest a single TCP port on a remote server
timeout 5 bash -c '</dev/tcp/HOST/PORT'Test a single TCP port with Bash
sudo ufw statusShow ufw status and rules
sudo firewall-cmd --get-active-zonesFind the active firewalld zones
sudo firewall-cmd --zone=ZONE --list-allList rules for a firewalld zone
sudo nft list rulesetInspect the complete nftables ruleset

FAQ

What is the difference between a listening port and an open port?
A listening port is one that a local application has bound to and is waiting for connections. An open port is a listening port that is reachable from the scanner. A listening port can appear filtered externally when a firewall or another network device prevents the scanner from determining its state. A closed result means the host was reachable but no application accepted the connection on that port.

How do I check if a specific port is open on my own machine?
Use ss -tlnp | grep PORT or netstat -tlnp | grep PORT to check listening ports locally. See How to Check Listening Ports in Linux for more detail.

Can I scan ports without installing nmap?
Yes. Use nc -z -v HOST PORT_RANGE for a range scan, telnet HOST PORT for one port on a remote server, or the Bash /dev/tcp/HOST/PORT pseudo-device. The Bash example avoids a dedicated scanner when both Bash and the timeout command are already installed.

Do I need root to scan ports?
TCP connect scans (nmap -sT) and nc work as a regular user. UDP scans (nmap -sU) and SYN scans (nmap -sS) require root or sudo because they send raw packets.

Conclusion

Use nmap for thorough port scanning, netcat for quick range checks, telnet for a single TCP port, and the Bash /dev/tcp pseudo-device when Bash and timeout are already available. When a port scans as filtered, check the host firewall and the rest of the network path before you assume the service is down, and use tcpdump when you need to watch the packets themselves.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page