So there is a process running on your machine and you know it has opened one or more ports but you don’t know the port numbers.
Let’s find out how to retrieve them!
Legacy Network Tools (netstat)
Netstat is the good old go-to tool to figure out all about open network connections on a Linux machine.
These days it is getting more and more replaced by the newer ss tool, but it is still installed on a lot of machines.
Without sudo
If you are a regular user and you don’t use sudo you can only find out the open ports for processes that run under your own user ID.
netstat -lntp
The flags we use for netstat have the following meaning:
| Netstat Flag | Description |
| l | Only print listening sockets |
| n | Print ports as numbers (instead of printing the names from /etc/services) |
| t | Only print TCP sockets |
| p | Print the process ID and the name of the program that listens on a socket |
Output:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 81.169.224.2:25 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:6789 0.0.0.0:* LISTEN 546120/nc
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 ::1:25 :::* LISTEN -
As you can see here netstat prints the PID and the program name only for one process. This process is a netcat process that was started with our user account with the command nc -l 6789 and consequently listens on port 6789. The processes that listen on the other ports were started by different users or root. Therefore we can see neither their PID nor their program name. They are off-limits to us.
So if we want to just get the port of our own nc process we can use this command:
netstat -lntp | grep nc
Output:
tcp 0 0 0.0.0.0:6789 0.0.0.0:* LISTEN 546120/nc
Of course, we knew before that our process was running on port 6789. But now we know how to figure it out for all other processes, too.
What if there are multiple processes with the same name?
If there are multiple processes running that have the same name you have to grep for the process ID instead of the process name.
To do this execute this command first:
ps aux | grep <your_process_name>
Now you have to figure out the correct process (here you are on your own because this depends on your circumstances) and copy its PID.
Now you can grep for the open ports of the correct process with:
netstat -lntp | grep <your_process_id>
With sudo
If we run netstat as root or with sudo we have full access to all process names:
$ sudo netstat -lntp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 611/sshd: /usr/sbin
tcp 0 0 81.169.224.2:25 0.0.0.0:* LISTEN 900/exim4
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 900/exim4
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 543551/apache2
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 543551/apache2
tcp6 0 0 :::22 :::* LISTEN 611/sshd: /usr/sbin
tcp6 0 0 ::1:25 :::* LISTEN 900/exim4
So to figure out the open ports of a process by the name of the process we can just use this command:
sudo netstat -lntp | grep <your_process_name>
If we try it out with Apache
sudo netstat -lntp | grep apache2
we get this result:
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 543551/apache2
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 543551/apache2
So Apache runs on the ports 443 (SSL) and 80 (unencrypted HTTP) which is not really a surprise.
Modern Network Tools (ss)
The modern replacement for netstat is called ss. Thankfully, for our use case here, it takes exactly the same parameters as netstat. Only the output looks a little bit different. But not by much.
If we enter the most basic command from above but replace netstat with ss we get the following output:
ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 20 81.169.224.2:25 0.0.0.0:*
LISTEN 0 20 127.0.0.1:25 0.0.0.0:*
LISTEN 0 128 0.0.0.0:443 0.0.0.0:*
LISTEN 0 1 0.0.0.0:6789 0.0.0.0:* users:(("nc",pid=546120,fd=3))
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 20 [::1]:25 [::]:
The order of the fields has changed, the IPv6 addresses are formatted differently, as well as the process column. The basic format is still very similar.
This means our commands are nearly unchanged.
Get the ports of a process by process name without sudo:
ss -lntp | grep <your_process_name>
And with sudo:
sudo ss -lntp | grep <your_process_name>
If there are multiple processes with the same name you have to find the PID of the correct process and grep for the PID instead of the process name as described above.
Admittedly, the output can be more ugly in a real-world example:
LISTEN 0 128 0.0.0.0:443 0.0.0.0:* users:(("apache2",pid=546080,fd=4),("apache2",pid=546079,fd=4),("apache2",pid=546078,fd=4),("apache2",pid=545635,fd=4),("apache2",pid=545406,fd=4),("apache2",pid=543577,fd=4),("apache2",pid=543576,fd=4),("apache2",pid=543575,fd=4),("apache2",pid=543574,fd=4),("apache2",pid=543573,fd=4),("apache2",pid=543551,fd=4))
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("apache2",pid=546080,fd=3),("apache2",pid=546079,fd=3),("apache2",pid=546078,fd=3),("apache2",pid=545635,fd=3),("apache2",pid=545406,fd=3),("apache2",pid=543577,fd=3),("apache2",pid=543576,fd=3),("apache2",pid=543575,fd=3),("apache2",pid=543574,fd=3),("apache2",pid=543573,fd=3),("apache2",pid=543551,fd=3))
Just look for the IP address for orientation and you are fine.