Analyze Network Ports and Sessions with netstat in Linux

CompTIABeginner
Practice Now

Introduction

In this lab, you will learn how to use the netstat command to analyze network activity on a Linux system. You will explore fundamental concepts such as network ports, sockets, and active connections to gain insight into how services communicate over the network.

You will start by listing all active sockets and then filter the results to focus on listening TCP and UDP ports, mapping them to their running services. To see these concepts in action, you will generate a new connection by browsing a website and then use netstat to identify the newly created ESTABLISHED session and its associated ephemeral port.

List All Active and Listening Sockets with netstat -a

In this step, you will begin exploring your system's network activity using the netstat command. This command is a fundamental tool for network administrators and developers, providing insights into network connections, routing tables, and interface statistics. We will start with the -a option, which instructs netstat to display all active sockets, including both connections to remote systems and ports that are "listening" for new incoming connections.

First, ensure you are in your default working directory. All commands in this lab will be run from the terminal.

Now, let's list all sockets. In your terminal, type the following command and press Enter:

netstat -a

You will see a large amount of output. Don't worry, we will break it down. The output shows all types of sockets, including TCP, UDP, and UNIX domain sockets.

Let's examine the structure of the output. It should look similar to this (the exact details on your system will vary):

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
tcp        0      0 localhost:6010          0.0.0.0:*               LISTEN
tcp        0     52 labex-vm:ssh            192.168.0.10:54321      ESTABLISHED
tcp6       0      0 [::]:http-alt           [::]:*                  LISTEN
udp        0      0 0.0.0.0:bootpc          0.0.0.0:*
...
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ]         DGRAM                    23456    /run/systemd/notify
unix  2      [ ACC ]     STREAM     LISTENING     34567    /tmp/.X11-unix/X0
...

Here is a breakdown of the most important columns for Internet connections:

  • Proto: The protocol used by the socket, such as tcp (for TCPv4), tcp6 (for TCPv6), or udp.
  • Local Address: Your system's IP address and the port number it is using for this connection. The port is the number after the colon (:). An address of 0.0.0.0 or [::] means the port is listening on all available network interfaces on your machine.
  • Foreign Address: The IP address and port number of the remote system. If the state is LISTEN, this will typically be 0.0.0.0:* or [::]:*, indicating it's waiting for a connection from any address.
  • State: This is crucial for TCP connections.
    • LISTEN: The application is waiting for an incoming connection on the specified Local Address port. This is a server-side state.
    • ESTABLISHED: A connection is active and data can be transferred between the local and foreign addresses.
    • Other states like TIME_WAIT or CLOSE_WAIT relate to the process of closing a TCP connection.

Take a moment to scroll through the output and identify any entries in the LISTEN state. These represent services on your system that are ready to accept network connections. This is a direct look at the Transport Layer (Layer 4) in action.

Filter for Listening TCP/UDP Ports with sudo netstat -tulnp

In the previous step, the netstat -a command gave us a complete but lengthy list of all sockets. To make this information more useful, we need to filter it. In this step, you will learn how to use specific options with netstat to display only the listening TCP and UDP ports and, most importantly, to identify which programs are using them.

To see the program name associated with a port, you often need administrative privileges, as the process might be owned by the system or another user. This is why we use the sudo command. In the LabEx environment, you can use sudo without a password.

Let's run a more focused netstat command. In your terminal, type the following:

sudo netstat -tulnp

Let's break down these options, as they are commonly combined:

  • t: Displays TCP connections.
  • u: Displays UDP connections.
  • l: Displays only listening sockets. This is our primary filter to see which services are waiting for connections.
  • n: Displays numerical addresses. This prevents netstat from trying to resolve IP addresses and port numbers into hostnames and service names (e.g., it shows 22 instead of ssh), which makes the command run much faster.
  • p: Shows the process ID (PID) and name of the program to which the socket belongs. This requires sudo to see all processes.

After pressing Enter, your output will be much shorter and more informative. It will look something like this:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      779/systemd-resolve
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3422/sshd
udp        0      0 127.0.0.53:53           0.0.0.0:*                           779/systemd-resolve

Notice the new column at the end: PID/Program name. This is the key piece of information. You can now directly map a listening port to the exact application that opened it. For example, in the output above, you can see that port 22 (the standard port for SSH) is being used by the sshd program with a Process ID of 3422.

This command is extremely powerful for system administrators. It allows you to quickly verify which services are running and exposed to the network, which is essential for both troubleshooting and security auditing.

Map Listening Ports to Running Services

In this step, you will solidify your understanding of the link between running applications and listening network ports. You've seen how to list existing services with netstat. Now, you will start your own simple web service and watch it appear in the netstat output, demonstrating this relationship in real-time.

We will use Python's built-in http.server module to quickly launch a web server. This is a convenient tool for development and testing.

  1. First, let's start the web server. We'll tell it to listen on port 8080, a common alternative port for web services. In your terminal, run the following command. Note that your terminal will appear to "hang" as it is now actively running the server.

    python3 -m http.server 8080
    

    You should see output indicating the server has started:

    Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
    
  2. This terminal is now occupied by the web server process. You need a new terminal to run other commands. In the LabEx environment, you can open a new terminal tab by clicking the "plus" icon in the terminal window or by using the menu (File -> New Tab).

  3. In your new terminal tab, run the netstat command again to see the list of listening ports.

    sudo netstat -tulnp
    
  4. Examine the output carefully. You will now see a new entry for port 8080.

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      779/systemd-resolve
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3422/sshd
    tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      12345/python3
    udp        0      0 127.0.0.53:53           0.0.0.0:*                           779/systemd-resolve
    ...
    

    As you can see, the system now reports that the python3 program (with a specific PID, like 12345) is in the LISTEN state on port 8080. You have successfully launched a service and confirmed it is listening for network connections.

  5. Now, let's stop the service. Go back to your first terminal tab (the one running the Python server) and press Ctrl+C. This will interrupt and terminate the server process.

  6. Return to the second terminal tab and run the netstat command one last time.

    sudo netstat -tulnp
    

    The line for port 8080 will be gone, proving that when an application is terminated, it no longer listens on the port.

Create a New Connection by Browsing a Website

In this step, you will shift your focus from server-side listening ports to client-side active connections. So far, you have observed services waiting for others to connect to them. Now, you will initiate a connection from your machine to a remote server and watch the connection being formed. We will use the command-line tool curl to simulate visiting a website.

To observe this fleeting event, we will use the watch command, which repeatedly runs another command, allowing us to see changes in the output of netstat in near real-time.

  1. First, let's set up our monitoring window. In your terminal, run the following command. This will execute netstat -antp every two seconds and display the results, continuously refreshing the screen.

    watch netstat -antp
    
    • a: Shows all sockets.
    • n: Shows numerical addresses.
    • t: Shows TCP connections only.
    • p: Shows the PID/Program name.

    Your terminal will now be filled with the netstat output, which updates automatically. Keep this terminal open and visible.

  2. Now, you need to open a new terminal tab to issue the command that will create the connection. Click the "plus" icon on your terminal's tab bar.

  3. In the new terminal tab, you will use curl to fetch the homepage of the LabEx website. The > symbol redirects the HTML output to /dev/null so it doesn't clutter your screen.

    curl https://www.labex.io > /dev/null
    
  4. As soon as you press Enter, quickly switch your view back to your first terminal tab (the one running watch). You will see a new connection appear for a few seconds. It will look something like this:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    ...
    tcp        0      0 172.17.0.2:45678        104.21.5.141:443        ESTABLISHED 13579/curl
    ...
    
    • Notice the State is ESTABLISHED, indicating an active connection.
    • The Foreign Address shows the IP address of the labex.io server and the port 443 (the standard for HTTPS).
    • The PID/Program name column clearly identifies curl as the program that initiated this connection.
    • The Local Address uses a high-numbered, random port (like 45678 in the example). This is an ephemeral port, which we will discuss in the next step.
  5. Once the curl command finishes downloading (which is very fast), you will see the connection state change to TIME_WAIT or FIN_WAIT before it disappears entirely from the list.

  6. You can now stop the watch command. Go to the first terminal tab and press Ctrl+C. You can also close the second terminal tab.

Identify an ESTABLISHED Session and Ephemeral Ports

In this final step, you will consolidate your understanding by examining a persistent, active connection. This will allow you to clearly identify a network "session" and see how your system uses temporary, or "ephemeral," ports for client-side communication.

An ESTABLISHED connection in netstat's output represents an active session (OSI Layer 5), where two applications are ready to exchange data. In the previous step, the curl session was very brief. To study a session more easily, we will create one that stays open using SSH.

First, let's define an important concept: ephemeral ports. When your computer (the client) connects to a server on a well-known port (like port 22 for SSH or 443 for HTTPS), your operating system must assign a port for its side of the conversation. It picks a temporary, unused port from a high-numbered range (typically above 32768). This is called an ephemeral port. This mechanism allows your single machine to have many separate connections to the same server port, for example, having multiple browser tabs open to the same website.

  1. To create a stable, observable session, you will SSH from your lab machine back into itself. In your terminal, run the following command:

    ssh localhost
    

    The first time you do this, you may see a message about the authenticity of the host. This is normal.

    The authenticity of host 'localhost (127.0.0.1)' can't be established.
    ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
    Are you sure you want to continue connecting (yes/no/[fingerprint])?
    

    Type yes and press Enter to continue.

    It will show you a prompt to enter the password. You don't need to enter the password, just hang there.

  2. Open a new terminal tab by clicking the "plus" icon. We need this new terminal to run netstat without disturbing our active SSH session.

  3. In the new terminal, run netstat again, but this time, we will use the grep command to filter the output and show only the lines containing ESTABLISHED. This makes it much easier to find active sessions.

    netstat -antp | grep ESTABLISHED
    
  4. The output will show all currently active TCP connections. You may see a warning that not all processes could be identified, which is expected since we are not using sudo. You should see your original SSH connection to the lab environment and the new one you just created to localhost.

    (Not all processes could be identified, non-owned process info
     will not be shown, you would have to be root to see it all.)
    tcp        0      0 172.16.50.192:22        47.251.66.143:36882     ESTABLISHED -
    tcp        0      0 127.0.0.1:46280         127.0.0.1:22            ESTABLISHED 5449/ssh
    tcp        0      0 127.0.0.1:22            127.0.0.1:46280         ESTABLISHED -
    

    Let's analyze the new localhost connection, identified by the 127.0.0.1 address:

    • The server-side of the connection is 127.0.0.1:22, which is the SSH server (sshd) listening on port 22. It has an established connection from 127.0.0.1:46280. The program information is - because the sshd process is owned by the root user, and we did not use sudo.
    • The client-side is 127.0.0.1:46280 connected to 127.0.0.1:22. The program is clearly identified as 5449/ssh.
    • The port 46280 is the ephemeral port. Your system chose it randomly for the client end of this specific SSH session. If you were to open another ssh localhost connection, it would use a different ephemeral port.
  5. To finish, close the session. Switch back to the terminal tab where you ran ssh localhost and type exit, then press Enter.

    exit
    

    This will terminate the connection. If you run netstat -antp | grep ESTABLISHED again in the other terminal, you will see that the localhost session has disappeared.

Summary

In this lab, you learned how to use the netstat command to analyze network activity on a Linux system. You began by using netstat -a to list all active and listening sockets, including TCP, UDP, and UNIX domain sockets. You then refined this output by applying flags such as -t, -u, -l, -n, and -p to specifically filter for listening TCP and UDP ports, display numeric addresses, and identify the process ID and name associated with each port.

Building on this, you practiced interpreting the command's output to map listening ports to their corresponding services. To observe a connection in action, you initiated a new network session by connecting to a website. This allowed you to identify a connection in the ESTABLISHED state and understand the role of ephemeral ports, which are temporary ports assigned to the client side of a network communication.