Link to home
Start Free TrialLog in
Avatar of AL_XResearch
AL_XResearchFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Linux: Viewing the status of all ports

This may be a very simple question, in which case I apologize, but for the life of me I can't find it online and know there must be a way.

How do you show the status of all TCP ports on CentOS 7, Linux Mint and Ubuntu ?

I usually use either of the following commands but they only show a small selection of ports - even if I use an 'all' switch - but seem to omit some ports I know to be in use:
  • lsof -P -i -n
  • sudo netstat -tulpn

What I am trying to do is find out the status of specific ports such as 80 or 443. Now the web is working so obviously they are in use by some service but I can't see them in any list. This is on a home Linux Mint install or at work with CentOS. Even if I pipe the result of the above commands to 'grep' and filter for the port I am interested in, nothing comes back.

Keep in mind that I have sudo or root access - so permissions are not an issue.

Specifically: I have a server at my office that needs specific ports open and I can't see them in any list to see if they have 'LISTEN' or 'ESTABLISHED' status. There is no firewall setup at the moment.

Basically I just want a list of all IPv4 ports and their status

If someone could at least point me in the right direction I would be most grateful.
Avatar of arnold
arnold
Flag of United States of America image

What do you mean show status?

netstat -an will reflect all the ports that are in use
LISTEN are the service ports
ESTABLISHED will reflect current connection
TIME_SYN initiating outgoing connection..

sudo lsof -iL80 -i:443 -i:port_of_interest

you can list as many -i:ports as you are inteterested in.
Avatar of Dr. Klahn
Dr. Klahn

Basically I just want a list of all IPv4 ports and their status ...

Do you want the status of all of them?  There are 65,535 TCP ports.  That would print about 1300 pages at 50 lines per page.  And it changes constantly.

Even a list of "commonly used" ports (0-1024) would be lengthy.

https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

As arnold says, better to concentrate on ports you're interested in and/or ports that are active.  If there's nothing listening on a port then that port can be completely ignored, so the vast majority of those 65,535 ports are on no interest at all.

Side note:  netstat -tua should return information on nearly all ports of interest.

root:/home/seagoon> netstat -tua
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:smtp            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:https           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:submission      0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:pop3            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:http            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 www.seagoon.com:pop3       workstation:7276        TIME_WAIT
tcp        0    256 www.bluebottle.com:ssh        workstation:7191        ESTABLISHED

Open in new window


[/code]
Avatar of AL_XResearch

ASKER

Yes I am fully aware that there are 65,535 ports so obviously I am not suggesting listing all ports. What I mean is all ports that are actually in use.

For example I have just tested 'sudo lsof -i:80' on Ubuntu 18.04 and it returned nothing - even though I am using the web to respond to you.

What I am saying is that ports I know to be in use, even if they may be in use by the wrong process, are not listed at all. The 'lsof' has always worked for me before.

For example the below - where is port 80 or 443 ?

User generated image
Neither appears to be in use.  Is there in fact a web server running on the system which is serving on both ports 80 and 443?
Can you define your meaning of in use?

netstat -an |grep -i "listen"

But you want to also see the process ID bound for these?
netstat -laputen
ss -an

the above commands should help, but as mentioned above, your existing command shows those ports were not in use at the time.

$ ss -a | grep :https
tcp    ESTAB      0      0         192.168.1.29:35306    34.197.160.142:https  
tcp    ESTAB      0      0         192.168.1.29:35328    34.197.160.142:https  
tcp    ESTAB      0      0         192.168.1.29:35267    34.197.160.142:https  
tcp    ESTAB      0      0         192.168.1.29:35327    34.197.160.142:https  
tcp    TIME-WAIT  0      0         192.168.1.29:42462     13.224.223.46:https  
tcp    ESTAB      0      0         192.168.1.29:35010      104.22.5.165:https  
tcp    ESTAB      0      0         192.168.1.29:34928    216.58.201.234:https  
tcp    ESTAB      0      0         192.168.1.29:38848     216.58.215.46:https  
tcp    ESTAB      0      0         192.168.1.29:53550      13.107.42.14:https  

Open in new window


also note that most of these  commands can filter the ports and types of connection which is more efficient than grepping

ss -tr -o state established '( dport = :443 )'

Open in new window

lsof can also do that. i leave it as an exercise to figure out the syntax

netstat was not that configurable last time i checked

there are other ways using procfs which i'm not describing either
Dr. Klahn: At least IPv4 port 80 is in use - bound to an Apache server

arnold: I tried this an again it does not show port 80 or 443 and mainly seems to show IPv6 ports (which are not used)

skullnobrains: The command 'netstat -laputen' produces a very short list that does not include IPv4 port 80 whereas 'ss -an' does show IPv4 port 80

Since all these commands are more or less equivalent why do they return such varying responses ? Why is port 80 hidden from all results except for 'ss' ? This is what I mean some ports which are 'open' are not shown yet 'ss' shows the port 80 state as 'LISTEN' - so I would expect to see it on the other command's results.

My understanding is that 'ss' is a new version of 'netstats' and so I would expect they would return the same results, even if the the layout and column change.
As an example I was looking to see if port 21226 was open - but that is not shown in any of the lists, even via 'ss'.

So how can I tell if port 21226 is 'LISTENING' or not ?
ASKER CERTIFIED SOLUTION
Avatar of noci
noci

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I DOUBT port 21226 was open for listening, it seems to be an ephemeral port ("random" assigned port on the CLIENT side of a connection).
If it is LISTENING, the for TCP it needs to be in the LISTEN mode (shown in netstat etc)  for UDP it just needs to be listed.
It it was connected to a webserver it should (most often) show 80 / 443 (or http/https) on the server side.
noci : I just want to see if the port is 'LISTENING' or 'ESTABLISHED' and what processes / PID is using it.

I am not talking about a remote server - only the local one.

Previously lsof or netstat would always show me what I need to know. I can't understand why they are not shown when they are quite obviously in use.
But surely any of these commands should show if 21226 is open or closed ?

For example; if I specifically target the port using 'sudo lsof -i:21226' the command returns nothing - surely there must be a status of some kind ?
Ports are not "open" or "closed" on a linux system, unless a software firewall is installed.  That is a function of the firewall.  Firewalls "close" ports by blocking packets destined for those ports from passing through, or "open" them by allowing those packets to pass to their destination.

On a linux system, a port is in one of three states:

Unused - Nothing is using it
Listening - A process is listening on the port but there is no connection
Connected - A process is connected to the port.  Data may or may not be transferring.

All other states are ephemeral, such as "connection closing" or "timeout."

Netstat reports ports which are listening or connected.  Unused ports don't show up in netstat.  If they did, the listing would go on forever.  The fact that netstat returns nothing for, e.g., port 21226 means that it's not Listening and not Connected, therefore that port is not in use.
Yes I understand the concepts but my point is there are processes using 80 / 443 and trying to connect via 21226 - so I would expect all these varieties of command to show both ports as LISTENING.

So far 'ss' is the only one to show port 80 but nothing shows 21226
Did you start a process that would listen on 21226?  => no then no one is listening
Did a process connect to a remote server? Then the client side port MAY become 21226 or any port in the ephemeral port range.
If you have apache running on your system the following would show that fact:
  netstat -antp | grep apache
  ps ax | grep apache

If you can connect to that service:
   curl -v http://localhost/
Should show some output.
During the curl transfer there would be a short lived session that  would be visible in netstat, lsof etc.
Anything not shown in netstat is NOT active.==> unused...

Open or closed as in firewalled or not needs different commands:
 iptables -L -nv
 ip6tables -L -nv

Those rules determine if access is allowed or not.
(to some extend netstat -rn as well as whole networks can be routed into a blackhole if yo like)


I was trying to not make this more complicated, so I have not mentioned this before:
  • I am working for client who's IT controls the firewall
  • The processes that are accessing the 21226 port and creating Apache server are enclosed inside a Docker container. So I would expect to see a docker or docker-compose process accessing that port - at least something.
Several ways to do this...

Using nmap you can scan inside or outside the machine/container for high detail...

lxd: net17-template-focal # myips
144.217.229.96

lxd: net17-template-focal # sudo nmap -sV -Pn -p 80,443 144.217.229.96
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-10 06:42 CDT
Nmap scan report for ip96.ip-144-217-229.net (144.217.229.96)
Host is up (0.000025s latency).

PORT    STATE SERVICE   VERSION
80/tcp  open  http      Apache httpd 2.4.43 ((Ubuntu))
443/tcp open  ssl/https Apache/2.4.43 (Ubuntu)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.53 seconds

Open in new window


You can also check inside the machine...

lxd: net17-template-focal # netstat -pluten | egrep -e ":80" -e ":443"
tcp6       0      0 :::80                   :::*                    LISTEN      0          348942212  56438/apache2       
tcp6       0      0 :::443                  :::*                    LISTEN      0          348942216  56438/apache2  

Open in new window


You can use lsof, as mentioned above...

lxd: net17-template-focal # sudo lsof -i :80 -i :443
COMMAND    PID     USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
apache2  56438     root    4u  IPv6 348942212      0t0  TCP *:http (LISTEN)
apache2  56438     root    6u  IPv6 348942216      0t0  TCP *:https (LISTEN)
apache2 100776 www-data    4u  IPv6 348942212      0t0  TCP *:http (LISTEN)
apache2 100776 www-data    6u  IPv6 348942216      0t0  TCP *:https (LISTEN)
apache2 100777 www-data    4u  IPv6 348942212      0t0  TCP *:http (LISTEN)
apache2 100777 www-data    6u  IPv6 348942216      0t0  TCP *:https (LISTEN)

Open in new window


Or ss...

lxd: net17-template-focal # ss -pnl | egrep -e :80 -e :443
tcp   LISTEN 0      511                                             *:80                     *:*         users:(("apache2",pid=100777,fd=4),("apache2",pid=100776,fd=4),("apache2",pid=56438,fd=4))       
tcp   LISTEN 0      511                                             *:443                    *:*         users:(("apache2",pid=100777,fd=6),("apache2",pid=100776,fd=6),("apache2",pid=56438,fd=6)) 

Open in new window


There's a difference between listing ports + ephemeral ports used for communication. For "all" ports, you'll simply remove the option to each command which scopes/limits the search to listening ports.

And... knowing all ephemeral ports provides no useful information, as sftp + apache might at some point use the same ephemeral port, so these ports are continuously recycled between all listeners.
To see if port 21226 is listening...

netstat -pluten | egrep :21226

Open in new window


And this is a non-standard port. This port will only have a listener under 2x circumstances...

1) You specifically started a listener on this port, in which case you'll already know if you have a listener.

2) Your machine/container is hacked + it's time to do an expunge/cleanse.
Difference between listening privileged ports (1-1024) + ephemeral ports (>1024).

1) Apache will never listen on port 21226 unless you start an Apache instance targeting this port.

2) Apache might at some point assign port 21226 for an Apache conversation.

Note...

#1 != #2

In this case port 21226 is never a listening port, it's an ephemeral port used to transfer application data back to a client.

https://www.cyberciti.biz/faq/linux-unix-open-ports/ provides a simple, graphic visual of how this works.
Docker processes run in their OWN namespace. So you need to run netstat inside the container ...
Your docker host is not listening on those ports, the docker container (separated from the host) does that.
Filtering possibly needed identifying data (like docker or other containerisation , VM's etc) that are relevant to the question, are also cause for misunderstanding the issue, the implications caused by containerisation, etc cause the right answers to the wrong question.

Separate namespace slightly simplyfied means: the same kernel running with a different datasegment. ("private" process table, private network buffers, private network description, ... etc.)

The process list on the host will also show the processes, the network stacks are kept separated.
Try docker inspect containername to get the data about a container including if it is listening for ports on the host.
(That needs to be specified using -p on docker run, or on the right places in a compose yaml file.)

Then you should see a docker_proxy process to act as an intermediate between the outside world and the container.
Or indeed some iptables MAGIC to NAT the stuff.


noci is correct.

1) The processes that are accessing the 21226 port and creating Apache server are enclosed inside a Docker container. So I would expect to see a docker or docker-compose process accessing that port - at least something.

If you notice above, all the commands I ran are inside an LXD container, which shows processes based on the specific container's namespace.

And, there's no different running Apache at machine level or inside a container.

Privileged Ports != Ephemeral Ports

2) I am working for client who's IT controls the firewall

Then the most likely problem is your client's IT folks are clueless about how Ephemeral Ports work.

Likely they have only opened firewall access for listening ports, which is insufficient.

The entire Ephemeral Port range must be opened, for daemons like Apache + SFTP + many others to work correctly.
https://serverfault.com/questions/121309/how-to-configure-iptables-to-use-apt-get-in-a-server provides a... fairly good overview of how to accomplish this using iptables firewall rules.

And I think this is overly complex.

The simple way to handle this is just to allow all Ephemeral Port I/O, so all daemons work as expected.
With a stetefull firewall you only need to allow for the first packet, all the trailing packet will be allowed as well.
No need to worry about ephemeral ports.
The example quoted by david is far too complicated. All the FTP stuff can be solved with ftp connection tracking and allow RELATED packets.
(or even better by dropping FTP completely, use SCP/SFTP instead.)
The simple way to handle this is just to allow all Ephemeral Port I/O, so all daemons work as expected.
^^ worst advice ever. that is REALLY dangerous.

and yes ss is namespace agnostic while netstat is not ( or maybe features a flag to cross namespaces boundaries )
https://man7.org/linux/man-pages/man8/ip-netns.8.html

note that running ss from within a container should not show the other network connections. that may not be true in docker, or not always but SHOULD be if you expect any mildly decent security.