Initial Commit
This commit is contained in:
parent
77ad808cb3
commit
915a67fce7
234
IPtables Blacklist/blocklists.sh
Normal file
234
IPtables Blacklist/blocklists.sh
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
#### System Variables ####
|
||||||
|
IPSET_PREFIX="bl" # Prefix for ipset names
|
||||||
|
IPSET_TYPE="hash:net" # Type of created ipsets
|
||||||
|
IPV4=1 # Enable IPv4 by default
|
||||||
|
IPV6=1 # Enable IPv6 by default
|
||||||
|
QUIET=0 # Default quiet mode setting
|
||||||
|
VERBOSE=0 # Default verbosity level
|
||||||
|
declare -A BLOCKLISTS # Array for blocklists to use. Populated by CLI args,
|
||||||
|
IPV4_REGEX="(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/[1-3]?[0-9])?" # Regex for a valid IPv4 address with optional subnet part
|
||||||
|
IPV6_REGEX="(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(/[1-6]?[0-9])?" # Regef for a valid IPv6 address with optional subnet part
|
||||||
|
|
||||||
|
if [ ! "$(command -v ipset)" ]; then
|
||||||
|
apt -y install ipset
|
||||||
|
else
|
||||||
|
IPSET_BIN=$(command -v ipset)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "/var/lib/ipset" ]; then
|
||||||
|
mkdir -p /var/lib/ipset
|
||||||
|
else
|
||||||
|
IPSET_DIR="/var/lib/ipset" # Folder to write ipset save files to
|
||||||
|
fi
|
||||||
|
|
||||||
|
##
|
||||||
|
# Prints the help/usage message
|
||||||
|
##
|
||||||
|
function print_usage() {
|
||||||
|
{
|
||||||
|
cat << EOF
|
||||||
|
Usage: $0 [-h]
|
||||||
|
Blocking lists of IPs from public blocklists / blacklists (e.g. blocklist.de, spamhaus.org)
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-l : Blocklist to use. Can be specified multiple times.
|
||||||
|
Format: "\$name \$url" (space-separated). See examples below.
|
||||||
|
-4 : Run in IPv4 only mode. Ignore IPv6 addresses.
|
||||||
|
-6 : Run in IPv6 only mode. Ignore IPv4 addresses.
|
||||||
|
-q : Quiet mode. Outputs are suppressed if flag is present.
|
||||||
|
-v : Verbose mode. Prints additional information during execution.
|
||||||
|
-h : Print this help message.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
$0 -l "spamhaus https://www.spamhaus.org/drop/drop.txt"
|
||||||
|
$0 -l "blocklist https://lists.blocklist.de/lists/all.txt" -l "spamhaus https://www.spamhaus.org/drop/drop.txt"
|
||||||
|
$0 -l "spamhaus https://www.spamhaus.org/drop/drop.txt" -l "spamhaus6 https://www.spamhaus.org/drop/dropv6.txt"
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Writes argument $1 to stdout if $QUIET is not set
|
||||||
|
function log() {
|
||||||
|
{
|
||||||
|
if [[ $QUIET -eq 0 ]]; then
|
||||||
|
echo "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Writes argument $1 to stdout if $VERBOSE is set and $QUIET is not set
|
||||||
|
function log_verbose() {
|
||||||
|
{
|
||||||
|
if [[ $VERBOSE -eq 1 ]]; then
|
||||||
|
if [[ $QUIET -eq 0 ]]; then
|
||||||
|
echo "$1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Writes argument $1 to stderr. Ignores $QUIET.
|
||||||
|
function log_error() {
|
||||||
|
{
|
||||||
|
>&2 echo "[ERROR]: $1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Validates the BLOCKLISTS array. Exits upon error.
|
||||||
|
function validate_blocklists() {
|
||||||
|
{
|
||||||
|
if [ ${#BLOCKLISTS[@]} -eq 0 ]; then
|
||||||
|
log_error "No blocklists given. Exiting..."
|
||||||
|
print_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for list in "${BLOCKLISTS[@]}"
|
||||||
|
do
|
||||||
|
list_name=$(echo "$list" | cut -d ' ' -f 1)
|
||||||
|
list_url=$(echo "$list" | cut -d ' ' -f 2)
|
||||||
|
|
||||||
|
if [ -z "$list_name" ]; then
|
||||||
|
log_error "Invalid name for list: $list"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$list_url" ]; then
|
||||||
|
log_error "Invalid url for list: $list"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_verbose "Found valid blocklist: name=${list_name}, url=${list_url}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Updates an ipset based on a list of IP addresses
|
||||||
|
function update_ipset() {
|
||||||
|
{
|
||||||
|
# Setup local vars
|
||||||
|
setname=$1 # $1 Name of the ipset to update
|
||||||
|
ipfile=$2 # $2 File containing all IP addresses to store in ipset
|
||||||
|
family=$3 # $3 Procotol family (e.g. inet OR inet6)
|
||||||
|
|
||||||
|
# Create temporary ipset to build and ensure existence of live ipset
|
||||||
|
livelist="$setname-$family"
|
||||||
|
templist="$setname-$family-T"
|
||||||
|
|
||||||
|
$IPSET_BIN create -q "$livelist" "$IPSET_TYPE" family "$family"
|
||||||
|
$IPSET_BIN create -q "$templist" "$IPSET_TYPE" family "$family"
|
||||||
|
log_verbose "Prepared ipset lists: livelist='$livelist', templist='$templist'"
|
||||||
|
|
||||||
|
while read -r ip; do
|
||||||
|
if $IPSET_BIN add "$templist" "$ip"; then
|
||||||
|
log_verbose "Added '$ip' to '$templist'"
|
||||||
|
else
|
||||||
|
log "Failed to add '$ip' to '$templist'"
|
||||||
|
fi
|
||||||
|
done < "$ipfile"
|
||||||
|
|
||||||
|
$IPSET_BIN swap "$templist" "$livelist"
|
||||||
|
log_verbose "Swapped ipset: $livelist"
|
||||||
|
|
||||||
|
$IPSET_BIN destroy "$templist"
|
||||||
|
log_verbose "Destroyed ipset: $templist"
|
||||||
|
|
||||||
|
# Write ipset savefile
|
||||||
|
$IPSET_BIN save "$livelist" > "$IPSET_DIR/$livelist.save"
|
||||||
|
log_verbose "Wrote savefile for '$livelist' to: $IPSET_DIR/$livelist.save"
|
||||||
|
log "Added $(wc -l < "$ipfile") to ipset '$livelist'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Updates the given blocklist from an URL
|
||||||
|
function update_blocklist() {
|
||||||
|
{
|
||||||
|
# Download blocklist
|
||||||
|
log "Updating blacklist '$1' ..." # $1 Name of the blocklist
|
||||||
|
log_verbose "Downloading blocklist '$1' from: $2 ..." # $2 URL of the blocklist
|
||||||
|
tempfile=$(mktemp "/tmp/blocklist.$1.XXXXXXXX")
|
||||||
|
wget -q -O "$tempfile" "$2"
|
||||||
|
|
||||||
|
# Check downloaded list
|
||||||
|
linecount=$(wc -l < "$tempfile")
|
||||||
|
if [ "$linecount" -lt 10 ]; then
|
||||||
|
log_error "Blacklist '$1' containes only $linecount lines. This seems to short. Exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract ips from raw list data
|
||||||
|
if [[ $IPV4 -eq 1 ]]; then
|
||||||
|
grep -v '^[#;]' "$tempfile" | grep -E -o "$IPV4_REGEX" | cut -d ' ' -f 1 > "$tempfile.filtered"
|
||||||
|
numips=$(wc -l < "$tempfile.filtered")
|
||||||
|
log_verbose "Got $numips IPv4 entries from blocklist '$1'"
|
||||||
|
|
||||||
|
if [[ $numips -gt 0 ]]; then
|
||||||
|
update_ipset "${IPSET_PREFIX}-$1" "$tempfile.filtered" "inet"
|
||||||
|
else
|
||||||
|
log_verbose "No IPv4 addresses found in blocklist '$1'. Skipping"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $IPV6 -eq 1 ]]; then
|
||||||
|
grep -v '^[#;]' "$tempfile" | grep -E -o "$IPV6_REGEX" | cut -d ' ' -f 1 > "$tempfile.filtered6"
|
||||||
|
numips=$(wc -l < "$tempfile.filtered6")
|
||||||
|
log_verbose "Got $numips IPv6 entries from blocklist '$1'"
|
||||||
|
|
||||||
|
if [[ $numips -gt 0 ]]; then
|
||||||
|
update_ipset "${IPSET_PREFIX}-$1" "$tempfile.filtered6" "inet6"
|
||||||
|
else
|
||||||
|
log_verbose "No IPv6 addresses found in blocklist '$1'. Skipping"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
rm "$tempfile"*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Main loop
|
||||||
|
function main() {
|
||||||
|
{
|
||||||
|
# Check arguments
|
||||||
|
validate_blocklists
|
||||||
|
|
||||||
|
# Update blocklists
|
||||||
|
for list in "${BLOCKLISTS[@]}"; do
|
||||||
|
list_name=$(echo "$list" | cut -d ' ' -f 1)
|
||||||
|
list_url=$(echo "$list" | cut -d ' ' -f 2)
|
||||||
|
update_blocklist "$list_name" "$list_url"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while getopts ":hqv46l:" opt
|
||||||
|
do
|
||||||
|
case ${opt} in
|
||||||
|
l) BLOCKLISTS[${#BLOCKLISTS[@]}]=${OPTARG}
|
||||||
|
;;
|
||||||
|
4) IPV4=1
|
||||||
|
IPV6=0
|
||||||
|
log "Using IPv4 only mode. Skipping IPv6 addresses."
|
||||||
|
;;
|
||||||
|
6) IPV4=0
|
||||||
|
IPV6=1
|
||||||
|
log "Using IPv6 only mode. Skipping IPv4 addresses."
|
||||||
|
;;
|
||||||
|
q) QUIET=1
|
||||||
|
;;
|
||||||
|
v) VERBOSE=1
|
||||||
|
;;
|
||||||
|
h) print_usage; exit
|
||||||
|
;;
|
||||||
|
:) print_usage; exit
|
||||||
|
;;
|
||||||
|
\?) print_usage; exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
#### Main function call
|
||||||
|
main
|
||||||
332
IPtables Blacklist/ipset_blocklist.sh
Normal file
332
IPtables Blacklist/ipset_blocklist.sh
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Where we keep all the blacklists.
|
||||||
|
iproute=$(ip route get 8.8.8.8 | awk -- '{print $5}')
|
||||||
|
BL_DIR="/var/lib/ipset"
|
||||||
|
|
||||||
|
if [ ! -d $BL_DIR ]; then
|
||||||
|
mkdir -p $BL_DIR
|
||||||
|
else
|
||||||
|
echo "Unable to create $BL_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! "$(command -v ipset)" ]; then
|
||||||
|
dnf install ipset
|
||||||
|
else
|
||||||
|
echo 'Unable find or install ipset'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Some hosting services such as RamNode will ban you for using > 90% of the cpu!!!
|
||||||
|
# So we recommend installing cpulimit and limiting to 20% of cpu usage when
|
||||||
|
# calling this script.
|
||||||
|
#
|
||||||
|
## cpulimit -z -l 20 /usr/local/bin/blacklists.sh
|
||||||
|
# cpulimit dosn't like scripts writing to stdout/stderr so them redirect to
|
||||||
|
# an output file.
|
||||||
|
#
|
||||||
|
|
||||||
|
exec >$BL_DIR/blocklists.out 2>&1
|
||||||
|
|
||||||
|
SCRIPT_NAME=$0
|
||||||
|
HOST_NAME=$(uname -n)
|
||||||
|
|
||||||
|
# default syslog messages priority and tag.
|
||||||
|
LOG_PRI="local0.notice"
|
||||||
|
LOG_TAG="[$SCRIPT_NAME]"
|
||||||
|
|
||||||
|
# Set to empty string if you don't want error emails. Otherwise, set to an admin email.
|
||||||
|
MAIL_ADMIN="root"
|
||||||
|
|
||||||
|
# Logging is enabled for the following ports this is so we can do later audit checks
|
||||||
|
# in case we are droping legitimate traffic.
|
||||||
|
TCP_PORTS="53,80,443"
|
||||||
|
UDP_PORTS="53"
|
||||||
|
|
||||||
|
# If PSAD is installed then block Danger Level = $DL and above attackers
|
||||||
|
# each time the blacklists are reloaded.
|
||||||
|
DL=3
|
||||||
|
|
||||||
|
# Retrieve new blacklists only when they are older then BL_AGE
|
||||||
|
BL_AGE="23 hours ago"
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# logmessage <msg_text>
|
||||||
|
logmessage() {
|
||||||
|
{
|
||||||
|
MSG="$1"
|
||||||
|
logger -s -p $LOG_PRI -t "$LOG_TAG" "$MSG"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# <ips> goodinbadnets
|
||||||
|
# - returns whitelist <ips> that that are in blacklists.
|
||||||
|
goodinbadnets() {
|
||||||
|
{
|
||||||
|
myips=""
|
||||||
|
for good in $(ipset list good_ips | grep -E "^[1-9]");
|
||||||
|
do
|
||||||
|
myip=$(ipset test bad_nets_n "$good" 2>&1 | grep "is in" | awk '{print $1}')
|
||||||
|
if [ -n "$myip" ]; then
|
||||||
|
myips="$myips $myip"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "$myips"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# blacklistit <ip/cdr> <listname>
|
||||||
|
# - blacklists the given <ip/cdr> to bad_nets_n or gad_ips_n
|
||||||
|
# - also checks if the <ip/cdr> blacklists one of your whitelisted ips, and
|
||||||
|
# if so it will remove it from the blacklist and warn you.
|
||||||
|
blacklistit() {
|
||||||
|
{
|
||||||
|
IP=$1
|
||||||
|
LISTNAME=$2
|
||||||
|
if echo "$IP" | grep -E -q "\/[0-9]+"; then
|
||||||
|
ipset add bad_nets_n "$IP" -exist
|
||||||
|
badip=$(goodinbadnets)
|
||||||
|
if [ -n "$badip" ]; then
|
||||||
|
error_msg="ERROR Your whitelist IP $badip has been blacklisted in $LISTNAME"
|
||||||
|
logmessage "$error_msg"
|
||||||
|
ERROR_MSGS="$ERROR_MSGS\n$error_msg"
|
||||||
|
ipset del bad_nets_n "$IP"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if ipset test good_ips "$IP" 2>/dev/null; then
|
||||||
|
error_msg="ERROR Your whitelist IP $IP has been blacklisted in $LISTNAME"
|
||||||
|
logmessage "$error_msg"
|
||||||
|
ERROR_MSGS="$ERROR_MSGS\n$error_msg"
|
||||||
|
else
|
||||||
|
ipset add bad_ips_n "$IP" -exist
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# loadblacklist <name> <url>
|
||||||
|
# - loads standard form blacklist from <url> website, labels cache files with <name>
|
||||||
|
loadblacklist() {
|
||||||
|
{
|
||||||
|
BL_NAME=$1
|
||||||
|
BL_URL=$2
|
||||||
|
|
||||||
|
BL_FILE="$BL_DIR/$BL_NAME.txt"
|
||||||
|
if [ ! -f "$BL_FILE" ] || [ "$(date +%s -r "$BL_FILE")" -lt "$(date +%s --date="$BL_AGE")" ]; then
|
||||||
|
echo "-- getting fresh $BL_NAME from $BL_URL"
|
||||||
|
wget -q -t 2 --output-document="$BL_FILE" "$BL_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$BL_FILE" ]; then
|
||||||
|
echo "-- loading $BL_NAME from $BL_FILE"
|
||||||
|
|
||||||
|
# strip comments - mac address and ipv6 not supported yet so strip :
|
||||||
|
awk '{print $1}' "$BL_FILE" | cut -d\; -f1 | cut -d\, -f1 | grep -Ev "^#|^ *$|:" | sed -e "s/[^0-9\.\/]//g" | grep -E "^[0-9]" >"${BL_FILE}".filtered
|
||||||
|
echo "-- loading $BL_NAME - $(wc -l "${BL_FILE}".filtered) entries"
|
||||||
|
|
||||||
|
filter=$(cat "${BL_FILE}".filtered)
|
||||||
|
for ip in $filter;
|
||||||
|
do
|
||||||
|
blacklistit "$ip" "$BL_NAME"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# MAIN
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# concatenated list of all error message
|
||||||
|
ERROR_MSGS=""
|
||||||
|
|
||||||
|
if ! which ipset >/dev/null 2>&1; then
|
||||||
|
echo "ERROR: You must install 'ipset'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
logmessage "mylinux.work blocklist script started"
|
||||||
|
|
||||||
|
# Create temporary swap ipsets
|
||||||
|
ipset create bad_ips_n hash:ip hashsize 4096 maxelem 262144 2>/dev/null
|
||||||
|
ipset flush bad_ips_n
|
||||||
|
|
||||||
|
ipset create bad_nets_n hash:net hashsize 4096 maxelem 262144 2>/dev/null
|
||||||
|
ipset flush bad_nets_n
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup the active ipsets if they don't yet exist.
|
||||||
|
# Load them from last save sets to speed up load times in cases of reboot
|
||||||
|
# and ensure protection faster.
|
||||||
|
#
|
||||||
|
if ! ipset list bad_ips >/dev/null 2>&1; then
|
||||||
|
echo "-- creating bad_ips ipset as does not exist."
|
||||||
|
ipset create bad_ips hash:ip hashsize 4096 maxelem 262144
|
||||||
|
if [ -f "$BL_DIR/bad_ips.sav" ]; then
|
||||||
|
echo "-- importing from save file $BL_DIR/bad_ips.sav"
|
||||||
|
grep -v "create" $BL_DIR/bad_ips.sav | ipset restore
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ipset list bad_nets >/dev/null 2>&1; then
|
||||||
|
echo "-- creating bad_nets ipset as does not exist."
|
||||||
|
ipset create bad_nets hash:net hashsize 4096 maxelem 262144
|
||||||
|
if [ -f "$BL_DIR/bad_nets.sav" ]; then
|
||||||
|
echo "-- importing from save file $BL_DIR/bad_nets.sav"
|
||||||
|
grep -v "create" $BL_DIR/bad_nets.sav | ipset restore
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup our firewall ip chains
|
||||||
|
#
|
||||||
|
if ! iptables -L ftmon-blacklists -n >/dev/null 2>&1; then
|
||||||
|
|
||||||
|
echo "-- creating iptables rules for first time"
|
||||||
|
iptables -N ftmon-blacklists
|
||||||
|
|
||||||
|
iptables -I INPUT \
|
||||||
|
-m set --match-set bad_ips src -j ftmon-blacklists
|
||||||
|
|
||||||
|
# insert the smaller set first.
|
||||||
|
iptables -I INPUT \
|
||||||
|
-m set --match-set bad_nets src -j ftmon-blacklists
|
||||||
|
|
||||||
|
# keep a record of our business traffic ports.
|
||||||
|
# so we can check if we blocked legitimate traffic if need be.
|
||||||
|
# DNS and http/https are most typical legit ports
|
||||||
|
iptables -A blocklists -i "$iproute" -p tcp -m multiport --dports $TCP_PORTS -m limit --limit 5/min -j LOG --log-prefix "[BL DROP] "
|
||||||
|
iptables -A blocklists -i "$iproute" -p udp -m multiport --dport $UDP_PORTS -m limit --limit 5/min -j LOG --log-prefix "[BL DROP] "
|
||||||
|
iptables -A blocklists -i "$iproute" -m state --state NEW -p tcp -m multiport --dports $TCP_PORTS -j REJECT
|
||||||
|
iptables -A blocklists -i "$iproute" -m state --state NEW -p udp -m multiport --dports $UDP_PORTS -j REJECT
|
||||||
|
iptables -A blocklists -i "$iproute" -m state --state NEW -j DROP
|
||||||
|
fi
|
||||||
|
|
||||||
|
# List of ips to whitelist
|
||||||
|
if ! ipset list good_ips >/dev/null 2>&1; then
|
||||||
|
ipset create good_ips hash:ip
|
||||||
|
fi
|
||||||
|
|
||||||
|
# load fresh white list each time as the list should be small.
|
||||||
|
ipset flush good_ips
|
||||||
|
|
||||||
|
# load your good ip's
|
||||||
|
WL_CUSTOM="$BL_DIR/whitelist.txt"
|
||||||
|
count=0
|
||||||
|
count1=$(grep -Ev "^#|^ *$" $WL_CUSTOM | sed -e "s/#.*$//" -e "s/[^.0-9\/]//g")
|
||||||
|
if [ -f "$WL_CUSTOM" ]; then
|
||||||
|
for ip in $count1; do
|
||||||
|
ipset add good_ips "$ip" -exist
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
echo "-- loaded $count entries from $WL_CUSTOM"
|
||||||
|
|
||||||
|
# load your personal custom blacklists.
|
||||||
|
BL_CUSTOM="$BL_DIR/blacklist.txt"
|
||||||
|
count=0
|
||||||
|
count2=$(grep -Ev "^#|^ *$" $BL_CUSTOM | sed -e "s/#.*$//" -e "s/[^.0-9\/]//g")
|
||||||
|
if [ -f "$BL_CUSTOM" ]; then
|
||||||
|
for ip in $count2; do
|
||||||
|
blacklistit "$ip" "$BLACKLIST"
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
echo "-- loaded $(ipset list bad_ips_n | grep -Ec "^[1-9]") entries from blacklist "
|
||||||
|
echo "-- loaded $count entries from $BL_CUSTOM"
|
||||||
|
|
||||||
|
# If PSAD is installed then use some of it's good detection work
|
||||||
|
# to stop attackers.
|
||||||
|
count=0
|
||||||
|
count3=$(awk '{print $2, $1}' /var/log/psad/top_attackers | grep "^[$DL-]" | awk '{print $2}')
|
||||||
|
if [ -f "/var/log/psad/top_attackers" ]; then
|
||||||
|
for ip in $count3; do
|
||||||
|
blacklistit "$ip" "$BLACKLIST"
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
echo "-- loaded $count entries from /var/log/psad/top_attackers "
|
||||||
|
|
||||||
|
#
|
||||||
|
# Load Standard format blacklists
|
||||||
|
# Some of them are over zealous, you may want to comment out.
|
||||||
|
#
|
||||||
|
# loadblacklist "bl-autoshun-inet" "http://www.autoshun.org/files/shunlist.csv"
|
||||||
|
loadblacklist "bl-bdsatib-inet" "https://www.binarydefense.com/banlist.txt"
|
||||||
|
loadblacklist "bl-bfblocker-inet" "http://danger.rulez.sk/projects/bruteforceblocker/blist.php"
|
||||||
|
loadblacklist "bl-cinsarmy-inet" "http://cinsscore.com/list/ci-badguys.txt"
|
||||||
|
loadblacklist "bl-drop-inet" "https://www.spamhaus.org/drop/drop.txt"
|
||||||
|
# loadblacklist "bl-dropv6-inet6" "https://www.spamhaus.org/drop/dropv6.txt"
|
||||||
|
# loadblacklist "bl-dshield-inet" "https://iplists.firehol.org/files/dshield.netset"
|
||||||
|
# loadblacklist "bl-dshield-top10-inet" "http://feeds.dshield.org/top10-2.txt"
|
||||||
|
# loadblacklist "bl-edrop-inet" "https://www.spamhaus.org/drop/edrop.txt"
|
||||||
|
# loadblacklist "bl-f2ball-inet" "http://lists.blocklist.de/lists/all.txt"
|
||||||
|
loadblacklist "bl-firehol-inet" "https://iplists.firehol.org/files/firehol_level1.netset"
|
||||||
|
# loadblacklist "bl-greensnow-inet" "https://blocklist.greensnow.co/greensnow.txt"
|
||||||
|
# loadblacklist "bl-infiltrated-inet" "http://www.infiltrated.net/blacklisted"
|
||||||
|
# loadblacklist "bl-ipsec-inet" "http://doc.emergingthreats.net/pub/Main/RussianBusinessNetwork/RussianBusinessNetworkIPs.txt"
|
||||||
|
loadblacklist "bl-ipsum-inet" "https://raw.githubusercontent.com/stamparm/ipsum/master/levels/2.txt"
|
||||||
|
# loadblacklist "bl-maxmind-inet" "https://www.maxmind.com/en/anonymous_proxies"
|
||||||
|
# loadblacklist "bl-openbl-inet" "http://www.openbl.org/lists/base.txt"
|
||||||
|
# loadblacklist "bl-torexitnodes-inet" "https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.1.1.1"
|
||||||
|
# loadblacklist "bl-shlasso-inet" "http://www.spamhaus.org/drop/drop.lasso"
|
||||||
|
|
||||||
|
#
|
||||||
|
# bot nets
|
||||||
|
#
|
||||||
|
# https://palevotracker.abuse.ch/blocklists.php
|
||||||
|
# loadblacklist "bl-palevo-inet" "https://palevotracker.abuse.ch/blocklists.php?download=ipblocklist"
|
||||||
|
# https://spyeyetracker.abuse.ch/blocklist.php
|
||||||
|
# loadblacklist "bl-spyeye-inet" "https://spyeyetracker.abuse.ch/blocklist.php?download=ipblocklist"
|
||||||
|
# https://zeustracker.abuse.ch/blocklist.php
|
||||||
|
# loadblacklist "bl-zeus-inet" "https://zeustracker.abuse.ch/blocklist.php?download=badips"
|
||||||
|
|
||||||
|
#
|
||||||
|
# special cases, custom formats blacklists
|
||||||
|
#
|
||||||
|
|
||||||
|
# Obtain List of badguys from dshield.org
|
||||||
|
# https://isc.sans.edu/feeds_doc.html
|
||||||
|
BL_NAME="bl-dshield-top10-inet"
|
||||||
|
BL_URL="http://feeds.dshield.org/top10-2.txt"
|
||||||
|
|
||||||
|
BL_FILE="$BL_DIR/$BL_NAME.txt"
|
||||||
|
if [ ! -f "$BL_FILE" ] || [ "$(date +%s -r "$BL_FILE")" -lt "$(date +%s --date="$BL_AGE")" ]; then
|
||||||
|
echo "-- getting fresh $BL_NAME from $BL_URL"
|
||||||
|
wget -q -t 2 --output-document=$BL_FILE $BL_URL
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$BL_FILE" ]; then
|
||||||
|
echo "-- loading $BL_NAME from $BL_FILE"
|
||||||
|
load=$(grep -E "^[1-9]" $BL_FILE | cut -f1)
|
||||||
|
for ip in $load; do
|
||||||
|
blacklistit "$ip" $BL_NAME
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# swap in the new sets.
|
||||||
|
ipset swap bad_ips_n bad_ips
|
||||||
|
ipset swap bad_nets_n bad_nets
|
||||||
|
|
||||||
|
# show before and after counts.
|
||||||
|
complete_msg="bad_ips: current=$(ipset --list bad_ips_n | grep -Ec '^[1-9]') \
|
||||||
|
previous=$(ipset --list bad_ips | grep -Ec '^[1-9]') \
|
||||||
|
bad_nets: previous=$(ipset --list bad_nets | grep -Ec '^[1-9]') \
|
||||||
|
current=$(ipset --list bad_nets_n | grep -Ec '^[1-9]')"
|
||||||
|
|
||||||
|
logmessage "$complete_msg"
|
||||||
|
|
||||||
|
# only send email if problems.
|
||||||
|
if [ -n "$MAIL_ADMIN" ] && [ -n "$ERROR_MSGS" ]; then
|
||||||
|
echo -e "${complete_msg}\n${ERROR_MSGS}" | mail -s "$LOG_TAG $HOST_NAME" $MAIL_ADMIN
|
||||||
|
fi
|
||||||
|
|
||||||
|
# save memory space by destroying the temporary swap ipset
|
||||||
|
ipset destroy bad_ips_n
|
||||||
|
ipset destroy bad_nets_n
|
||||||
|
|
||||||
|
# save our ipsets for quick import on reboot.
|
||||||
|
ipset save bad_ips >$BL_DIR/bad_ips.sav
|
||||||
|
ipset save bad_nets >$BL_DIR/bad_nets.sav
|
||||||
|
|
||||||
|
logmessage "mylinux.work blocklist script completed"
|
||||||
182
IPtables Blacklist/iptables_blacklist.sh
Normal file
182
IPtables Blacklist/iptables_blacklist.sh
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# IP blacklisting script for Linux servers
|
||||||
|
|
||||||
|
# iptables logging limit
|
||||||
|
LIMIT="10/minute"
|
||||||
|
|
||||||
|
# try to load config file
|
||||||
|
# it should contain one blacklist URL per line
|
||||||
|
|
||||||
|
config_file="/etc/ip-blacklist.conf"
|
||||||
|
if [ -f "${config_file}" ]; then
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source ${config_file}
|
||||||
|
else
|
||||||
|
# if no config file is available, load default set of blacklists
|
||||||
|
# URLs for further blocklists are appended using the classical
|
||||||
|
# shell syntax: "$URLS new_url"
|
||||||
|
|
||||||
|
# Emerging Threats lists offensive IPs such as botnet command servers
|
||||||
|
URLS="https://danger.rulez.sk/projects/bruteforceblocker/blist.php"
|
||||||
|
|
||||||
|
# Blocklist.de collects reports from fail2ban probes, listing password brute-forces, scanners and other offenders
|
||||||
|
URLS="$URLS https://cinsscore.com/list/ci-badguys.txt"
|
||||||
|
|
||||||
|
# badips.com, from score 2 up
|
||||||
|
URLS="$URLS https://www.spamhaus.org/drop/drop.txt"
|
||||||
|
|
||||||
|
URLS="$URLS https://iplists.firehol.org/files/firehol_level1.netset"
|
||||||
|
|
||||||
|
URLS="$URLS https://raw.githubusercontent.com/stamparm/ipsum/master/levels/2.txt"
|
||||||
|
|
||||||
|
|
||||||
|
# iblocklist.com is also supported
|
||||||
|
# URLS="$URLS http://list.iblocklist.com/?list=srzondksmjuwsvmgdbhi&fileformat=p2p&archiveformat=gz&username=USERNAMEx$&pin=PIN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
link_set() {
|
||||||
|
if [ "$3" = "log" ]; then
|
||||||
|
iptables -A "$1" -m set --match-set "$2" src,dst -m limit --limit "$LIMIT" -j LOG --log-prefix "BLOCK $2 "
|
||||||
|
fi
|
||||||
|
iptables -A "$1" -m set --match-set "$2" src -j DROP
|
||||||
|
iptables -A "$1" -m set --match-set "$2" dst -j DROP
|
||||||
|
}
|
||||||
|
|
||||||
|
# This is how it will look like on the server
|
||||||
|
|
||||||
|
# Chain blocklists (2 references)
|
||||||
|
# pkts bytes target prot opt in out source destination
|
||||||
|
# 0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 match-set manual-blacklist src,dst limit: avg 10/min burst 5 LOG flags 0 level 4 prefix "BLOCK manual-blacklist "
|
||||||
|
# 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set manual-blacklist src,dst
|
||||||
|
# 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set rules.emergingthreats src
|
||||||
|
# 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set rules.emergingthreats dst
|
||||||
|
# 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set www.blocklist.de src
|
||||||
|
# 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set www.blocklist.de dst
|
||||||
|
# 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set www.badips.com src
|
||||||
|
# 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set www.badips.com dst
|
||||||
|
blocklist_chain_name=blocklists
|
||||||
|
|
||||||
|
# check for dependencies - ipset and curl
|
||||||
|
if [ -z "$(which ipset 2>/dev/null)" ]; then
|
||||||
|
echo "Cannot find ipset"
|
||||||
|
echo "Run \"apt-get install ipset\" (Debian/Ubuntu) or \"yum install ipset\" (RedHat/CentOS/Fedora) or \"opkg install ipset\" (OpenWRT/LEDE)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$(which curl 2>/dev/null)" ]; then
|
||||||
|
echo "Cannot find curl"
|
||||||
|
echo "Run \"apt-get install curl\" (Debian/Ubuntu) or \"yum install curl\" (RedHat/CentOS/Fedora) or \"opkg install curl\" (OpenWRT/LEDE)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if we are on OpenWRT
|
||||||
|
if [ "$(which uci 2>/dev/null)" ]; then
|
||||||
|
# we're on OpenWRT
|
||||||
|
wan_iface=pppoe-wan
|
||||||
|
IN_OPT="-i $wan_iface"
|
||||||
|
INPUT=input_rule
|
||||||
|
FORWARD=forwarding_rule
|
||||||
|
COMPRESS_OPT=""
|
||||||
|
else
|
||||||
|
COMPRESS_OPT="--compressed"
|
||||||
|
INPUT=INPUT
|
||||||
|
FORWARD=FORWARD
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create main blocklists chain
|
||||||
|
if ! iptables -nL | grep -q "Chain ${blocklist_chain_name}"; then
|
||||||
|
iptables -N ${blocklist_chain_name}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# inject references to blocklist in the beginning of input and forward chains
|
||||||
|
if ! iptables -nL ${INPUT} | grep -q ${blocklist_chain_name}; then
|
||||||
|
iptables -I ${INPUT} 1 "${IN_OPT}" -j ${blocklist_chain_name}
|
||||||
|
fi
|
||||||
|
if ! iptables -nL ${FORWARD} | grep -q ${blocklist_chain_name}; then
|
||||||
|
iptables -I ${FORWARD} 1 "${IN_OPT}" -j ${blocklist_chain_name}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# flush the chain referencing blacklists, they will be restored in a second
|
||||||
|
iptables -F ${blocklist_chain_name}
|
||||||
|
|
||||||
|
# create the "manual" blacklist set
|
||||||
|
# this can be populated manually using ipset command:
|
||||||
|
# ipset add manual-blacklist a.b.c.d
|
||||||
|
set_name="manual-blacklist"
|
||||||
|
if ! ipset list | grep -q "Name: ${set_name}"; then
|
||||||
|
ipset create "${set_name}" hash:net
|
||||||
|
fi
|
||||||
|
link_set "${blocklist_chain_name}" "${set_name}" "$1"
|
||||||
|
|
||||||
|
# download and process the dynamic blacklists
|
||||||
|
for url in $URLS; do
|
||||||
|
# initialize temp files
|
||||||
|
unsorted_blocklist=$(mktemp)
|
||||||
|
sorted_blocklist=$(mktemp)
|
||||||
|
new_set_file=$(mktemp)
|
||||||
|
headers=$(mktemp)
|
||||||
|
|
||||||
|
# download the blocklist
|
||||||
|
set_name=$(echo "$url" | awk -F/ '{print substr($3,0,21);}') # set name is derived from source URL hostname
|
||||||
|
curl -L -v -s ${COMPRESS_OPT} -k "$url" >"${unsorted_blocklist}" 2>"${headers}"
|
||||||
|
|
||||||
|
# this is required for blocklist.de that sends compressed content regardless of asked or not
|
||||||
|
if [ -z "$COMPRESS_OPT" ]; then
|
||||||
|
if grep -qi 'content-encoding: gzip' "${headers}"; then
|
||||||
|
mv "${unsorted_blocklist}" "${unsorted_blocklist}.gz"
|
||||||
|
gzip -d "${unsorted_blocklist}.gz"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# autodetect iblocklist.com format as it needs additional conversion
|
||||||
|
if echo "${url}" | grep -q 'iblocklist.com'; then
|
||||||
|
if [ -f /etc/range2cidr.awk ]; then
|
||||||
|
mv "${unsorted_blocklist}" "${unsorted_blocklist}.gz"
|
||||||
|
gzip -d "${unsorted_blocklist}.gz"
|
||||||
|
awk_tmp=$(mktemp)
|
||||||
|
awk -f /etc/range2cidr.awk <"${unsorted_blocklist}" >"${awk_tmp}"
|
||||||
|
mv "${awk_tmp}" "${unsorted_blocklist}"
|
||||||
|
else
|
||||||
|
echo "/etc/range2cidr.awk script not found, cannot process ${unsorted_blocklist}, skipping"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
sort -u <"${unsorted_blocklist}" | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(/[0-9]{1,2})?$" >"${sorted_blocklist}"
|
||||||
|
|
||||||
|
# calculate performance parameters for the new set
|
||||||
|
if [ "${RANDOM}" ]; then
|
||||||
|
# bash
|
||||||
|
tmp_set_name="tmp_${RANDOM}"
|
||||||
|
else
|
||||||
|
# non-bash
|
||||||
|
tmp_set_name="tmp_$$"
|
||||||
|
fi
|
||||||
|
new_list_size=$(wc -l "${sorted_blocklist}" | awk '{print $1;}')
|
||||||
|
hash_size=$(("$new_list_size" / 2))
|
||||||
|
|
||||||
|
if ! ipset -q list "${set_name}" >/dev/null; then
|
||||||
|
ipset create "${set_name}" hash:net family inet
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start writing new set file
|
||||||
|
echo "create ${tmp_set_name} hash:net family inet hashsize ${hash_size} maxelem ${new_list_size}" >>"${new_set_file}"
|
||||||
|
|
||||||
|
# convert list of IPs to ipset statements
|
||||||
|
while read -r line; do
|
||||||
|
echo "add ${tmp_set_name} ${line}" >>"${new_set_file}"
|
||||||
|
done <"$sorted_blocklist"
|
||||||
|
|
||||||
|
# replace old set with the new, temp one - this guarantees an atomic update
|
||||||
|
echo "swap ${tmp_set_name} ${set_name}" >>"${new_set_file}"
|
||||||
|
|
||||||
|
# clear old set (now under temp name)
|
||||||
|
echo "destroy ${tmp_set_name}" >>"${new_set_file}"
|
||||||
|
|
||||||
|
# actually execute the set update
|
||||||
|
ipset -! -q restore <"${new_set_file}"
|
||||||
|
|
||||||
|
link_set "${blocklist_chain_name}" "${set_name}" "$1"
|
||||||
|
|
||||||
|
# clean up temp files
|
||||||
|
rm "${unsorted_blocklist}" "${sorted_blocklist}" "${new_set_file}" "${headers}"
|
||||||
|
done
|
||||||
@ -1,80 +1,189 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# ##################################################
|
|
||||||
# ufw-ipset-blocklist-autoupdate
|
|
||||||
#
|
|
||||||
# Blocking lists of IPs from public blocklists / blacklists (e.g. blocklist.de, spamhaus.org)
|
|
||||||
#
|
|
||||||
# Version: 1.1.1
|
|
||||||
#
|
|
||||||
# See: https://github.com/ngandrass/ufw-ipset-blocklist-autoupdate
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# MIT License
|
|
||||||
#
|
|
||||||
# Copyright (c) 2023 Niels Gandraß <niels@gandrass.de>
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in all
|
|
||||||
# copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
# SOFTWARE.
|
|
||||||
# ##################################################
|
|
||||||
|
|
||||||
IPSET_BIN="$(which ipset)"
|
#### Variables ####
|
||||||
IPSET_DIR="/var/lib/ipset"
|
iproute=$(ip route get 8.8.8.8 | awk -- '{print $5}')
|
||||||
|
seedlist_dir=/var/lib/ipset
|
||||||
|
blists=$(find "$seedlist_dir" -name "*-inet.save")
|
||||||
|
|
||||||
# Check prerequisites
|
#### Check for IPset ###
|
||||||
if [ ! -x "${IPSET_BIN}" ]; then
|
if [ ! "$(command -v /usr/sbin/ipset)" ]; then
|
||||||
echo "ERROR: ipset binary not found in ${IPSET_BIN}"
|
echo "ERROR: ipset binary not found in path"
|
||||||
return
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "${IPSET_DIR}" ]; then
|
chain_exists() {
|
||||||
echo "ERROR: ipset data directory does not exist: ${IPSET_DIR}" >&2
|
{
|
||||||
return
|
[ $# -lt 1 ] || [ $# -gt 2 ] && {
|
||||||
fi
|
echo "Usage: chain_exists <chain_name>" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
savefiles=$(find "$IPSET_DIR" -name "*-inet.save")
|
chain_name="$1"
|
||||||
|
shift
|
||||||
|
[ $# -eq 1 ]
|
||||||
|
iptables -n -L "$chain_name" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_exists() {
|
||||||
|
{
|
||||||
|
[ $# -ne 1 ] && {
|
||||||
|
echo "Usage: list_exists <list_name>" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
list_name="$1"
|
||||||
|
ipset list "$list_name" -name >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Command Line Options ####
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start)
|
||||||
for f in $savefiles; do
|
for sl in $blists
|
||||||
listname=$(basename -s ".save" "$f")
|
do
|
||||||
|
listdir=$(basename -s ".save" "$sl")
|
||||||
|
#### Check for SeedList Dir ####
|
||||||
|
if [ ! -d "$seedlist_dir" ]; then
|
||||||
|
echo "ERROR: Seedlist directory does not exist" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
$IPSET_BIN restore -! <"$f"
|
ipset restore -! < "$sl"
|
||||||
iptables -I INPUT -m set --match-set "$listname" src -j DROP
|
|
||||||
iptables -I INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] "
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-input; then
|
||||||
|
iptables -D INPUT -i "$iproute" -m set --match-set "$listdir" src -j "$listdir"-input || true
|
||||||
|
iptables -D "$listdir"-input -i "$iproute" -j DROP -m comment --comment "$listdir"-input || true
|
||||||
|
iptables -F "$listdir"-input
|
||||||
|
iptables -X "$listdir"-input
|
||||||
|
fi
|
||||||
|
|
||||||
|
iptables -N "$listdir"-input
|
||||||
|
iptables -A "$listdir"-input -i "$iproute" -j DROP -m comment --comment "$listdir"-input
|
||||||
|
iptables -I INPUT -i "$iproute" -m set --match-set "$listdir" src -j "$listdir"-input
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-output; then
|
||||||
|
iptables -D OUTPUT -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-output || true
|
||||||
|
iptables -D "$listdir"-output -j DROP -m comment --comment "$listdir"-output || true
|
||||||
|
iptables -F "$listdir"-output
|
||||||
|
iptables -X "$listdir"-output
|
||||||
|
fi
|
||||||
|
|
||||||
|
iptables -N "$listdir"-output
|
||||||
|
iptables -A "$listdir"-output -j DROP -m comment --comment "$listdir"-output
|
||||||
|
iptables -I OUTPUT -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-output
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-forward; then
|
||||||
|
iptables -D FORWARD -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-forward || true
|
||||||
|
iptables -D "$listdir"-forward -i "$iproute" -j DROP -m comment --comment "$listdir"-forward || true
|
||||||
|
iptables -F "$listdir"-forward
|
||||||
|
iptables -X "$listdir"-forward
|
||||||
|
fi
|
||||||
|
|
||||||
|
iptables -N "$listdir"-forward
|
||||||
|
iptables -A "$listdir"-forward -i "$iproute" -j DROP -m comment --comment "$listdir"-forward
|
||||||
|
iptables -I FORWARD -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-forward
|
||||||
|
done
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
for f in $savefiles; do
|
for sl in $blists
|
||||||
listname=$(basename -s ".save" "$f")
|
do
|
||||||
|
listdir=$(basename -s ".save" "$sl")
|
||||||
|
#### Check for SeedList Dir ####
|
||||||
|
if [ ! -d "$seedlist_dir" ]; then
|
||||||
|
echo "ERROR: ipset data directory does not exist" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
iptables -D INPUT -m set --match-set "$listname" src -j DROP || true
|
for i in $listdir
|
||||||
iptables -D INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] " || true
|
do
|
||||||
$IPSET_BIN destroy -q "$listname" || true
|
if chain_exists "$i"-input; then
|
||||||
|
iptables -D INPUT -i "$iproute" -m set --match-set "$listdir" src -j "$listdir"-input || true
|
||||||
|
iptables -D "$listdir"-input -i "$iproute" -j DROP -m comment --comment "$listdir"-input || true
|
||||||
|
iptables -F "$listdir"-input
|
||||||
|
iptables -X "$listdir"-input
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-output; then
|
||||||
|
iptables -D OUTPUT -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-output || true
|
||||||
|
iptables -D "$listdir"-output -o "$iproute"-j DROP -m comment --comment "$listdir"-output || true
|
||||||
|
iptables -F "$listdir"-output
|
||||||
|
iptables -X "$listdir"-output
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-forward; then
|
||||||
|
iptables -D FORWARD -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-forward || true
|
||||||
|
iptables -D "$listdir"-forward -o "$iproute" -j DROP -m comment --comment "$listdir"-forward || true
|
||||||
|
iptables -F "$listdir"-forward
|
||||||
|
iptables -X "$listdir"-forward
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if list_exists "$i"; then
|
||||||
|
ipset flush "$listdir"
|
||||||
|
ipset destroy -q "$listdir" || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
echo "= after.init ="
|
echo '= after.init Blocklist(s) Status ='
|
||||||
$IPSET_BIN -t list
|
ipset -t list
|
||||||
# show iptables hit/byte counts
|
# show iptables block/byte counts
|
||||||
iptables -L -nvx | grep "$listname" | grep 'match-set'
|
echo ''
|
||||||
|
echo 'Total Block/Byte Counts by List Inbound'
|
||||||
|
echo ''
|
||||||
|
iptables -L -nvx | grep "$listdir" | grep 'match-set' | grep input | awk 'BEGIN{print "Pkts Bytes Blocklist Prot Opt In Out Source Destination"}1' | column -t
|
||||||
echo ""
|
echo ""
|
||||||
|
echo 'Total Block/Byte Counts by List Outbound'
|
||||||
|
echo ''
|
||||||
|
iptables -L -nvx | grep "$listdir" | grep 'match-set' | grep output | awk 'BEGIN{print "Pkts Bytes Blocklist Prot Opt In Out Source Destination"}1' | column -t
|
||||||
|
echo ""
|
||||||
|
echo 'Total Block/Byte Counts by List Forwarded'
|
||||||
|
echo ''
|
||||||
|
iptables -L -nvx | grep "$listdir" | grep 'match-set' | grep forward | awk 'BEGIN{print "Pkts Bytes Blocklist Prot Opt In Out Source Destination"}1' | column -t
|
||||||
|
;;
|
||||||
|
reset-count)
|
||||||
|
echo '= after.init is resetting the Block/Byte Counts ='
|
||||||
|
|
||||||
|
# reset iptables blocklist pkts/bytes
|
||||||
|
ipi=$( iptables -L INPUT -nvx --line-numbers | grep bl-| awk '{print $1}')
|
||||||
|
for i in $ipi
|
||||||
|
do
|
||||||
|
iptables -Z INPUT "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
ipo=$( iptables -L OUTPUT -nvx --line-numbers | grep bl- | awk '{print $1}')
|
||||||
|
for i in $ipo
|
||||||
|
do
|
||||||
|
iptables -Z OUTPUT "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
ipf=$( iptables -L FORWARD -nvx --line-numbers | grep bl-| awk '{print $1}')
|
||||||
|
for i in $ipf
|
||||||
|
do
|
||||||
|
iptables -Z FORWARD "$i"
|
||||||
|
done
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "'$1' not supported"
|
echo "'$1' is not supported"
|
||||||
echo "Usage: after.init {start|stop|status}"
|
echo 'Usage: /etc/ufw/after.init {start|stop|status|reset-count}'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@ -1,93 +1,189 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# ##################################################
|
|
||||||
# ufw-ipset-blocklist-autoupdate
|
|
||||||
#
|
|
||||||
# Blocking lists of IPs from public blocklists / blacklists (e.g. blocklist.de, spamhaus.org)
|
|
||||||
#
|
|
||||||
# Version: 1.1.1
|
|
||||||
#
|
|
||||||
# See: https://github.com/ngandrass/ufw-ipset-blocklist-autoupdate
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# MIT License
|
|
||||||
#
|
|
||||||
# Copyright (c) 2023 Niels Gandraß <niels@gandrass.de>
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in all
|
|
||||||
# copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
# SOFTWARE.
|
|
||||||
# ##################################################
|
|
||||||
|
|
||||||
IPSET_BIN="$(which ipset)"
|
#### Variables ####
|
||||||
IPSET_DIR="/var/lib/ipset"
|
iproute=$(ip route get 2001:4860:4860::8888 | awk -- '{print $7}')
|
||||||
|
seedlist_dir=/var/lib/ipset
|
||||||
|
blists=$(find "$seedlist_dir" -name "*-inet6.save")
|
||||||
|
|
||||||
# Check prerequisites
|
|
||||||
if [ ! -x "${IPSET_BIN}" ]; then
|
#### Check for IPset ###
|
||||||
echo "ERROR: ipset binary not found in ${IPSET_BIN}"
|
if [ ! "$(command -v /usr/sbin/ipset)" ]; then
|
||||||
return
|
echo "ERROR: ipset binary not found in path"
|
||||||
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "${IPSET_DIR}" ]; then
|
chain_exists() {
|
||||||
echo "ERROR: ipset data directory does not exist: ${IPSET_DIR}" >&2
|
{
|
||||||
return
|
[ $# -lt 1 ] || [ $# -gt 2 ] && {
|
||||||
fi
|
echo "Usage: chain_exists <chain_name>" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
savefiles=$(find "$IPSET_DIR" -name "*-inet\.save")
|
chain_name="$1"
|
||||||
savefiles6=$(find "$IPSET_DIR" -name "*-inet6\.save")
|
shift
|
||||||
|
[ $# -eq 1 ]
|
||||||
|
ip6tables -n -L "$chain_name" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_exists() {
|
||||||
|
{
|
||||||
|
[ $# -ne 1 ] && {
|
||||||
|
echo "Usage: list_exists <list_name>" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
list_name="$1"
|
||||||
|
ipset list "$list_name" -name >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#### Command Line Options ####
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start)
|
||||||
for f in $savefiles; do
|
for f in $blists
|
||||||
listname=$(basename -s ".save" "$f")
|
do
|
||||||
|
listdir=$(basename -s ".save" "$f")
|
||||||
|
#### Check for SeedList Dir ####
|
||||||
|
if [ ! -d "$seedlist_dir" ]; then
|
||||||
|
echo "ERROR: Seedlist directory does not exist" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
$IPSET_BIN restore -! <"$f"
|
ipset restore -! < "$f"
|
||||||
iptables -I INPUT -m set --match-set "$listname" src -j DROP
|
|
||||||
iptables -I INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] "
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-input; then
|
||||||
|
ip6tables -D INPUT -i "$iproute" -m set --match-set "$listdir" src -j "$listdir"-input || true
|
||||||
|
ip6tables -D "$listdir"-input -i "$iproute" -j DROP -m comment --comment "$listdir"-input || true
|
||||||
|
ip6tables -F "$listdir"-input
|
||||||
|
ip6tables -X "$listdir"-input
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip6tables -N "$listdir"-input
|
||||||
|
ip6tables -A "$listdir"-input -i "$iproute" -j DROP -m comment --comment "$listdir"-input
|
||||||
|
ip6tables -I INPUT -i "$iproute" -m set --match-set "$listdir" src -j "$listdir"-input
|
||||||
done
|
done
|
||||||
for f in $savefiles6; do
|
|
||||||
listname=$(basename -s ".save" "$f")
|
|
||||||
|
|
||||||
$IPSET_BIN restore -! <"$f"
|
for i in $listdir
|
||||||
ip6tables -I INPUT -m set --match-set "$listname" src -j DROP
|
do
|
||||||
ip6tables -I INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] "
|
if chain_exists "$i"-output; then
|
||||||
|
ip6tables -D OUTPUT -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-output || true
|
||||||
|
ip6tables -D "$listdir"-output -j DROP -m comment --comment "$listdir"-output || true
|
||||||
|
ip6tables -F "$listdir"-output
|
||||||
|
ip6tables -X "$listdir"-output
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip6tables -N "$listdir"-output
|
||||||
|
ip6tables -A "$listdir"-output -j DROP -m comment --comment "$listdir"-output
|
||||||
|
ip6tables -I OUTPUT -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-output
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-forward; then
|
||||||
|
ip6tables -D FORWARD -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-forward || true
|
||||||
|
ip6tables -D "$listdir"-forward -o "$iproute" -j DROP -m comment --comment "$listdir"-forward || true
|
||||||
|
ip6tables -F "$listdir"-forward
|
||||||
|
ip6tables -X "$listdir"-forward
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip6tables -N "$listdir"-forward
|
||||||
|
ip6tables -A "$listdir"-forward -o "$iproute" -j DROP -m comment --comment "$listdir"-forward
|
||||||
|
ip6tables -I FORWARD -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-forward
|
||||||
|
done
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
for f in $savefiles; do
|
for f in $blists
|
||||||
listname=$(basename -s ".save" "$f")
|
do
|
||||||
|
listdir=$(basename -s ".save" "$f")
|
||||||
|
#### Check for SeedList Dir ####
|
||||||
|
if [ ! -d "$seedlist_dir" ]; then
|
||||||
|
echo "ERROR: ipset data directory does not exist" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
iptables -D INPUT -m set --match-set "$listname" src -j DROP || true
|
for i in $listdir
|
||||||
iptables -D INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] " || true
|
do
|
||||||
$IPSET_BIN destroy -q "$listname" || true
|
if chain_exists "$i"-input; then
|
||||||
|
ip6tables -D INPUT -i "$iproute" -m set --match-set "$listdir" src -j "$listdir"-input || true
|
||||||
|
ip6tables -D "$listdir"-input -i "$iproute" -j DROP -m comment --comment "$listdir"-input || true
|
||||||
|
ip6tables -F "$listdir"-input
|
||||||
|
ip6tables -X "$listdir"-input
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
for f in $savefiles6; do
|
|
||||||
listname=$(basename -s ".save" "$f")
|
|
||||||
|
|
||||||
ip6tables -D INPUT -m set --match-set "$listname" src -j DROP || true
|
for i in $listdir
|
||||||
ip6tables -D INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] " || true
|
do
|
||||||
$IPSET_BIN destroy -q "$listname" || true
|
if chain_exists "$i"-output; then
|
||||||
|
ip6tables -D OUTPUT -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-output || true
|
||||||
|
ip6tables -D "$listdir"-output -o "$iproute" -j DROP -m comment --comment "$listdir"-output || true
|
||||||
|
ip6tables -F "$listdir"-output
|
||||||
|
ip6tables -X "$listdir"-output
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if chain_exists "$i"-forward; then
|
||||||
|
ip6tables -D FORWARD -o "$iproute" -m set --match-set "$listdir" dst -j "$listdir"-forward || true
|
||||||
|
ip6tables -D "$listdir"-forward -o "$iproute" -j DROP -m comment --comment "$listdir"-forward || true
|
||||||
|
ip6tables -F "$listdir"-forward
|
||||||
|
ip6tables -X "$listdir"-forward
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in $listdir
|
||||||
|
do
|
||||||
|
if list_exists "$i"; then
|
||||||
|
ipset flush "$listdir"
|
||||||
|
ipset destroy -q "$listdir" || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
echo "= after.init ="
|
echo '= after.init Blocklist(s) Status ='
|
||||||
$IPSET_BIN -t list
|
ipset -t list
|
||||||
|
#### show ip6tables block/byte counts ####
|
||||||
|
echo ''
|
||||||
|
echo 'Total Block/Byte Counts by List Inbound'
|
||||||
|
echo ''
|
||||||
|
ip6tables -L -nvx | grep "$listdir" | grep 'match-set' | grep input | awk 'BEGIN{print "Pkts Bytes Blocklist Prot Opt In Out Source Destination"}1' | column -t
|
||||||
echo ""
|
echo ""
|
||||||
|
echo 'Total Block/Byte Counts by List Outbound'
|
||||||
|
echo ''
|
||||||
|
ip6tables -L -nvx | grep "$listdir" | grep 'match-set' | grep output | awk 'BEGIN{print "Pkts Bytes Blocklist Prot Opt In Out Source Destination"}1' | column -t
|
||||||
|
echo ""
|
||||||
|
echo 'Total Block/Byte Counts by List Forwarded'
|
||||||
|
echo ''
|
||||||
|
ip6tables -L -nvx | grep "$listdir" | grep 'match-set' | grep forward | awk 'BEGIN{print "Pkts Bytes Blocklist Prot Opt In Out Source Destination"}1' | column -t
|
||||||
|
;;
|
||||||
|
reset-count)
|
||||||
|
echo '= after.init is resetting the Block/Byte Counts ='
|
||||||
|
#### reset ip6tables blocklist counts ####
|
||||||
|
ipi=$( ip6tables -L INPUT -nvx --line-numbers | grep bl-| awk '{print $1}')
|
||||||
|
for i in $ipi
|
||||||
|
do
|
||||||
|
ip6tables -Z INPUT "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
ipo=$( ip6tables -L OUTPUT -nvx --line-numbers | grep bl- | awk '{print $1}')
|
||||||
|
for i in $ipo
|
||||||
|
do
|
||||||
|
ip6tables -Z OUTPUT "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
ipf=$( ip6tables -L FORWARD -nvx --line-numbers | grep bl-| awk '{print $1}')
|
||||||
|
for i in $ipf
|
||||||
|
do
|
||||||
|
ip6tables -Z FORWARD "$i"
|
||||||
|
done
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "'$1' not supported"
|
echo "'$1' is not supported"
|
||||||
echo "Usage: after.init {start|stop|status}"
|
echo 'Usage: /etc/ufw/after.init {start|stop|status|reset-count}'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
71
UFW-Blocklist/blocklist_update
Normal file
71
UFW-Blocklist/blocklist_update
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
#### Variables
|
||||||
|
seedlist_dir=/var/lib/ipset
|
||||||
|
update=/usr/local/bin/ufw-blocklists.sh
|
||||||
|
blists=$(find "$seedlist_dir" -name "*-inet.save")
|
||||||
|
blists6=$(find "$seedlist_dir" -name "*-inet6.save")
|
||||||
|
|
||||||
|
#### Check for SeedList Dir ####
|
||||||
|
if [ ! -d "$seedlist_dir" ]; then
|
||||||
|
echo "ERROR: ipset data directory does not exist" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
#### Update Ipv4 Blocklist ####
|
||||||
|
for seeds in $blists
|
||||||
|
do
|
||||||
|
seedlists=$(basename -s ".save" "$seeds")
|
||||||
|
if [ "$seedlists" = bl-bdsatib-inet ]; then
|
||||||
|
$update -l "bdsatib https://www.binarydefense.com/banlist.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-bfblocker-inet ]; then
|
||||||
|
$update -l "bfblocker https://danger.rulez.sk/projects/bruteforceblocker/blist.php"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-cinsarmy-inet ]; then
|
||||||
|
$update -l "cinsarmy http://cinsscore.com/list/ci-badguys.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-drop-inet ]; then
|
||||||
|
$update -l "drop https://www.spamhaus.org/drop/drop.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-dshield-inet ]; then
|
||||||
|
$update -l "dshield https://iplists.firehol.org/files/dshield.netset"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-edrop-inet ]; then
|
||||||
|
$update -l "edrop https://www.spamhaus.org/drop/edrop.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-f2ball-inet ]; then
|
||||||
|
$update -l "f2ball https://lists.blocklist.de/lists/all.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-firehol1-inet ]; then
|
||||||
|
$update -l "firehol1 https://iplists.firehol.org/files/firehol_level1.netset"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-greensnow-inet ]; then
|
||||||
|
$update -l "greensnow https://blocklist.greensnow.co/greensnow.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-ipsuml2-inet ]; then
|
||||||
|
$update -l "ipsuml2 https://raw.githubusercontent.com/stamparm/ipsum/master/levels/2.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-maxmind-inet ]; then
|
||||||
|
$update -l "maxmind https://www.maxmind.com/en/anonymous_proxies"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
#### Update Ipv6 Blocklist ####
|
||||||
|
for seeds in $blists6
|
||||||
|
do
|
||||||
|
seedlists=$(basename -s ".save" "$seeds")
|
||||||
|
if [ "$seedlists" = bl-dropv6-inet ]; then
|
||||||
|
$update -l "dropv6 https://www.spamhaus.org/drop/dropv6.txt"
|
||||||
|
fi
|
||||||
|
done
|
||||||
26
UFW-Blocklist/feodobl_update
Normal file
26
UFW-Blocklist/feodobl_update
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
#### Variables ####
|
||||||
|
seedlist_dir=/var/lib/ipset
|
||||||
|
update=/usr/local/bin/ufw-blocklists.sh
|
||||||
|
blists=$(find "$seedlist_dir" -name "*-inet.save")
|
||||||
|
|
||||||
|
#### Check for SeedList Dir ####
|
||||||
|
if [ ! -d "$seedlist_dir" ]; then
|
||||||
|
echo "ERROR: ipset data directory does not exist" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
#### Update Loop ####
|
||||||
|
for seeds in $blists
|
||||||
|
do
|
||||||
|
seedlists=$(basename -s ".save" "$seeds")
|
||||||
|
if [ "$seedlists" = bl-feodoc2-inet ]; then
|
||||||
|
$update -l "feodoc2 https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$seedlists" = bl-feodoc2ioc-inet ]; then
|
||||||
|
$update -l "feodoc2ioc https://feodotracker.abuse.ch/downloads/ipblocklist.txt"
|
||||||
|
fi
|
||||||
|
done
|
||||||
@ -36,7 +36,7 @@ chain_exists() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
local chain_name="$1" ; shift
|
chain_name="$1" ; shift
|
||||||
[ $# -eq 1 ] && local table="--table $1"
|
[ $# -eq 1 ] && local table="--table $1"
|
||||||
iptables "$table" -n --list "$chain_name" >/dev/null 2>&1
|
iptables "$table" -n --list "$chain_name" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# ##################################################
|
|
||||||
# ufw-ipset-blocklist-autoupdate
|
|
||||||
#
|
|
||||||
# Blocking lists of IPs from public blocklists / blacklists (e.g. blocklist.de, spamhaus.org)
|
|
||||||
#
|
|
||||||
# Version: 1.1.1
|
|
||||||
#
|
|
||||||
# See: https://github.com/ngandrass/ufw-ipset-blocklist-autoupdate
|
|
||||||
# ##################################################
|
|
||||||
|
|
||||||
IPSET_BIN="/usr/bin/ipset" # Path to ipset binary. Updated by detect_ipset().
|
|
||||||
IPSET_DIR="/var/lib/ipset" # Folder to write ipset save files to
|
|
||||||
IPSET_PREFIX="bl" # Prefix for ipset names
|
IPSET_PREFIX="bl" # Prefix for ipset names
|
||||||
IPSET_TYPE="hash:net" # Type of created ipsets
|
IPSET_TYPE="hash:net" # Type of created ipsets
|
||||||
IPV4=1 # Enable IPv4 by default
|
IPV4=1 # Enable IPv4 by default
|
||||||
@ -22,6 +12,18 @@ declare -A BLOCKLISTS # Array for blocklists to use. Populated by CLI args
|
|||||||
IPV4_REGEX="(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/[1-3]?[0-9])?" # Regex for a valid IPv4 address with optional subnet part
|
IPV4_REGEX="(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/[1-3]?[0-9])?" # Regex for a valid IPv4 address with optional subnet part
|
||||||
IPV6_REGEX="(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(/[1-6]?[0-9])?" # Regef for a valid IPv6 address with optional subnet part
|
IPV6_REGEX="(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(/[1-6]?[0-9])?" # Regef for a valid IPv6 address with optional subnet part
|
||||||
|
|
||||||
|
if [ ! "$(command -v ipset)" ]; then
|
||||||
|
apt -y install ipset
|
||||||
|
else
|
||||||
|
IPSET_BIN=$(command -v ipset)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "/var/lib/ipset" ]; then
|
||||||
|
mkdir -p /var/lib/ipset
|
||||||
|
else
|
||||||
|
IPSET_DIR="/var/lib/ipset" # Folder to write ipset save files to
|
||||||
|
fi
|
||||||
|
|
||||||
##
|
##
|
||||||
# Prints the help/usage message
|
# Prints the help/usage message
|
||||||
##
|
##
|
||||||
@ -48,12 +50,7 @@ EOF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
#### Writes argument $1 to stdout if $QUIET is not set
|
||||||
# Writes argument $1 to stdout if $QUIET is not set
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 Message to write to stdout
|
|
||||||
##
|
|
||||||
function log() {
|
function log() {
|
||||||
{
|
{
|
||||||
if [[ $QUIET -eq 0 ]]; then
|
if [[ $QUIET -eq 0 ]]; then
|
||||||
@ -62,12 +59,7 @@ function log() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
#### Writes argument $1 to stdout if $VERBOSE is set and $QUIET is not set
|
||||||
# Writes argument $1 to stdout if $VERBOSE is set and $QUIET is not set
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 Message to write to stdout
|
|
||||||
##
|
|
||||||
function log_verbose() {
|
function log_verbose() {
|
||||||
{
|
{
|
||||||
if [[ $VERBOSE -eq 1 ]]; then
|
if [[ $VERBOSE -eq 1 ]]; then
|
||||||
@ -78,38 +70,14 @@ function log_verbose() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
#### Writes argument $1 to stderr. Ignores $QUIET.
|
||||||
# Writes argument $1 to stderr. Ignores $QUIET.
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 Message to write to stderr
|
|
||||||
##
|
|
||||||
function log_error() {
|
function log_error() {
|
||||||
{
|
{
|
||||||
>&2 echo "[ERROR]: $1"
|
>&2 echo "[ERROR]: $1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
#### Validates the BLOCKLISTS array. Exits upon error.
|
||||||
# Detects ipset binary
|
|
||||||
#
|
|
||||||
# Return: Path to ipset
|
|
||||||
#
|
|
||||||
function detect_ipset() {
|
|
||||||
{
|
|
||||||
IPSET_BIN=$(which ipset)
|
|
||||||
if [ ! -x "${IPSET_BIN}" ]; then
|
|
||||||
log_error "ipset binary not found."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "${IPSET_BIN}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# Validates the correctness of the BLOCKLISTS array. Exits upon error.
|
|
||||||
#
|
|
||||||
function validate_blocklists() {
|
function validate_blocklists() {
|
||||||
{
|
{
|
||||||
if [ ${#BLOCKLISTS[@]} -eq 0 ]; then
|
if [ ${#BLOCKLISTS[@]} -eq 0 ]; then
|
||||||
@ -138,23 +106,17 @@ function validate_blocklists() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
#### Updates an ipset based on a list of IP addresses
|
||||||
# Updates an ipset based on a list of IP addresses
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 Name of the ipset to update
|
|
||||||
# $2 File containing all IP addresses to store in ipset
|
|
||||||
# $3 Procotol family (e.g. inet OR inet6)
|
|
||||||
function update_ipset() {
|
function update_ipset() {
|
||||||
{
|
{
|
||||||
# Setup local vars
|
# Setup local vars
|
||||||
local setname=$1
|
setname=$1 # $1 Name of the ipset to update
|
||||||
local ipfile=$2
|
ipfile=$2 # $2 File containing all IP addresses to store in ipset
|
||||||
local family=$3
|
family=$3 # $3 Procotol family (e.g. inet OR inet6)
|
||||||
|
|
||||||
# Create temporary ipset to build and ensure existence of live ipset
|
# Create temporary ipset to build and ensure existence of live ipset
|
||||||
local livelist="$setname-$family"
|
livelist="$setname-$family"
|
||||||
local templist="$setname-$family-T"
|
templist="$setname-$family-T"
|
||||||
|
|
||||||
$IPSET_BIN create -q "$livelist" "$IPSET_TYPE" family "$family"
|
$IPSET_BIN create -q "$livelist" "$IPSET_TYPE" family "$family"
|
||||||
$IPSET_BIN create -q "$templist" "$IPSET_TYPE" family "$family"
|
$IPSET_BIN create -q "$templist" "$IPSET_TYPE" family "$family"
|
||||||
@ -181,18 +143,12 @@ function update_ipset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
#### Updates the given blocklist from an URL
|
||||||
# Updates the given blocklist from an URL
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 Name of the blocklist
|
|
||||||
# $2 URL of the blocklist
|
|
||||||
#
|
|
||||||
function update_blocklist() {
|
function update_blocklist() {
|
||||||
{
|
{
|
||||||
# Download blocklist
|
# Download blocklist
|
||||||
log "Updating blacklist '$1' ..."
|
log "Updating blacklist '$1' ..." # $1 Name of the blocklist
|
||||||
log_verbose "Downloading blocklist '$1' from: $2 ..."
|
log_verbose "Downloading blocklist '$1' from: $2 ..." # $2 URL of the blocklist
|
||||||
tempfile=$(mktemp "/tmp/blocklist.$1.XXXXXXXX")
|
tempfile=$(mktemp "/tmp/blocklist.$1.XXXXXXXX")
|
||||||
wget -q -O "$tempfile" "$2"
|
wget -q -O "$tempfile" "$2"
|
||||||
|
|
||||||
@ -214,7 +170,9 @@ function update_blocklist() {
|
|||||||
else
|
else
|
||||||
log_verbose "No IPv4 addresses found in blocklist '$1'. Skipping"
|
log_verbose "No IPv4 addresses found in blocklist '$1'. Skipping"
|
||||||
fi
|
fi
|
||||||
elif [[ $IPV6 -eq 1 ]]; then
|
fi
|
||||||
|
|
||||||
|
if [[ $IPV6 -eq 1 ]]; then
|
||||||
grep -v '^[#;]' "$tempfile" | grep -E -o "$IPV6_REGEX" | cut -d ' ' -f 1 > "$tempfile.filtered6"
|
grep -v '^[#;]' "$tempfile" | grep -E -o "$IPV6_REGEX" | cut -d ' ' -f 1 > "$tempfile.filtered6"
|
||||||
numips=$(wc -l < "$tempfile.filtered6")
|
numips=$(wc -l < "$tempfile.filtered6")
|
||||||
log_verbose "Got $numips IPv6 entries from blocklist '$1'"
|
log_verbose "Got $numips IPv6 entries from blocklist '$1'"
|
||||||
@ -231,23 +189,16 @@ function update_blocklist() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
##
|
#### Main loop
|
||||||
# Main program loop
|
|
||||||
##
|
|
||||||
function main() {
|
function main() {
|
||||||
{
|
{
|
||||||
# Check arguments
|
# Check arguments
|
||||||
validate_blocklists
|
validate_blocklists
|
||||||
|
|
||||||
# Setup ipset
|
|
||||||
IPSET_BIN=$(detect_ipset)
|
|
||||||
mkdir -p "${IPSET_DIR}"
|
|
||||||
|
|
||||||
# Update blocklists
|
# Update blocklists
|
||||||
for list in "${BLOCKLISTS[@]}"; do
|
for list in "${BLOCKLISTS[@]}"; do
|
||||||
list_name=$(echo "$list" | cut -d ' ' -f 1)
|
list_name=$(echo "$list" | cut -d ' ' -f 1)
|
||||||
list_url=$(echo "$list" | cut -d ' ' -f 2)
|
list_url=$(echo "$list" | cut -d ' ' -f 2)
|
||||||
|
|
||||||
update_blocklist "$list_name" "$list_url"
|
update_blocklist "$list_name" "$list_url"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -280,5 +231,5 @@ while getopts ":hqv46l:" opt
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Entry point
|
#### Min function call
|
||||||
main
|
main
|
||||||
@ -1,5 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
LOGFILE=/var/log/auth.log # Log file
|
||||||
|
LINE=0 # Where to start count
|
||||||
|
|
||||||
# Install geoiplookup if needed
|
# Install geoiplookup if needed
|
||||||
if [ ! "$(command -v geoiplookup)" ]; then
|
if [ ! "$(command -v geoiplookup)" ]; then
|
||||||
apt -y install geoip-bin
|
apt -y install geoip-bin
|
||||||
@ -12,9 +16,6 @@ BY="\033[1;33m" # Bold Yellow
|
|||||||
GR="\033[0;32m" # Green
|
GR="\033[0;32m" # Green
|
||||||
LY="\033[3;33m" # Light Yellow
|
LY="\033[3;33m" # Light Yellow
|
||||||
RB="\033[1;31m" # Red bold (Default)
|
RB="\033[1;31m" # Red bold (Default)
|
||||||
|
|
||||||
LOGFILE=/var/log/auth.log # Log file
|
|
||||||
LINE=0 # Where to start count
|
|
||||||
NC="\033[00m" # Color Reset
|
NC="\033[00m" # Color Reset
|
||||||
|
|
||||||
while true
|
while true
|
||||||
@ -28,7 +29,7 @@ while true
|
|||||||
else
|
else
|
||||||
LOCATION=$(geoiplookup6 "$i" | awk '{print $6 " " $7}')
|
LOCATION=$(geoiplookup6 "$i" | awk '{print $6 " " $7}')
|
||||||
fi
|
fi
|
||||||
echo -e "[*] The Attacker's Country: ${RB}$LOCATION ${NC}[IP ADDRESS:${RB} $i] ${NC}"
|
echo -e "[*] The Blocked Attacker's Country: ${RB}$LOCATION ${NC}[IP ADDRESS:${RB} $i]${NC}"
|
||||||
|
|
||||||
done
|
done
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user