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