Search code examples
awkgrepwatchnetstatuniq

Monitoring Server Connections - Netstat formatting issue


I have had a few issues with a server recently. So i just wanted to leave a window showing the unique and IP's of connected devices.

I have been using:

watch -n 5 "netstat -tn 2>/dev/null | grep :80 | awk '{print $5}' | sed 's/.*::ffff://' | sort | uniq -c | sort -nr"

This works okay, but i have a formatting issue i cannot resolve, It seems to be when local connections appear.

Example of the output (Screenshot) Aligment falls out Example of Netstat without pipe Results from NetStat The reason for the confusion, is i am using awk '{print $5}' to print the 5th column only

I am assuming its because i am trying to use watch with pips and something does not agree with the other.

Can anyone suggest a tweak to the one liner, Or can anyone advise of another tool to monitor the active connections to the server (Not interested in local connections)

Edited Here is what i am using now. I decided against Watch due to the number of formatting issues.

RED='\033[00;31m'
RESTORE='\033[0m'
YELLOW='\033[00;33m'
PURPLE='\033[00;35m'
LCYAN='\033[01;36m'
BLUE='\033[00;34m'
LIGHTGRAY='\033[00;37m'

while true
do
echo -e ${RED}"Connection Script"
echo -e ${YELLOW}"Current Active Connections to the Server Port 80"
  netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr
echo -e ${RESTORE}
echo -e ${PURPLE}"FTP Connections: 21"
  netstat -tn 2>/dev/null | awk '/:21 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr
echo -e ${RESTORE}
echo -e ${LCYAN}"SSH/'SFTP' Connections: 22"
  netstat -tn 2>/dev/null | awk '/:22 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr
echo -e ${RESTORE}
echo -e ${RED}"Yellowfin Connections: 8181"
  netstat -tn 2>/dev/null | awk '/:8181 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr
echo -e ${RESTORE}
MySQLCon=$(netstat -tn 2>/dev/null | awk '/:3306 /' | sort | uniq -c | sort -nr | wc -l)
echo -e ${RESTORE}
echo -e $LIGHTGRAY"MySQL Active Connections on port 3306 =" $MySQLCon
echo -e ${RESTORE}
  sleep 5
  clear
done

I appreciate the feedback provided here, Its been a interesting learning curve Example of the outputted script:

enter image description here

Part of image has been blacked out as the IP is special ;-)


Solution

  • There are a couple of things going into this "odd" output.

    Look at the command that watch claims it is running. Specifically look at the awk script. See that it is awk '{print }'?

    That's because you embedded the entire command in double quotes so the shell itself expands $5 as a positional parameter and it disappears before awk even runs and you end up printing out the entire line.

    Drop the sed from the pipeline and you'll see that every line is the full line in the output. (Alternatively drop the awk from the pipeline and you'll see that the output doesn't change at all.)

    The only reason some of the lines aren't full is because the sed is dropping everything before ::ffff: on lines that contain that. Which, you'll notice, none of the IPv4 lines at the end do (which is why they show up in full). So the fact that you get even close to the output you expect is because you were double covering the "only print the remote IP column" goal.

    This all is also why you get the status column in the output (despite not indicating that you want that in the first place).

    Escape \$ in the command to "fix" the pipeline.

    That said going for "not using grep and sed" try this:

    netstat -tn | awk '/:80 / {print $5}'
    

    and see how close to what you want that gets you.

    That will match :80 in the wrong column so if you want to limit that to Local Address column you can do that by using $4 ~ /:80$/ instead of just /:80 /.