When trying to monitor incoming connections for potential DoS attacks using the command:
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
Many admins encounter formatting issues when attempting to refresh the output periodically using watch. The command's normally clean output showing connection counts per IP gets mangled.
The issue occurs because watch by default tries to maintain a consistent screen width and may reformat columns. Additionally, the header lines from netstat get included in each refresh cycle.
Option 1: Proper watch Implementation
watch -n 30 "netstat -ntu | awk 'NR>2{print \$5}' | cut -d: -f1 | sort | uniq -c | sort -n"
Key improvements:
- NR>2 skips the header lines
- Escaped $ in awk prevents shell interpretation
Option 2: Alternative Continuous Monitoring
For more robust monitoring:
while true; do
clear
netstat -ntu | awk 'NR>2{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
sleep 30
done
Option 3: Using ss Instead (Modern Alternative)
watch -n 30 "ss -ntu | awk 'NR>1{print \$6}' | cut -d: -f1 | sort | uniq -c | sort -n"
For production monitoring of DoS attacks:
#!/bin/bash
INTERVAL=30
THRESHOLD=50
while true; do
clear
date
echo "Monitoring connections (threshold: $THRESHOLD)"
echo "--------------------------------------------"
netstat -ntu | awk 'NR>2{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | \
awk -v limit=$THRESHOLD '$1 > limit {print $0}'
sleep $INTERVAL
done
Consider combining with:
- fail2ban for automatic blocking
- tcpdump for packet inspection
- ntop for traffic analysis
When trying to continuously monitor network connections using netstat with watch, many users encounter unexpected output formatting issues. The original command:
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
Produces clean output showing connection counts per IP address. However, when wrapped in watch:
watch -n 30 "netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n"
The output becomes mangled with additional headers and incorrect formatting.
The issue stems from how watch handles the command's output. Watch tries to preserve the terminal width and formatting, which interferes with our carefully constructed pipeline. The headers you're seeing are actually part of netstat's normal output that gets included in the count.
Option 1: Use watch with --precise flag
Try this more precise version that handles the output better:
watch -n 30 --precise "netstat -ntu | awk '/^tcp|^udp/{print \$5}' | cut -d: -f1 | sort | uniq -c | sort -n"
The key improvements:
- Added --precise for better timing accuracy
- Modified awk to filter only tcp/udp lines
- Escaped the $ in awk to prevent shell interpretation
Option 2: Alternative with ss command
For modern Linux systems, ss (socket statistics) is preferred over netstat:
watch -n 30 "ss -ntu | awk '{print \$6}' | cut -d: -f1 | sort | uniq -c | sort -n"
Option 3: Create a shell script
For more complex monitoring, create a dedicated script:
#!/bin/bash
while true; do
clear
date
echo "Active connections:"
netstat -ntu | awk '/^tcp|^udp/{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
sleep 30
done
For serious DoS monitoring, consider these enhanced approaches:
# Monitor only connections in SYN_RECV state (potential SYN flood)
watch -n 10 "netstat -nt | grep 'SYN_RECV' | awk '{print \$5}' | cut -d: -f1 | sort | uniq -c | sort -n"
# Track connection rate changes
watch -n 10 "netstat -ntu | awk '/^tcp|^udp/{print \$5}' | cut -d: -f1 | sort | uniq -c | sort -n | tee -a /var/log/connection_counts.log"
For automatic blocking of suspicious IPs, you could extend the script:
#!/bin/bash
THRESHOLD=50
while true; do
netstat -ntu | awk '/^tcp|^udp/{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n | \
while read count ip; do
if [ $count -gt $THRESHOLD ]; then
echo "$(date) Blocking $ip with $count connections" >> /var/log/dos_block.log
iptables -A INPUT -s $ip -j DROP
fi
done
sleep 30
done
Remember to adjust the THRESHOLD value according to your server's normal traffic patterns.