How to Filter and Monitor Outbound TCP Connections in Linux Using Netstat


8 views

When dealing with a potentially compromised Linux server, one of the first diagnostic steps is examining network connections. The standard netstat command shows all active connections, but we often need to focus specifically on outbound TCP connections when investigating malware or suspicious activity.

Here's the most effective way to list only outbound TCP connections:

netstat -tupan | grep -v "0.0.0.0:\|127.0.0.1:\|:::" | grep ESTABLISHED

This command breakdown:

  • -t shows TCP connections
  • -u shows UDP connections (we include it to be thorough)
  • -p shows the process ID/name
  • -a shows all connections
  • -n shows numerical addresses

For modern Linux systems, ss (socket statistics) is often preferred:

ss -tupn state established | grep -v "127.0.0.1\|::1"

In your case where HTTP requests are being made to multiple websites, you could further filter:

netstat -tupan | grep -E ":80\>|:443\>" | grep -v "0.0.0.0:\|127.0.0.1:\|:::"

While your UFW rule blocks outbound traffic, you might want to temporarily allow specific monitoring:

sudo ufw allow out proto tcp to any port 80,443 comment "Temporary monitoring"

For continuous monitoring, create a simple bash script:

#!/bin/bash
while true; do
    echo "===== $(date) ====="
    ss -tupn state established | grep -v "127.0.0.1\|::1"
    sleep 5
done

To identify the culprit process making these connections:

sudo lsof -iTCP -sTCP:established | grep -v "localhost\|127.0.0.1"

When dealing with a compromised Ubuntu server making unauthorized HTTP requests, the first step is proper connection monitoring. While ufw deny out blocks the traffic, we need visibility into the existing connections.

The most precise way to show only outbound TCP connections is:

netstat -tunp | grep -v "0.0.0.0:\|127.\|:::\|192.168.\|10.\|172.16." | grep ESTABLISHED

This command:

  • -t shows TCP connections only
  • -u would show UDP (removed in final command)
  • -n shows numerical addresses
  • -p shows process information
  • The grep filters remove local/LAN connections

For modern Linux systems, ss (socket statistics) is more efficient:

ss -tunp state established | grep -v "0.0.0.0:\|127.\|:::\|192.168.\|10.\|172.16."

Let's analyze sample output:

tcp        0      0 192.168.1.100:47932    52.85.247.14:443      ESTABLISHED 1234/python

This shows an outbound HTTPS connection from port 47932 to AWS (52.85.247.14) by a Python process.

Create a monitoring script (check_outbound.sh):

#!/bin/bash
while true; do
    TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
    CONNS=$(ss -tunp state established | grep -v "0.0.0.0:\|127.\|:::\|192.168.\|10.\|172.16." | wc -l)
    echo "[$TIMESTAMP] Outbound connections: $CONNS"
    if [ $CONNS -gt 10 ]; then
        echo "ALERT: High outbound connection count detected!" | mail -s "Security Alert" admin@example.com
    fi
    sleep 60
done
  • Combine with lsof -i to verify processes
  • Use kill -9 PID to terminate malicious processes
  • Consider installing fail2ban for automated blocking
  • Regularly audit with apt list --installed | grep -i suspicious