Iptables: Difference between revisions

From Lolly's Wiki
Jump to navigationJump to search
Line 3: Line 3:
<SyntaxHighlight lang=bash>
<SyntaxHighlight lang=bash>
#!/bin/bash
#!/bin/bash
#
# Based on a script from here https://www.lupovis.io/implementing-a-dynamic-blocklist-with-iptables/
#
declare -A BLOCKLIST_URLS=(
declare -A BLOCKLIST_URLS=(
Emerging_Threats  https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt
Emerging_Threats  https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt

Revision as of 05:23, 8 May 2025

Block IPs dynamically from blocklists

I found a basic script [here] which I adapted to a set of lists and added logging.

#!/bin/bash
#
# Based on a script from here https://www.lupovis.io/implementing-a-dynamic-blocklist-with-iptables/
#

declare -A BLOCKLIST_URLS=(
Emerging_Threats   https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt
TOR_exit_nodes     https://opendbl.net/lists/tor-exit.list
Bruteforce_Blocker https://opendbl.net/lists/bruteforce.list
Blocklist_de       https://opendbl.net/lists/blocklistde-all.list
Dshield            https://opendbl.net/lists/dshield.list
SSL_Abuse_IP_list  https://opendbl.net/lists/sslblock.list
IPSum_Level_3      https://opendbl.net/lists/ipsum.list
)
IPTABLES="/sbin/iptables"
IPSET="/sbin/ipset"

LIST_DIR="/etc/iptables_blocklist/lists"
MAX_ELEMENTS=$[2**16]

[ ! -d ${LIST_DIR} ] && mkdir -p ${LIST_DIR}

case $1 in
stop)
	for BLOCKLIST in ${!BLOCKLIST_URLS[@]}
	do
	 PREVIOUS_BLOCKLIST="${LIST_DIR}/${BLOCKLIST}_previous.txt"
 	 LOG="DENY Dyn ${BLOCKLIST}"
	 ${IPTABLES} -D INPUT -m set --match-set ${BLOCKLIST} src -j DROP
	 ${IPTABLES} -D INPUT -m set --match-set ${BLOCKLIST} src -j LOG --log-prefix "${LOG} " --log-tcp-options --log-ip-options
	 ${IPSET} destroy ${BLOCKLIST} -exist
	 >${PREVIOUS_BLOCKLIST}
	done
	;;
restart)
	$0 stop
	$0 start
	;;
start|update|*)
	for BLOCKLIST in ${!BLOCKLIST_URLS[@]}
	do
	 PREVIOUS_BLOCKLIST="${LIST_DIR}/${BLOCKLIST}_previous.txt"
	 CURRENT_BLOCKLIST="${LIST_DIR}/${BLOCKLIST}_current.txt"
	 LOG="DENY Dyn ${BLOCKLIST}"
	 [ -f ${CURRENT_BLOCKLIST} ] || touch ${CURRENT_BLOCKLIST}
	 [ -f ${PREVIOUS_BLOCKLIST} ] || touch ${PREVIOUS_BLOCKLIST}
	 # Download the current blocklist
	 curl -s ${BLOCKLIST_URLS[${BLOCKLIST}]} -o ${CURRENT_BLOCKLIST}
	 # Create the ipset set if it does not exist
	 ${IPSET} create ${BLOCKLIST} hash:net maxelem ${MAX_ELEMENTS} timeout 0 -exist
	 # Add new IPs to the blocklist
	 comm -13 <(sort -u <(grep -Ev "(^#|^$)" ${PREVIOUS_BLOCKLIST})) <(sort -u <(grep -Ev "(^#|^$)" ${CURRENT_BLOCKLIST})) | while read -r IP
	 do
	   ${IPSET} add -exist ${BLOCKLIST} ${IP}
	 done
	 # Remove outdated IPs from the blocklist
	 comm -23 <(sort -u <(grep -Ev "(^#|^$)" ${PREVIOUS_BLOCKLIST})) <(sort -u <(grep -Ev "(^#|^$)" ${CURRENT_BLOCKLIST})) | while read -r IP
	 do
	   ${IPSET} del -exist ${BLOCKLIST} ${IP}
	 done
	 # Ensure the IPtables rule is in place
	 ${IPTABLES} -C INPUT -m set --match-set ${BLOCKLIST} src -j DROP 2>/dev/null || ${IPTABLES} -I INPUT -m set --match-set ${BLOCKLIST} src -j DROP
	 ${IPTABLES} -C INPUT -m set --match-set ${BLOCKLIST} src -j LOG --log-prefix "${LOG} " --log-tcp-options --log-ip-options 2>/dev/null || ${IPTABLES} -I INPUT -m set --match-set ${BLOCKLIST} src -j LOG --log-prefix "${LOG} " --log-tcp-options --log-ip-options
	 # Save the current blocklist as the previous one for the next run
	 cp ${CURRENT_BLOCKLIST} ${PREVIOUS_BLOCKLIST}
	done
	;;
esac

To find the blocked IPs of the last 24hours you can try:

# journalctl --full --dmesg --no-pager --grep "DENY Dyn \w+ " --since -24hours

or what is going on now:

# journalctl --full --dmesg --no-pager --follow --grep "DENY Dyn \w+ "