Example for netstat

Paolo Predonzani edited this page Dec 27, 2017 · 2 revisions

Just like the proof of the pudding is in the eating, the proof that the services that you want (and only those!) are running on your system is in netstat -plnt.

The output of this Linux command is something like the following:

$ sudo netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0    *               LISTEN      876/sshd        
tcp6       0      0 :::80                   :::*                    LISTEN      3076/apache2    
tcp6       0      0 :::22                   :::*                    LISTEN      876/sshd        
tcp6       0      0 :::443                  :::*                    LISTEN      3076/apache2    

From this we see that the open ports are 22 (ssh), 80 (http) and 443 (https). If these are fewer than you expected, some server is not running. If they are more, some application is running but shouldn't or is not on your security radar.

Running netstat manually is good, but setting up Tstconfig to test it automatically for you is even better.

Parsing netstat's output

The first two lines of netstat's output are just header text and can be skipped. The rest of the output is a table with a fixed-position format. There are 7 columns and, counting the characters, they start at positions 0, 6, 13, 20, 44, 68, and 80. The columns are:

  • the protocol (tcp/tcp6/udp)
  • the receive queue size
  • the send queue size
  • the local bind address
  • the remote address (not used for these ports)
  • the state (always LISTEN for these ports)
  • the PID and program name that opened the port

With this in mind, we can create a file called netstat.tstconfig with the following content:

# Test open ports via netstat
command sudo netstat -plnt
parse_mode fixed
positions 0 6 13 20 44 68 80
skip_header_lines 2

Testing open ports

Of all the available columns, we're interested in column 3 (local bind addess) and 6 (PID and program name). All other columns can be ignored.

columns 3 6

Of the two selected columns, the first can be used as a property key, the second as the property value. Let's check the ports we expect to be open:

assert_ends_with /sshd

property :::22
assert_ends_with /sshd

property :::80
assert_ends_with /apache2

property :::443
assert_ends_with /apache2

Notice that we've used assert_ends_with instead of assert_eq. In this way we can ignore the PID which is variable, and test the process name which is predictable.

Testing ports that should not be open

Knowing that certain ports are indeed open is not sufficient. We also want to know that other ports are not open by mistake or as a result of malicious activity.

One way of doing this is to check the number of open ports:

assert_eq 4

The four ports are clearly the ones we tested in the previous section, no more, no less.

A less drastic approach would be to test that certain specific ports do not appear in netstat's output. For example to test that a mail server is not running on the machine, we could check port 25:


property :::25 

Running the tests

Save netstat.tstconfig and run:

$ tstconfig netstat.tstconfig 
Tstconfig 0.2

Reading definition file: netstat.tstconfig
 Command: sudo netstat -plnt
 Value: 6
 Assertion: assert_eq 4

 Command: sudo netstat -plnt
 Value: 4435/master
 Assertion: assert_undefined

 Command: sudo netstat -plnt
 Property: :::25
 Value: 4435/master
 Assertion: assert_undefined

Assertions tested: 7
Assertions passed: 4
Assertions failed: 3
Errors: 0

The report shows that the tests failed because port 25 (associated to a mail server) was found to be open. To fix the problem, shut down the mail server, then re-run the tests.


Testing runtime statuses has advantages over testing static configuration files. You may set up all the required configuration files to start e.g. apache, but you cannot be 100% sure it's running unless you check port 80 with netstat.

Like netstat, there are many Linux commands (iptables --list for the firewall, free for memory usage, not to mention anything that can be read from the /proc virtual file system) that show the system's runtime status in the form of simple tables that can parsed and checked automatically.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.