The iptables recent module is a powerful tool for tracking connection attempts from specific IP addresses. In your SSH brute force protection setup, you're using two key rules:
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
The first rule adds any new SSH connection attempt to the "SSH" tracking list, while the second rule blocks IPs that make more than 8 new connection attempts within 60 seconds.
To list currently tracked IP addresses (including blocked ones), examine the recent module's tracking file:
cat /proc/net/xt_recent/SSH
This will show all IP addresses currently being tracked by your SSH protection rules, including their timestamps. Blocked IPs will typically appear multiple times with recent timestamps.
For more detailed information, use these commands:
# View IPs that have triggered the block
sudo iptables -L INPUT -v -n | grep SSH
# Check the hit count for each IP
sudo iptables -L INPUT -v -n --line-numbers | grep recent
To manually remove an IP from the block list:
echo -1.2.3.4 > /proc/net/xt_recent/SSH
Replace 1.2.3.4 with the actual IP address you want to unblock.
For long-term tracking across reboots, consider these approaches:
# Save current blocked IPs to a file
cat /proc/net/xt_recent/SSH > ~/blocked_ips.txt
# Restore them after reboot
while read ip; do
iptables -A INPUT -s $ip -j DROP
done < ~/blocked_ips.txt
For better analysis, use this command to see blocked IPs sorted by frequency:
cat /proc/net/xt_recent/SSH | awk '{print $1}' | sort | uniq -c | sort -nr
This shows each blocked IP along with how many times it's been recorded in your tracking list.
When securing SSH servers, many administrators implement iptables rules to automatically block IPs attempting excessive connections. The standard approach uses two key rules:
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
To view currently blocked addresses, inspect the recent module's tracking list:
sudo cat /proc/net/xt_recent/SSH
Sample output shows source IPs and timestamps:
src=192.168.1.100 ttl: 64 last_seen: 4294977026 oldest_pkt: 1 4294977026
src=203.0.113.42 ttl: 128 last_seen: 4294977120 oldest_pkt: 1 4294977120
For systems using newer iptables versions, check the counters:
sudo iptables -L INPUT -v -n --line-numbers | grep SSH
To see which IPs triggered the DROP rule:
sudo iptables -Z && sleep 60 && sudo iptables -L INPUT -v -n
Create a monitoring script that logs blocked attempts:
#!/bin/bash
LOG_FILE="/var/log/iptables_ssh_blocks.log"
echo "Blocked IPs at $(date)" >> $LOG_FILE
cat /proc/net/xt_recent/SSH | awk '{print $1}' | cut -d= -f2 >> $LOG_FILE
To automatically add persistent blocks:
BLOCKED_IPS=$(cat /proc/net/xt_recent/SSH | awk -F= '{print $2}' | awk '{print $1}')
for ip in $BLOCKED_IPS; do
iptables -A INPUT -s $ip -j DROP
echo "$ip" >> /etc/iptables/permanent_blocks.conf
done
Combine with logging tools for analysis:
sudo grep "DROP.*SSH" /var/log/kern.log | awk '{print $10}' | sort | uniq -c | sort -nr