Initial Commit

This commit is contained in:
Phil Connor 2024-06-26 15:43:16 -05:00
parent 9f59dfc9e8
commit 6cee4da2c1
19 changed files with 1951 additions and 151 deletions

89
Pages/ufw-autoupdate.html Normal file
View File

@ -0,0 +1,89 @@
ufw-ipset-blocklist-autoupdate
Latest Version Maintenance Status License GitHub Issues GitHub Pull Requests Donate with PayPal Sponsor with GitHub GitHub Stars GitHub Forks GitHub Contributors
This collection of scripts automatically pulls IP blocklists (e.g. Spamhaus, Blocklist, ...) and drops packages from listed IP addresses. It integrates with the uncomplicated firewall (ufw) and makes use of ipset for storing IP addresses and network ranges. Both IPv4 and IPv6 blocklists are supported.
Installation
Install ufw and ipset.
Deploy after.init script via executing: ./setup-ufw.sh
Determine the blocklist you would like to use.
Get initial set of blocklists: ./update-ip-blocklists.sh -l "blocklist https://lists.blocklist.de/lists/all.txt" -l "spamhaus https://www.spamhaus.org/drop/drop.txt"
Add update-ip-blocklists.sh to your crontab:
@daily /path/to/update-ip-blocklists.sh -l "blocklist https://lists.blocklist.de/lists/all.txt" -l "spamhaus https://www.spamhaus.org/drop/drop.txt"
Usage
Usage: ./update-ip-blocklists.sh [-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:
./update-ip-blocklists.sh -l "spamhaus https://www.spamhaus.org/drop/drop.txt"
./update-ip-blocklists.sh -l "blocklist https://lists.blocklist.de/lists/all.txt" -l "spamhaus https://www.spamhaus.org/drop/drop.txt"
./update-ip-blocklists.sh -l "spamhaus https://www.spamhaus.org/drop/drop.txt" -l "spamhaus6 https://www.spamhaus.org/drop/dropv6.txt"
Supplying blocklist sources
Blocklists can be passed to the script using the -l CLI argument. Each entry consists of a name and download URL, separated by a space. Examples:
-l "spamhaus https://www.spamhaus.org/drop/drop.txt"
-l "mylist http://mylist.local/list.txt"
-l "spamhaus6 https://www.spamhaus.org/drop/dropv6.txt"
Lists are stripped of comments. This means all text after one of the following characters is removed before parsing: ;, #. Valid IPv4/IPv6 addresses with an optional CIDR are loaded into the ipset to block.
Processing of either IPv6 or IPv4 addresses can be disabled by supplying the -4 (IPv4 only) or -6 (IPv6 only) flags respectively.
Listing blocked IPs
The total number of blocked IPs is indicated by running ipset -t list. A full list of all blocked addresses is given by ipset list.
Components
update-ip-blocklist.sh: Pulls the latest versions of requested blocklists, updates ipsets, and exports created ipsets to $IPSET_DIR (default: /var/lib/ipset). Ipsets are swapped during update to minimize the update downtime.
ufw/after.init: Inserts and deletes the required iptables rules on ufw reloads. Ipsets are loaded from $IPSET_DIR.
setup-ufw.sh: Helper script to deploy ufw/after.init.
Available blocklists
This script can parse all blocklists that list IPv4 or IPv6 addresses with optional CIDR notation row per row in a plain text format (see Supplying blocklist sources).
The following blocklists are known to work. They can be enabled by passing the respective -l argument to the update-ip-blocklists.sh script.
Binary Defense Systems Artillery Threat Intelligence Banlist:
-l "bdsatib https://www.binarydefense.com/banlist.txt"
Blocklist.de Fail2Ban Reporting (all):
-l "blocklist https://lists.blocklist.de/lists/all.txt"
BruteForceBlocker:
-l "bfblocker https://danger.rulez.sk/projects/bruteforceblocker/blist.php"
CINS Army List:
-l "cnisarmy http://cinsscore.com/list/ci-badguys.txt"
FEODO Tracker: Botnet C2 (Recommended):
-l "feodoc2 https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt"
FEODO Tracker: Botnet C2 IoC (Recommended):
-l "feodoc2ioc https://feodotracker.abuse.ch/downloads/ipblocklist.txt"
FEODO Tracker: Botnet C2 IoC (Aggressive):
-l "feodoc2ioca https://feodotracker.abuse.ch/downloads/ipblocklist_aggressive.txt"
FireHOL IP List Level 1:
-l "firehol1 https://iplists.firehol.org/files/firehol_level1.netset"
GreenSnow:
-l "greensnow https://blocklist.greensnow.co/greensnow.txt"
IPsum:
-l "ipsum https://raw.githubusercontent.com/stamparm/ipsum/master/levels/3.txt"
Spamhaus Don't Route Or Peer List (DROP):
-l "spamhaus https://www.spamhaus.org/drop/drop.txt"
Spamhaus IPv6 DROP List (DROPv6):
-l "spamhaus6 https://www.spamhaus.org/drop/dropv6.txt"
Spamhaus Extended DROP List (EDROP):
-l "spamhausex https://www.spamhaus.org/drop/edrop.txt"
Acknowledgments
This project is inspired by this post on Xela's Linux Blog.

View File

@ -0,0 +1,35 @@
#!/bin/bash
# Install geoiplookup if needed
if [ ! "$(command -v geoiplookup)" ]; then
apt -y install geoip-bin
fi
# Colors for Location/Address
BB="\033[1;34m" # Blue bold
BW="\033[1;37m" # Bold White
BY="\033[1;33m" # Bold Yellow
GR="\033[0;32m" # Green
LY="\033[3;33m" # Light Yellow
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
while true
do
for i in $(cat $LOGFILE | awk "NR>$LINE" | grep Invalid | awk '{print $(NF-2)}' | uniq)
do
LINE=$(cat $LOGFILE | wc -l)
# Detect if IPv4 address for lookups
if [ "$i" != "${i#*[0-9].[0-9]}" ]; then
LOCATION=$(geoiplookup "$i" | awk '{print $5 " " $6}')
else
LOCATION=$(geoiplookup6 "$i" | awk '{print $6 " " $7}')
fi
echo -e "[*] The Attacker's Country: ${RB}$LOCATION ${NC}[IP ADDRESS:${RB} $i] ${NC}"
done
sleep 2
done

View File

@ -1,172 +1,80 @@
#!/bin/bash #!/bin/bash
# ##################################################
# ufw-ipset-blocklist-autoupdate
# #
# after.init: if executable, called by ufw-init. See 'man ufw-framework' for # Blocking lists of IPs from public blocklists / blacklists (e.g. blocklist.de, spamhaus.org)
# details. Note that output from these scripts is not seen via the
# the ufw command, but instead via ufw-init.
# #
############################################################################### # Version: 1.1.1
#### #### #
#### Based on ufw-blocklist edition: IP blocklist extension for Ubuntu ufw #### # See: https://github.com/ngandrass/ufw-ipset-blocklist-autoupdate
#### https://github.com/poddmo/ufw-blocklist #### #
#### #### #
#### Modified https://mylinux.work #### # MIT License
#### Version 1.0.2.061324 #### #
#### Contact: contact@mylinux.work #### # Copyright (c) 2023 Niels Gandraß <niels@gandrass.de>
#### #### #
############################################################################### # Permission is hereby granted, free of charge, to any person obtaining a copy
set -e # 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.
# ##################################################
export ipsetname=ufw-blocklist-ipsum IPSET_BIN="$(which ipset)"
IPSET_DIR="/var/lib/ipset"
# seed file containing the list of IP addresses to be blocked, one per line # Check prerequisites
export seedlist=/etc/ipsum.ipv4.txt if [ ! -x "${IPSET_BIN}" ]; then
echo "ERROR: ipset binary not found in ${IPSET_BIN}"
return
fi
export IPSET_EXE="/sbin/ipset" if [ ! -d "${IPSET_DIR}" ]; then
# check ipset exists and is executable echo "ERROR: ipset data directory does not exist: ${IPSET_DIR}" >&2
[ -x "$IPSET_EXE" ] || { return
echo "$IPSET_EXE is not executable" fi
exit 1
}
# Function to check if a chain exists (chain_exists ufw_blocklist_input && action if true || action if false)
chain_exists() {
{
[ $# -lt 1 ] || [ $# -gt 2 ] && {
echo "Usage: chain_exists <chain_name> [table]" >&2
return 1
}
local chain_name="$1" ; shift
[ $# -eq 1 ] && local table="--table $1"
iptables "$table" -n --list "$chain_name" >/dev/null 2>&1
}
}
# Function to check if an set exists (set_exists setname && action if true || action if false)
set_exists() {
{
[ $# -ne 1 ] && {
echo "Usage: set_exists <set_name>" >&2
return 1
}
local set_name="$1"
ipset list "$set_name" -name >/dev/null 2>&1
}
}
savefiles=$(find "$IPSET_DIR" -name "*-inet.save")
case "$1" in case "$1" in
start) start)
# check that blocklist seed file exists for f in $savefiles; do
if [ ! -f "$seedlist" ]; then listname=$(basename -s ".save" "$f")
echo "ufw after.init: $seedlist does not exist."
exit 1
fi
# create an empty ipset $IPSET_BIN restore -! <"$f"
$IPSET_EXE create $ipsetname hash:net -exist iptables -I INPUT -m set --match-set "$listname" src -j DROP
$IPSET_EXE flush $ipsetname iptables -I INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] "
done
## Insert firewall rules to take precedence, removing them and adding them back if they already existed
# Block inbound to localhost from blocklist
if chain_exists ufw-blocklist-input; then
iptables -D INPUT -m set --match-set $ipsetname src -j ufw-blocklist-input || true
iptables -F ufw-blocklist-input
iptables -X ufw-blocklist-input
fi
iptables -N ufw-blocklist-input
iptables -A ufw-blocklist-input -j DROP -m comment --comment "ufw-blocklist-input"
iptables -I INPUT -m set --match-set $ipsetname src -j ufw-blocklist-input
# Log and drop outbound to blocklist. Hits here may indicate compromised localhost
if chain_exists ufw-blocklist-output; then
iptables -D OUTPUT -m set --match-set $ipsetname dst -j ufw-blocklist-output || true
iptables -F ufw-blocklist-output
iptables -X ufw-blocklist-output
fi
iptables -N ufw-blocklist-output
iptables -A ufw-blocklist-output -j LOG --log-level 3 --log-prefix "[UFW BLOCKLIST OUTPUT] " -m limit --limit 3/minute --limit-burst 10
iptables -A ufw-blocklist-output -j DROP -m comment --comment "ufw-blocklist-output"
iptables -I OUTPUT -m set --match-set $ipsetname dst -j ufw-blocklist-output
# Log and drop forwarding to blocklist. Hits here may indicate compromised internal hosts
if chain_exists ufw-blocklist-forward; then
iptables -D FORWARD -m set --match-set $ipsetname dst -j ufw-blocklist-forward || true
iptables -F ufw-blocklist-forward
iptables -X ufw-blocklist-forward
fi
iptables -N ufw-blocklist-forward
iptables -A ufw-blocklist-forward -j LOG --log-level 3 --log-prefix "[UFW BLOCKLIST FORWARD] " -m limit --limit 3/minute --limit-burst 10
iptables -A ufw-blocklist-forward -j DROP -m comment --comment "ufw-blocklist-forward"
iptables -I FORWARD -m set --match-set $ipsetname dst -j ufw-blocklist-forward
# add members to the ipset
# start this in a subshell and then disown the job so we return quickly.
(
while read -r ip < "$seedlist"
do
$IPSET_EXE add "$ipsetname" "$ip"
done
) < /dev/null &> /dev/null & disown -h
;; ;;
stop) stop)
for f in $savefiles; do
listname=$(basename -s ".save" "$f")
# delete resources created above iptables -D INPUT -m set --match-set "$listname" src -j DROP || true
if chain_exists ufw-blocklist-input; then iptables -D INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] " || true
iptables -D INPUT -m set --match-set $ipsetname src -j ufw-blocklist-input || true $IPSET_BIN destroy -q "$listname" || true
iptables -F ufw-blocklist-input done
iptables -X ufw-blocklist-input
fi
if chain_exists ufw-blocklist-output; then
iptables -D OUTPUT -m set --match-set $ipsetname dst -j ufw-blocklist-output || true
iptables -F ufw-blocklist-output
iptables -X ufw-blocklist-output
fi
if chain_exists ufw-blocklist-forward; then
iptables -D FORWARD -m set --match-set $ipsetname dst -j ufw-blocklist-forward || true
iptables -F ufw-blocklist-forward
iptables -X ufw-blocklist-forward
fi
if set_exists $ipsetname; then
$IPSET_EXE flush $ipsetname
$IPSET_EXE destroy $ipsetname
fi
;; ;;
status) status)
# display details of the ipset echo "= after.init ="
$IPSET_EXE list "$ipsetname" -t $IPSET_BIN -t list
# show iptables hit/byte counts # show iptables hit/byte counts
iptables -L -nvx | grep "$ipsetname" | grep 'match-set' iptables -L -nvx | grep "$listname" | grep 'match-set'
echo ""
# show the last 10 lines from the logs
journalctl | grep -i blocklist | tail
;;
flush-all)
# flush sets created above. Use /etc/cron.daily/ufw-blocklist-ipsum to repopulate
$IPSET_EXE flush $ipsetname
# reset iptables accounting
ipz=$( iptables -L INPUT -nvx --line-numbers | grep ufw-blocklist-input | awk '{print $1}')
iptables -Z INPUT "$ipz"
iptables -Z ufw-blocklist-input
ipz=$( iptables -L OUTPUT -nvx --line-numbers | grep ufw-blocklist-output | awk '{print $1}')
iptables -Z OUTPUT "$ipz"
iptables -Z ufw-blocklist-output
ipz=$( iptables -L FORWARD -nvx --line-numbers | grep ufw-blocklist-forward | awk '{print $1}')
iptables -Z FORWARD "$ipz"
iptables -Z ufw-blocklist-forward
;; ;;
*) *)
echo "'$1' not supported" echo "'$1' not supported"
echo "Usage: /etc/ufw/after.init {start|stop|flush-all|status}" echo "Usage: after.init {start|stop|status}"
;; ;;
esac esac

93
UFW-Blocklist/after6.init Normal file
View File

@ -0,0 +1,93 @@
#!/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)"
IPSET_DIR="/var/lib/ipset"
# Check prerequisites
if [ ! -x "${IPSET_BIN}" ]; then
echo "ERROR: ipset binary not found in ${IPSET_BIN}"
return
fi
if [ ! -d "${IPSET_DIR}" ]; then
echo "ERROR: ipset data directory does not exist: ${IPSET_DIR}" >&2
return
fi
savefiles=$(find "$IPSET_DIR" -name "*-inet\.save")
savefiles6=$(find "$IPSET_DIR" -name "*-inet6\.save")
case "$1" in
start)
for f in $savefiles; do
listname=$(basename -s ".save" "$f")
$IPSET_BIN 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] "
done
for f in $savefiles6; do
listname=$(basename -s ".save" "$f")
$IPSET_BIN restore -! <"$f"
ip6tables -I INPUT -m set --match-set "$listname" src -j DROP
ip6tables -I INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] "
done
;;
stop)
for f in $savefiles; do
listname=$(basename -s ".save" "$f")
iptables -D INPUT -m set --match-set "$listname" src -j DROP || true
iptables -D INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] " || true
$IPSET_BIN destroy -q "$listname" || true
done
for f in $savefiles6; do
listname=$(basename -s ".save" "$f")
ip6tables -D INPUT -m set --match-set "$listname" src -j DROP || true
ip6tables -D INPUT -m set --match-set "$listname" src -j LOG --log-prefix "[UFW BLOCK $listname] " || true
$IPSET_BIN destroy -q "$listname" || true
done
;;
status)
echo "= after.init ="
$IPSET_BIN -t list
echo ""
;;
*)
echo "'$1' not supported"
echo "Usage: after.init {start|stop|status}"
;;
esac

249
UFW-Blocklist/f3_menu.sh Normal file
View File

@ -0,0 +1,249 @@
#! /bin/bash
function bdsatib() {
{
ufw-blocklist -l "bdsatib https://www.binarydefense.com/banlist.txt"
if ! crontab -l | grep -q "bdsatib"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "bdsatib https://www.binarydefense.com/banlist.txt"" | crontab -u root -
fi
}
}
function f2ball() {
{
ufw-blocklist -l "f2ball https://lists.blocklist.de/lists/all.txt"
if ! crontab -l | grep -q "f2ball"; then
echo -e "$(crontab -u root -l)\n*/35 * * * * /usr/local/bin/ufw-blocklists.sh -l "f2ball https://lists.blocklist.de/lists/all.txt"" | crontab -u root -
fi
}
}
function bfblocker() {
{
ufw-blocklist -l "bfblocker https://danger.rulez.sk/projects/bruteforceblocker/blist.php"
if ! crontab -l | grep -q "bfblocker"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "bfblocker https://danger.rulez.sk/projects/bruteforceblocker/blist.php"" | crontab -u root -
fi
}
}
function cinsarmy() {
{
ufw-blocklist -l "cinsarmy http://cinsscore.com/list/ci-badguys.txt"
if ! crontab -l | grep -q "cinsarmy"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "cinsarmy http://cinsscore.com/list/ci-badguys.txt"" | crontab -u root -
fi
}
}
function drop() {
{
if grep -q -E "IPV6=(yes|YES)" /etc/default/ufw; then
ufw-blocklist -l "drop https://www.spamhaus.org/drop/drop.txt" -l "dropv6 https://www.spamhaus.org/drop/dropv6.txt"
if ! crontab -l | grep -q "dropv6"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "drop https://www.spamhaus.org/drop/drop.txt" -l "dropv6 https://www.spamhaus.org/drop/dropv6.txt"" | crontab -u root -
fi
else
ufw-blocklist -l "drop https://www.spamhaus.org/drop/drop.txt"
if ! crontab -l | grep -q "drop"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "drop https://www.spamhaus.org/drop/drop.txt"" | crontab -u root -
fi
fi
}
}
function edrop() {
{
ufw-blocklist -l "edrop https://www.spamhaus.org/drop/edrop.txt"
if ! crontab -l | grep -q "edrop"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "edrop https://www.spamhaus.org/drop/edrop.txt"" | crontab -u root -
fi
}
}
function feodoc2() {
{
ufw-blocklist -l "feodoc2 https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt"
if ! crontab -l | grep -q "feodoc2"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "feodoc2 https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt"" | crontab -u root -
fi
}
}
function feodoioc() {
{
ufw-blocklist -l "feodoioc https://feodotracker.abuse.ch/downloads/ipblocklist.txt"
if ! crontab -l | grep -q "fedoioc"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "feodoioc https://feodotracker.abuse.ch/downloads/ipblocklist.txt"" | crontab -u root -
fi
}
}
function firehol() {
{
ufw-blocklist -l "firehol https://iplists.firehol.org/files/firehol_level1.netset"
if ! crontab -l | grep -q "firehol"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "firehol https://iplists.firehol.org/files/firehol_level1.netset"" | crontab -u root -
fi
}
}
function greensnow() {
{
ufw-blocklist -l "greensnow https://blocklist.greensnow.co/greensnow.txt"
if ! crontab -l | grep -q "bdsatib"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "greensnow https://blocklist.greensnow.co/greensnow.txt"" | crontab -u root -
fi
}
}
function ipsum() {
{
ufw-blocklist -l "ipsum https://raw.githubusercontent.com/stamparm/ipsum/master/levels/2.txt"
if ! crontab -l | grep -q "ipsum"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "ipsum https://raw.githubusercontent.com/stamparm/ipsum/master/levels/2.txt"" | crontab -u root -
fi
}
}
function maxmind(){
{
ufw-blocklist -l "maxmind https://www.maxmind.com/en/anonymous_proxies"
if ! crontab -l | grep -q "maxmind"; then
echo -e "$(crontab -u root -l)\n@daily /usr/local/bin/ufw-blocklists.sh -l "maxmind https://www.maxmind.com/en/anonymous_proxies"" | crontab -u root -
fi
}
}
function blocklist_menu() {
{
clear
echo "Please select which blocklist from the list below"
printf "\n"
echo "1 - Binary Defense Systems Artillery Threat Intelligence Banlist"
echo "2 - Blocklist.de Fail2Ban Reporting (all)"
echo "3 - BruteForceBlocker"
echo "4 - CINS Army List"
echo "5 - FEODO Tracker: Botnet C2 - (Recommended)"
echo "6 - FEODO Tracker: Botnet C2 IoC - (Recommended)"
echo "7 - FireHOL IP List Level 1"
echo "8 - MaxMind"
echo "9 - GreenSnow"
echo "10 - IPsum - (Recommended)"
echo "11 - Spamhaus Don't Route Or Peer List (DROP)"
echo "12 - Spamhaus Extended DROP List (EDROP):"
echo "B - Go Back"
echo "X - Exit"
read -rn 1 user_input
if [[ "$user_input" == '1' ]]; then
bdsatib
blocklist_menu
elif [[ "$user_input" == '2' ]]; then
f2ball
blocklist_menu
elif [[ "$user_input" == '3' ]]; then
bfblocker
blocklist_menu
elif [[ "$user_input" == '4' ]]; then
cins
blocklist_menu
elif [[ "$user_input" == '5' ]]; then
feodoc2
blocklist_menu
elif [[ "$user_input" == '6' ]]; then
feodoioc
blocklist_menu
elif [[ "$user_input" == '7' ]]; then
firehol
blocklist_menu
elif [[ "$user_input" == '8' ]]; then
maxmind
blocklist_menu
elif [[ "$user_input" == '9' ]]; then
greensnow
blocklist_menu
elif [[ "$user_input" == '10' ]]; then
ipsum
blocklist_menu
elif [[ "$user_input" == '11' ]]; then
drop
blocklist_menu
elif [[ "$user_input" == '12' ]]; then
edrop
blocklist_menu
elif [[ "$user_input" == xX ]]; then
exit 0
elif [[ "$user_input" == bB ]]; then
Main_Menu
fi
}
}
function ipv6_install() {
{
# Check that ufw has IPv6 enabled
if ! grep -q -E "IPV6=(yes|YES)" /etc/default/ufw; then
echo "ERROR: IPv6 rules requested but UFW is not configured to use IPv6. Set IPV6=yes in /etc/default/ufw and rerun this script."
Main_Menu
fi
wget https://files.mylinux.work/s/aRXEsCe5G8b43QB/download/after6.init
chmod 750 after6.init
mv /tmp/after6.init /etc/ufw/after6.init
blocklist_menu
}
}
function ipv6_menu() {
{
clear
echo "Would you like to enable IPv6 support? [Y/n]"
printf "\n"
echo "Y - Yes"
echo "N - No"
read -rn 1 user_input
if [[ "$user_input" == [yY] ]]; then
ipv6_install
elif [[ "$user_input" == [nN] ]]; then
blocklist_menu
fi
}
}
function ipv4_install() {
{
if [ ! "$(command -v ipset)" ]; then
apt -y install ipset
fi
cd /tmp || exit 2
wget https://files.mylinux.work/s/cqKc2CkzmHMpBXW/download/after.init
chmod 750 after.init
mv /tmp/after.init /etc/ufw/after.init
wget https://files.mylinux.work/s/KfDSRWCcrxiTftf/download/ufw-blocklists.sh
chmod 755 ufw-blocklists.sh
mv /tmp/ufw-blocklists.sh /usr/local/bin/
ipv6_menu
}
}
function Main_Menu() {
{
clear
echo "Configure UFW to block IPs listed in blocklist ipsets? [Y/n]"
printf "\n"
echo "Y - Yes"
echo "N - No"
read -rn 1 user_input
if [[ "$user_input" == [yY] ]]; then
ipv4_install
elif [[ "$user_input" == [nN] ]]; then
exit 0
fi
}
}
Main_Menu

349
UFW-Blocklist/f4_menu.sh Normal file
View File

@ -0,0 +1,349 @@
#!/bin/bash
E='echo -e'
e='echo -en'
trap "R; exit" 2
ESC=$( $e "\e")
TPUT() {
$e "\e[${1};${2}H"
}
CLEAR() {
$e "\ec"
}
CIVIS() {
$e "\e[?25l"
}
MARK() {
$e "\e[7m"
}
UNMARK() {
$e "\e[27m"
}
R() {
CLEAR
stty
sane
CLEAR
}
HEAD() {
for each in $(seq 1 30)
do
$E " \xE2\x94\x82 \xE2\x94\x82"
done
MARK
TPUT 1 10
$E " UFW BlockList Install "
UNMARK
TPUT 2 10
$E " Select a Bloclist from the List "
UNMARK
}
i=0
CLEAR
CIVIS
NULL=/dev/null
FOOT() {
MARK
TPUT 15 5
$E " UP \xE2\x86\x91 \xE2\x86\x93 DOWN ENTER - SELECT,NEXT "
UNMARK
}
ARROW() {
IFS= read -sr -n1 key 2>/dev/null >&2
if [[ $key = "$ESC" ]]; then
read -sr -n1 key 2>/dev/null >&2
if [[ $key = \[ ]]; then
read -sr -n1 key 2>/dev/null >&2
if [[ $key = A ]]; then
echo up
fi
if [[ $key = B ]]; then
echo dn
fi
fi
fi
if [[ "$key" == "$($e \\x0A)" ]]; then
echo enter
fi
}
M0() {
TPUT 4 20
$e "Binary Defense Systems Artillery Threat Intelligence Banlist"
}
M1() {
TPUT 5 20
$e "Blocklist.de Fail2Ban Reporting (all)"
}
M2() {
TPUT 6 20
$e "BruteForceBlocker"
}
M3() {
TPUT 7 20
$e "CINS Army List"
}
M4() {
TPUT 8 20
$e "FEODO Tracker: Botnet C2"
}
M5() {
TPUT 9 20
$e "FEODO Tracker: Botnet C2 IoC"
}
M6() {
TPUT 10 20
$e "FireHOL IP List Level 1"
}
M7() {
TPUT 11 20
$e "GreenSnow"
}
M8() {
TPUT 12 20
$e "IPsum - (Recommended)"
}
M9() {
TPUT 12 20
$e "Spamhaus Don't Route Or Peer List (DROP)"
}
M10() {
TPUT 13 20
$e "Spamhaus Extended DROP List (EDROP)"
}
M11() {
TPUT 14 20
$e "MaxMind"
}
M12() {
TPUT 15 20
$e "Main Menu"
}
M13() {
TPUT 16 20
$e "EXIT "
}
LM=8
MENU() {
for each in $(seq 0 $LM)
do
M"${each}"
done
}
POS() {
if [[ $cur == up ]]; then
((i--))
fi
if [[ $cur == dn ]]; then
((i++))
fi
if [[ $i -lt 0 ]]; then
i=$LM
fi
if [[ $i -gt $LM ]]; then
i=0
fi
}
REFRESH() {
after=$((i+1))
before=$((i-1))
if [[ $before -lt 0 ]]; then
before=$LM
fi
if [[ $after -gt $LM ]]; then
after=0
fi
if [[ $j -lt $i ]]; then
UNMARK
M$before
else
UNMARK
M$after
fi
if [[ $after -eq 0 ]] || [ $before -eq $LM ]; then
UNMARK
M$before
M$after
fi
j=$i
UNMARK
M$before
M$after
}
INIT() {
R
HEAD
FOOT
MENU
}
SC() {
REFRESH
MARK
$S
$b
cur=$(ARROW)
}
ES() {
MARK
$e "ENTER = Main Menu "
$b
read -r
INIT
}
INIT
while [[ "$O" != " " ]];
do
case $i in
0) S=M0
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e Binary Defense Systems Artillery Threat Intelligence Banlist)\n"
ES
fi
;;
1) S=M1
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e Blocklist.de Fail2Ban Reporting - all)\n"
ES
fi
;;
2) S=M2
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e BruteForceBlocker)\n"
ES
fi
;;
3) S=M3
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e CINS Army List)\n"
ES
fi
;;
4) S=M4
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e FEODO Tracker: Botnet C2)\n"
ES
fi
;;
5) S=M5
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e FEODO Tracker: Botnet C2 IoC)\n"
ES
fi
;;
6) S=M6
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e FireHOL IP List Level 1)\n"
ES
fi
;;
7) S=M7
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e GreenSnow)\n"
ES
fi
;;
8) S=M8
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e IPsum - \(Recommended\))\n"
ES
fi
;;
9) S=M9
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e Spamhaus Don\'t Route Or Peer List \(DROP))\n"
ES
fi
;;
10) S=M10
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e Spamhaus Extended DROP List \(EDROP))\n"
ES
fi
;;
11) S=M11
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e MaxMind)\n"
ES
fi
;;
12) S=M12
SC
if [[ $cur == enter ]]; then
R
$e "\n$($e Main Menu)\n"
ES
fi
;;
13) S=M13
SC
if [[ $cur == enter ]]; then
R
exit 0
fi
;;
esac
POS
done

223
UFW-Blocklist/f5_menu.sh Normal file
View File

@ -0,0 +1,223 @@
#!/bin/bash
# Wrapper for desktopify Misko_2083
# Menu code adapted from https://askubuntu.com/questions/1705/how-can-i-create-a-select-menu-in-a-shell-script
# Run from the same dir as desktopify
E='echo -e';e='echo -en';trap "R;exit" 2
ESC=$( $e "\e")
TPUT(){ $e "\e[${1};${2}H" ;}
CLEAR(){ $e "\ec";}
CIVIS(){ $e "\e[?25l";}
MARK(){ $e "\e[7m";}
UNMARK(){ $e "\e[27m";}
cursor_blink_on() { printf "$ESC[?25h"; }
cursor_blink_off() { printf "$ESC[?25l"; }
R(){ CLEAR ;stty sane;CLEAR;};
HEAD(){ for each in $(seq 1 15);do
$E " \xE2\x94\x82 \xE2\x94\x82"
done
MARK;TPUT 1 5
$E " DESKTOPIFY " ;UNMARK;
TPUT 2 5
$E " SELECT A DESKTOP ENVIRONMENT " ;}
HEAD_II(){ for each in $(seq 1 15);do
$E " \xE2\x94\x82 \xE2\x94\x82"
done
MARK;TPUT 1 5
$E " DESKTOPIFY " ;UNMARK;
TPUT 2 5
$E " SELECT ADDITIONAL OPTIONS " ;
TPUT 4 10
$E " Desktop Environment $1" ;}
i=0; CLEAR; CIVIS;
FOOT(){ MARK;TPUT 15 5
$E " UP \xE2\x86\x91 \xE2\x86\x93 DOWN \xE2\x94\x82 \xe2\x86\xb5 ENTER - NEXT \xE2\x94\x82 EXIT - X ";UNMARK;}
FOOT_II(){ MARK;TPUT 14 5
$E " \xe2\x86\x90 BACK \xE2\x94\x82 SPACE - SELECT \xE2\x94\x82 ";
TPUT 15 5
$E " UP \xE2\x86\x91 \xE2\x86\x93 DOWN \xE2\x94\x82 \xe2\x86\xb5 ENTER - NEXT \xE2\x94\x82 EXIT - X ";UNMARK;}
ARROW(){ IFS= read -s -n1 key 2>/dev/null >&2
if [[ $key = $ESC ]];then
read -s -n2 key 2>/dev/null >&2;
if [[ $key = \[A ]]; then echo up;fi
if [[ $key = \[B ]]; then echo dn;fi
fi
if [[ $key = [xX] ]]; then echo exit;fi;
if [[ "$key" = "" ]];then echo enter;fi;}
M0(){ TPUT 4 20; $e "Lubuntu";}
M1(){ TPUT 5 20; $e "Kubuntu";}
M2(){ TPUT 6 20; $e "Ubuntu";}
M3(){ TPUT 7 20; $e "Ubuntu-Budgie";}
M4(){ TPUT 8 20; $e "Ubuntu-Kylin";}
M5(){ TPUT 9 20; $e "Ubuntu-Mate";}
M6(){ TPUT 10 20; $e "Ubuntu-Studio";}
M7(){ TPUT 11 20; $e "Xubuntu";}
M8(){ TPUT 12 20; $e "EXIT ";}
LM=8
MENU(){ for each in $(seq 0 $LM);do M${each};done;}
POS(){ if [[ $cur == up ]];then ((i--));fi
if [[ $cur == dn ]];then ((i++));fi
if [[ $i -lt 0 ]];then i=$LM;fi
if [[ $i -gt $LM ]];then i=0;fi;}
REFRESH(){ after=$((i+1)); before=$((i-1))
if [[ $before -lt 0 ]];then before=$LM;fi
if [[ $after -gt $LM ]];then after=0;fi
if [[ $j -lt $i ]];then UNMARK;M$before;else UNMARK;M$after;fi
if [[ $after -eq 0 ]] || [ $before -eq $LM ];then
UNMARK; M$before; M$after;fi;j=$i;UNMARK;M$before;M$after;}
INIT(){ R;HEAD;FOOT;MENU;}
SC(){ REFRESH;MARK;$S;$b;cur=`ARROW`;}
ES(){ INIT;};INIT
MSEL() { cursor_blink_on() { printf "$ESC[?25h"; }
cursor_blink_off() { printf "$ESC[?25l"; }
cursor_to() { printf "$ESC[$1;${2:-1}H"; }
print_inactive() { printf "$2 $1 "; }
print_active() { printf "$2 $ESC[7m$1 $ESC[27m"; }
get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; }
key_input() {
local key
IFS= read -rsn1 key 2>/dev/null >&2
if [[ $key = "" ]]; then echo enter; fi;
if [[ $key = [xX] ]]; then echo exit; fi;
if [[ $key = $'\x20' ]]; then echo space; fi;
if [[ $key = $'\x1b' ]]; then
read -rsn2 key
if [[ $key = [A ]]; then echo up; fi;
if [[ $key = [B ]]; then echo down; fi;
if [[ $key = [D ]]; then echo back; fi;
fi;}
toggle_option() {
local arr_name=$1
eval "local arr=(\"\${${arr_name}[@]}\")"
local option=$2
if [[ ${arr[option]} == true ]]; then
arr[option]=
else
arr[option]=true
fi
eval $arr_name='("${arr[@]}")';}
local retval=$1
local options
local defaults
IFS=';' read -r -a options <<< "$2"
if [[ -z $3 ]]; then
defaults=()
else
IFS=';' read -r -a defaults <<< "$3"
fi
local selected=()
for ((i=0; i<${#options[@]}; i++)); do
selected+=("${defaults[i]}")
printf "\n"
done
# determine current screen position for overwriting the options
local lastrow=`get_cursor_row`
local startrow=$(($lastrow - ${#options[@]}))
# ensure cursor and input echoing back on upon a ctrl+c during read -s
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
cursor_blink_off
local active=0
while true; do
# print options by overwriting the last lines
local idx=0
for option in "${options[@]}"; do
local prefix="[ ]"
if [[ ${selected[idx]} == true ]]; then
prefix="[x]"
fi
cursor_to $(($startrow + $idx))
if [ $idx -eq $active ]; then
if [ $option == OEM ]; then
TPUT $((idx+6)) 6
print_active "$option" "$prefix"
TPUT $((idx+7)) 11
$e "Run a setup wizard on the next boot"
elif [ $option == FORCE ]; then
TPUT $((idx+8)) 6
print_active "$option" "$prefix"
TPUT $((idx+9)) 11
$e "Force desktop package install"
fi
else
if [ $option == OEM ]; then
TPUT $((idx+6)) 6
print_inactive "$option" "$prefix"
TPUT $((idx+7)) 11
$e "Run a setup wizard on the next boot"
elif [ $option == FORCE ]; then
TPUT $((idx+8)) 6
print_inactive "$option" "$prefix"
TPUT $((idx+9)) 11
$e "Force desktop package install"
fi
fi
((idx++))
done
# user key control
case `key_input` in
space) toggle_option selected $active;;
enter) break;;
up) ((active--));
if [ $active -lt 0 ]; then active=$((${#options[@]} - 1)); fi;;
down) ((active++));
if [ $active -ge ${#options[@]} ]; then active=0; fi;;
back) CLEAR; exec $0;;
exit) CLEAR;exit 0;;
esac
done
# cursor position back to normal
cursor_to $lastrow
printf "\n"
cursor_blink_on
eval $retval='("${selected[@]}")'
}
RUN(){
if [[ $cur != back ]];then
R;HEAD_II "$1"
FOOT_II;
MSEL result "OEM;FORCE" "false;;false"
CLEAR
ARG=
if [[ ${result[0]} == true ]]; then
ARG="--oem"
fi
if [[ ${result[1]} == true ]]; then
ARG="$ARG --force"
fi
$E "sudo ./desktopify $ARG --de $1"
sudo ./desktopify $ARG --de $1
break
fi
}
# ensure cursor and input echoing back on upon a ctrl+c during read -s
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
cursor_blink_off
while [[ "$O" != " " ]] && [[ $cur != exit ]]; do case $i in
0) S=M0;SC;if [[ $cur == enter ]];then RUN lubuntu; fi;;
1) S=M1;SC;if [[ $cur == enter ]];then RUN kubuntu; fi;;
2) S=M2;SC;if [[ $cur == enter ]];then RUN ubuntu; fi;;
3) S=M3;SC;if [[ $cur == enter ]];then RUN ubuntu-budgie; fi;;
4) S=M4;SC;if [[ $cur == enter ]];then RUN ubuntu-kylin; fi;;
5) S=M5;SC;if [[ $cur == enter ]];then RUN ubuntu-mate; fi;;
6) S=M6;SC;if [[ $cur == enter ]];then RUN ubuntu-studio; fi;;
7) S=M7;SC;if [[ $cur == enter ]];then RUN xubuntu; fi;;
8) S=M8;SC;if [[ $cur == enter ]];then R;exit 0;fi;;
esac;POS;done
CLEAR
cursor_blink_on

View File

@ -0,0 +1,172 @@
#!/bin/bash
#
# after.init: if executable, called by ufw-init. See 'man ufw-framework' for
# details. Note that output from these scripts is not seen via the
# the ufw command, but instead via ufw-init.
#
###############################################################################
#### ####
#### Based on ufw-blocklist edition: IP blocklist extension for Ubuntu ufw ####
#### https://github.com/poddmo/ufw-blocklist ####
#### ####
#### Modified https://mylinux.work ####
#### Version 1.0.2.061324 ####
#### Contact: contact@mylinux.work ####
#### ####
###############################################################################
set -e
export ipsetname=ufw-blocklist-ipsum
# seed file containing the list of IP addresses to be blocked, one per line
export seedlist=/etc/ipsum.ipv4.txt
export IPSET_EXE="/sbin/ipset"
# check ipset exists and is executable
[ -x "$IPSET_EXE" ] || {
echo "$IPSET_EXE is not executable"
exit 1
}
# Function to check if a chain exists
chain_exists() {
{
[ $# -lt 1 ] || [ $# -gt 2 ] && {
echo "Usage: chain_exists <chain_name> [table]" >&2
return 1
}
local chain_name="$1" ; shift
[ $# -eq 1 ] && local table="--table $1"
iptables "$table" -n --list "$chain_name" >/dev/null 2>&1
}
}
# Function to check if an set exists (set_exists setname && action if true || action if false)
set_exists() {
{
[ $# -ne 1 ] && {
echo "Usage: set_exists <set_name>" >&2
return 1
}
local set_name="$1"
ipset list "$set_name" -name >/dev/null 2>&1
}
}
case "$1" in
start)
# check that blocklist seed file exists
if [ ! -f "$seedlist" ]; then
echo "ufw after.init: $seedlist does not exist."
exit 1
fi
# create an empty ipset
$IPSET_EXE create $ipsetname hash:net -exist
$IPSET_EXE flush $ipsetname
## Insert firewall rules to take precedence, removing them and adding them back if they already existed
# Block inbound to localhost from blocklist
if chain_exists ufw-blocklist-input; then
iptables -D INPUT -m set --match-set $ipsetname src -j ufw-blocklist-input || true
iptables -F ufw-blocklist-input
iptables -X ufw-blocklist-input
fi
iptables -N ufw-blocklist-input
iptables -A ufw-blocklist-input -j DROP -m comment --comment "ufw-blocklist-input"
iptables -I INPUT -m set --match-set $ipsetname src -j ufw-blocklist-input
# Log and drop outbound to blocklist. Hits here may indicate compromised localhost
if chain_exists ufw-blocklist-output; then
iptables -D OUTPUT -m set --match-set $ipsetname dst -j ufw-blocklist-output || true
iptables -F ufw-blocklist-output
iptables -X ufw-blocklist-output
fi
iptables -N ufw-blocklist-output
iptables -A ufw-blocklist-output -j LOG --log-level 3 --log-prefix "[UFW BLOCKLIST OUTPUT] " -m limit --limit 3/minute --limit-burst 10
iptables -A ufw-blocklist-output -j DROP -m comment --comment "ufw-blocklist-output"
iptables -I OUTPUT -m set --match-set $ipsetname dst -j ufw-blocklist-output
# Log and drop forwarding to blocklist. Hits here may indicate compromised internal hosts
if chain_exists ufw-blocklist-forward; then
iptables -D FORWARD -m set --match-set $ipsetname dst -j ufw-blocklist-forward || true
iptables -F ufw-blocklist-forward
iptables -X ufw-blocklist-forward
fi
iptables -N ufw-blocklist-forward
iptables -A ufw-blocklist-forward -j LOG --log-level 3 --log-prefix "[UFW BLOCKLIST FORWARD] " -m limit --limit 3/minute --limit-burst 10
iptables -A ufw-blocklist-forward -j DROP -m comment --comment "ufw-blocklist-forward"
iptables -I FORWARD -m set --match-set $ipsetname dst -j ufw-blocklist-forward
# add members to the ipset
# start this in a subshell and then disown the job so we return quickly.
(
while read -r ip < "$seedlist"
do
$IPSET_EXE add "$ipsetname" "$ip"
done
) < /dev/null &> /dev/null & disown -h
;;
stop)
# delete resources created above
if chain_exists ufw-blocklist-input; then
iptables -D INPUT -m set --match-set $ipsetname src -j ufw-blocklist-input || true
iptables -F ufw-blocklist-input
iptables -X ufw-blocklist-input
fi
if chain_exists ufw-blocklist-output; then
iptables -D OUTPUT -m set --match-set $ipsetname dst -j ufw-blocklist-output || true
iptables -F ufw-blocklist-output
iptables -X ufw-blocklist-output
fi
if chain_exists ufw-blocklist-forward; then
iptables -D FORWARD -m set --match-set $ipsetname dst -j ufw-blocklist-forward || true
iptables -F ufw-blocklist-forward
iptables -X ufw-blocklist-forward
fi
if set_exists $ipsetname; then
$IPSET_EXE flush $ipsetname
$IPSET_EXE destroy $ipsetname
fi
;;
status)
# display details of the ipset
$IPSET_EXE list "$ipsetname" -t
# show iptables hit/byte counts
iptables -L -nvx | grep "$ipsetname" | grep 'match-set'
# show the last 10 lines from the logs
journalctl | grep -i blocklist | tail
;;
flush-all)
# flush sets created above. Use /etc/cron.daily/ufw-blocklist-ipsum to repopulate
$IPSET_EXE flush $ipsetname
# reset iptables accounting
ipz=$( iptables -L INPUT -nvx --line-numbers | grep ufw-blocklist-input | awk '{print $1}')
iptables -Z INPUT "$ipz"
iptables -Z ufw-blocklist-input
ipz=$( iptables -L OUTPUT -nvx --line-numbers | grep ufw-blocklist-output | awk '{print $1}')
iptables -Z OUTPUT "$ipz"
iptables -Z ufw-blocklist-output
ipz=$( iptables -L FORWARD -nvx --line-numbers | grep ufw-blocklist-forward | awk '{print $1}')
iptables -Z FORWARD "$ipz"
iptables -Z ufw-blocklist-forward
;;
*)
echo "'$1' not supported"
echo "Usage: /etc/ufw/after.init {start|stop|flush-all|status}"
;;
esac

View File

@ -0,0 +1,90 @@
#!/usr/bin/env bash
# ##################################################
# ufw-ipset-blocklist-autoupdate
#
# Blocking lists of IPs from public blacklists / blocklists (e.g. blocklist.de, spamhaus.org)
#
# Version: 1.1.1
#
# See: https://github.com/ngandrass/ufw-ipset-blacklist-autoupdate
# ##################################################
UFW_CONF_DIR=/etc/ufw
UFW_AFTER_INIT_FILE=$UFW_CONF_DIR/after.init
IPSET_DIR="/var/lib/ipset" # Folder to write ipset save files to
CONFIGURE_IPV6=0
# Let user abort
read -r -p "Configure UFW to block IPs listed in blocklist ipsets? [Y/n] " ret
case "$ret" in
[nN][oO]|[nN]) exit
;;
*)
;;
esac
read -r -p "Would you like to enable IPv6 support? [Y/n] " ret
case "$ret" in
[nN][oO]|[nN]) CONFIGURE_IPV6=0
;;
*)
CONFIGURE_IPV6=1
;;
esac
#get required files
cd /tmp || exit 2
wget autoupdate-blocklist.sh
mv /tmp/autoupdate-blocklist.sh /usr/local/bin/
chmod 755 /usr/local/bin/autoupdate-blocklist.sh
wget https://files.mylinux.work/ /download/after.init.ipv4
wget https://after.init.ipv6/ /download/after.init.ipv6
# Ensure that IPSET_DIR exists
if [ ! -d "$IPSET_DIR" ]; then
mkdir -p "$IPSET_DIR" || exit
fi
# Check that ufw has IPv6 enabled
if [[ "$CONFIGURE_IPV6" == 1 ]]; then
if ! grep -q -E "IPV6=(yes|YES)" /etc/default/ufw; then
echo "ERROR: IPv6 rules requested but UFW is not configured to use IPv6. Set IPV6=yes in /etc/default/ufw and rerun this script."
exit 1
fi
fi
# Check if file already exists.
if [ -f "$UFW_AFTER_INIT_FILE" ]; then
read -r -p "The file $UFW_UFW_AFTER_INIT_FILE already exists. Are you sure that you want to overwrite it? [y/N] " ret
case "$ret" in
[yY][eE][sS]|[yY])
# continue
;;
*)
exit
;;
esac
fi
# Deploy after.init
if [[ "$CONFIGURE_IPV6" == 1 ]]; then
mv /tmp/after.init.ipv6 /tmp/after6.init
mv "/tmp/after6.init" "$UFW_AFTER_INIT_FILE" || exit
else
mv /tmp/after.init.ipv6 /tmp/after.init
mv "/tmp/after.init" "$UFW_AFTER_INIT_FILE" || exit
fi
chmod 755 "$UFW_AFTER_INIT_FILE"
echo "Deployed $UFW_UFW_AFTER_INIT_FILE"
# Restart ufw
read -r -p "Reload ufw to apply changes? [Y/n] " ret
case "$ret" in
[nN][oO]|[nN]) exit
;;
*)
ufw reload
;;
esac

View File

@ -0,0 +1,284 @@
#!/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_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
##
# 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
#
# Arguments:
# $1 Message to write to stdout
##
function log() {
{
if [[ $QUIET -eq 0 ]]; then
echo "$1"
fi
}
}
##
# Writes argument $1 to stdout if $VERBOSE is set and $QUIET is not set
#
# Arguments:
# $1 Message to write to stdout
##
function log_verbose() {
{
if [[ $VERBOSE -eq 1 ]]; then
if [[ $QUIET -eq 0 ]]; then
echo "$1"
fi
fi
}
}
##
# Writes argument $1 to stderr. Ignores $QUIET.
#
# Arguments:
# $1 Message to write to stderr
##
function log_error() {
{
>&2 echo "[ERROR]: $1"
}
}
##
# 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() {
{
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
#
# 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() {
{
# Setup local vars
local setname=$1
local ipfile=$2
local family=$3
# Create temporary ipset to build and ensure existence of live ipset
local livelist="$setname-$family"
local 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
#
# Arguments:
# $1 Name of the blocklist
# $2 URL of the blocklist
#
function update_blocklist() {
{
# Download blocklist
log "Updating blacklist '$1' ..."
log_verbose "Downloading blocklist '$1' from: $2 ..."
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
elif [[ $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 program loop
##
function main() {
{
# Check arguments
validate_blocklists
# Setup ipset
IPSET_BIN=$(detect_ipset)
mkdir -p "${IPSET_DIR}"
# 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
# Entry point
main

46
UFW-Blocklist/ufw-test.sh Normal file
View File

@ -0,0 +1,46 @@
#!/bin/bash
TMP_DIR="/tmp"
URL_LINKS=$"http://www.blocklist.de/lists/ssh.txt
http://www.blocklist.de/lists/apache.txt
http://www.blocklist.de/lists/asterisk.txt
http://www.blocklist.de/lists/bots.txt
http://www.blocklist.de/lists/courierimap.txt
http://www.blocklist.de/lists/courierpop3.txt
http://www.blocklist.de/lists/email.txt
http://www.blocklist.de/lists/ftp.txt
http://www.blocklist.de/lists/imap.txt
http://www.blocklist.de/lists/ircbot.txt
http://www.blocklist.de/lists/pop3.txt
http://www.blocklist.de/lists/postfix.txt
http://www.blocklist.de/lists/proftpd.txt
http://www.blocklist.de/lists/sip.txt
http://www.ciarmy.com/list/ci-badguys.txt
http://charles.the-haleys.org/ssh_dico_attack_hdeny_format.php/hostsdeny.txt
http://www.nothink.org/blacklist/blacklist_ssh_day.txt
http://malc0de.com/bl/IP_Blacklist.txt
http://www.nothink.org/blacklist/blacklist_malware_dns.txt
http://www.nothink.org/blacklist/blacklist_malware_http.txt
http://www.nothink.org/blacklist/blacklist_malware_irc.txt"
function denyHost() {
sudo ufw deny from $1;
}
function getLists() {
if [[ ! -d "${BACKUP_DIR}" ]]; then
mkdir -p "${BACKUP_DIR}";
fi;
for line in echo ${URL_LINKS}; do
filename=$(python -c 'import string; import random; acc=string.ascii_letters; d=["".join([random.choice(acc) for _ in range(1)]) for _ in range(7)]; print("".join(d))')
writeTo="${TMP_DIR}/${filename}.deny";
touch $writeTo;
curl -o "${writeTo}" $line;
while read item; do
denyHost $item;
done < "${writeTo}";
done;
}
getLists;

35
auth-log-lookup.sh Normal file
View File

@ -0,0 +1,35 @@
#!/bin/bash
# Install geoiplookup if needed
if [ ! "$(command -v geoiplookup)" ]; then
apt -y install geoip-bin
fi
# Colors for Location/Address
BB="\033[1;34m" # Blue bold
BW="\033[1;37m" # Bold White
BY="\033[1;33m" # Bold Yellow
GR="\033[0;32m" # Green
LY="\033[3;33m" # Light Yellow
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
while true
do
for i in $(cat $LOGFILE | awk "NR>$LINE" | grep Invalid | awk '{print $(NF-2)}' | uniq)
do
LINE=$(cat $LOGFILE | wc -l)
# Detect if IPv4 address for lookups
if [ "$i" != "${i#*[0-9].[0-9]}" ]; then
LOCATION=$(geoiplookup "$i" | awk '{print $5 " " $6}')
else
LOCATION=$(geoiplookup6 "$i" | awk '{print $6 " " $7}')
fi
echo -e "[*] The Attacker's Country: ${RB}$LOCATION ${NC}[IP ADDRESS:${RB} $i] ${NC}"
done
sleep 2
done

View File

@ -0,0 +1,27 @@
IPSET_BLACKLIST_NAME=blacklist # change it if it collides with a pre-existing ipset list
IPSET_TMP_BLACKLIST_NAME=${IPSET_BLACKLIST_NAME}-tmp
# ensure the directory for IP_BLACKLIST/IP_BLACKLIST_RESTORE exists (it won't be created automatically)
IP_BLACKLIST_RESTORE=/etc/ipset-blacklist/ip-blacklist.restore
IP_BLACKLIST=/etc/ipset-blacklist/ip-blacklist.list
VERBOSE=yes # probably set to "no" for cron jobs, default to yes
FORCE=yes # will create the ipset-iptable binding if it does not already exist
let IPTABLES_IPSET_RULE_NUMBER=1 # if FORCE is yes, the number at which place insert the ipset-match rule (default to 1)
# Sample (!) list of URLs for IP blacklists. Currently, only IPv4 is supported in this script, everything else will be filtered.
BLACKLISTS=(
# "file:///etc/ipset-blacklist/ip-blacklist-custom.list" # optional, for your personal nemeses (no typo, plural)
"https://www.projecthoneypot.org/list_of_ips.php?t=d&rss=1" # Project Honey Pot Directory of Dictionary Attacker IPs
"https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.1.1.1" # TOR Exit Nodes
"http://danger.rulez.sk/projects/bruteforceblocker/blist.php" # BruteForceBlocker IP List
"https://www.spamhaus.org/drop/drop.lasso" # Spamhaus Don't Route Or Peer List (DROP)
"https://cinsscore.com/list/ci-badguys.txt" # C.I. Army Malicious IP List
"https://lists.blocklist.de/lists/all.txt" # blocklist.de attackers
"https://blocklist.greensnow.co/greensnow.txt" # GreenSnow
"https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset" # Firehol Level 1
"https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/stopforumspam_7d.ipset" # Stopforumspam via Firehol
# "https://raw.githubusercontent.com/ipverse/rir-ip/master/country/zz/ipv4-aggregated.txt" # Ban an entire country(-code), see https://github.com/ipverse/rir-ip
# "https://raw.githubusercontent.com/ipverse/asn-ip/master/as/1234/ipv4-aggregated.txt" # Ban a specific autonomous system (ISP), see https://github.com/ipverse/asn-ip
)
MAXELEM=131072

View File

@ -0,0 +1,83 @@
#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
set -x
# Everything below will go to the file 'log.out':
source pid.sh
IP_TMP=/tmp/ip.tmp
IP_BLOCKLIST=/etc/ip-blocklist.conf
IP_BLOCKLIST_TMP=/tmp/ip-blocklist.tmp
IP_BLOCKLIST_CUSTOM=/etc/ip-blocklist-custom.conf # optional
BLACKLISTS=(
"http://www.projecthoneypot.org/list_of_ips.php?t=d&rss=1" # Project Honey Pot Directory of Dictionary Attacker IPs
"http://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.1.1.1" # TOR Exit Nodes
"http://www.maxmind.com/en/anonymous_proxies" # MaxMind GeoIP Anonymous Proxies
"https://www.maxmind.com/en/high-risk-ip-sample-list" # MaxMind High Risk Sample List
"http://danger.rulez.sk/projects/bruteforceblocker/blist.php" # BruteForceBlocker IP List
"https://rules.emergingthreats.net/blockrules/compromised-ips.txt" # Emerging Threats - Russian Business Networks List
"http://www.spamhaus.org/drop/drop.lasso" # Spamhaus Don't Route Or Peer List (DROP)
"http://cinsscore.com/list/ci-badguys.txt" # C.I. Army Malicious IP List
"http://www.autoshun.org/files/shunlist.csv" # Autoshun Shun List
"http://lists.blocklist.de/lists/all.txt" # blocklist.de fail2ban reporting service
"https://fx.vc-mp.eu/shared/iplist.txt" # ferex badlist
"https://feodotracker.abuse.ch/downloads/ipblocklist_aggressive.txt" # FEODO tracker
"https://reputation.alienvault.com/reputation.generic" # ALIENVAULT REPUTATION
"http://www.darklist.de/raw.php" # DARKLIST DE
"http://osint.bambenekconsulting.com/feeds/c2-dommasterlist-high.txt"
"http://osint.bambenekconsulting.com/feeds/c2-dommasterlist.txt"
"http://osint.bambenekconsulting.com/feeds/c2-ipmasterlist-high.txt"
"http://osint.bambenekconsulting.com/feeds/c2-ipmasterlist.txt"
"http://osint.bambenekconsulting.com/feeds/c2-masterlist.txt"
"http://osint.bambenekconsulting.com/feeds/dga-feed.txt"
"https://www.binarydefense.com/banlist.txt" # Binary Defense Systems
"https://raw.githubusercontent.com/stamparm/ipsum/master/ipsum.txt" # https://github.com/stamparm/ipsum
"http://sblam.com/blacklist.txt" # SBLAM
"http://blocklist.greensnow.co/greensnow.txt"
"http://charles.the-haleys.org/ssh_dico_attack_hdeny_format.php/hostsdeny.txt"
"https://www.malwaredomainlist.com/hostslist/ip.txt"
"https://www.stopforumspam.com/downloads/toxic_ip_cidr.txt"
)
for i in "${BLACKLISTS[@]}"
do
curl "$i" > $IP_TMP
grep -Po '(?:\d{1,3}.){3}\d{1,3}(?:/\d{1,2})?' $IP_TMP >> $IP_BLOCKLIST_TMP
done
#Get the iblocklist
wget -qO- http://list.iblocklist.com/?list=erqajhwrxiuvjxqrrwfj&fileformat=p2p&archiveformat=gz > $_input || { echo "$0: Unable to download ip list."; exit 1; }
#Consolidate iblocklist into master list
cat "$_input" >> $IP_BLOCKLIST_TMP
#Consolidate the shodan.io IP addresses database
cat /opt/blocklist/shodan.txt >> $IP_BLOCKLIST_TMP
#Sort the list
sort $IP_BLOCKLIST_TMP -n | uniq > $IP_BLOCKLIST
#Remove temporary list
rm $IP_BLOCKLIST_TMP
#count how many IP addresses are in the list
wc -l $IP_BLOCKLIST
#Flush the ipset
/usr/sbin/ipset flush blocklist
#Add IP addresses to the ipset
grep -v "^#|^$" $IP_BLOCKLIST | while IFS= read -r ip;
do
/usr/sbin/ipset add blocklist "$ip";
done
### Section for firewalld
firewall-cmd --delete-ipset=blocklist --permanent
firewall-cmd --permanent --new-ipset=blocklist --type=hash:net --option=family=inet --option=hashsize=1048576 --option=maxelem=1048576
firewall-cmd --permanent --ipset=blocklist --add-entries-from-file=/etc/ip-blocklist.conf
firewall-cmd --reload
echo "Firewalld ipset list entries:"
firewall-cmd --permanent --ipset=blocklist --get-entries | wc -l
echo "ipset list entries:"
cat /etc/ip-blocklist.conf | wc -l

View File

@ -0,0 +1,117 @@
#!/usr/bin/env bash
#
# usage update-blacklist.sh <configuration file>
# eg: update-blacklist.sh /etc/ipset-blacklist/ipset-blacklist.conf
#
function exists() { command -v "$1" >/dev/null 2>&1; }
if [[ -z "$1" ]]; then
echo "Error: please specify a configuration file, e.g. $0 /etc/ipset-blacklist/ipset-blacklist.conf"
exit 1
fi
# shellcheck source=ipset-blacklist.conf
if ! source "$1"; then
echo "Error: can't load configuration file $1"
exit 1
fi
if ! exists curl && exists egrep && exists grep && exists ipset && exists iptables && exists sed && exists sort && exists wc; then
echo >&2 "Error: searching PATH fails to find executables among: curl egrep grep ipset iptables sed sort wc"
exit 1
fi
DO_OPTIMIZE_CIDR=no
if exists iprange && [[ ${OPTIMIZE_CIDR:-yes} != no ]]; then
DO_OPTIMIZE_CIDR=yes
fi
if [[ ! -d $(dirname "$IP_BLACKLIST") || ! -d $(dirname "$IP_BLACKLIST_RESTORE") ]]; then
echo >&2 "Error: missing directory(s): $(dirname "$IP_BLACKLIST" "$IP_BLACKLIST_RESTORE" | sort -u)"
exit 1
fi
# create the ipset if needed (or abort if does not exists and FORCE=no)
if ! ipset list -n | command grep -q "$IPSET_BLACKLIST_NAME"; then
if [[ ${FORCE:-no} != yes ]]; then
echo >&2 "Error: ipset does not exist yet, add it using:"
echo >&2 "# ipset create $IPSET_BLACKLIST_NAME -exist hash:net family inet hashsize ${HASHSIZE:-16384} maxelem ${MAXELEM:-65536}"
exit 1
fi
if ! ipset create "$IPSET_BLACKLIST_NAME" -exist hash:net family inet hashsize "${HASHSIZE:-16384}" maxelem "${MAXELEM:-65536}"; then
echo >&2 "Error: while creating the initial ipset"
exit 1
fi
fi
# create the iptables binding if needed (or abort if does not exists and FORCE=no)
if ! iptables -nvL INPUT | command grep -q "match-set $IPSET_BLACKLIST_NAME"; then
# we may also have assumed that INPUT rule n°1 is about packets statistics (traffic monitoring)
if [[ ${FORCE:-no} != yes ]]; then
echo >&2 "Error: iptables does not have the needed ipset INPUT rule, add it using:"
echo >&2 "# iptables -I INPUT ${IPTABLES_IPSET_RULE_NUMBER:-1} -m set --match-set $IPSET_BLACKLIST_NAME src -j DROP"
exit 1
fi
if ! iptables -I INPUT "${IPTABLES_IPSET_RULE_NUMBER:-1}" -m set --match-set "$IPSET_BLACKLIST_NAME" src -j DROP; then
echo >&2 "Error: while adding the --match-set ipset rule to iptables"
exit 1
fi
fi
IP_BLACKLIST_TMP=$(mktemp)
for i in "${BLACKLISTS[@]}"; do
IP_TMP=$(mktemp)
((HTTP_RC = $(curl -L -A "blacklist-update/script/github" --connect-timeout 10 --max-time 10 -o "$IP_TMP" -s -w "%{http_code}" "$i")))
if ((HTTP_RC == 200 || HTTP_RC == 302 || HTTP_RC == 0)); then # "0" because file:/// returns 000
command grep -Po '^(?:\d{1,3}\.){3}\d{1,3}(?:/\d{1,2})?' "$IP_TMP" | sed -r 's/^0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+)$/\1.\2.\3.\4/' >>"$IP_BLACKLIST_TMP"
[[ ${VERBOSE:-yes} == yes ]] && echo -n "."
elif ((HTTP_RC == 503)); then
echo -e "\\nUnavailable (${HTTP_RC}): $i"
else
echo >&2 -e "\\nWarning: curl returned HTTP response code $HTTP_RC for URL $i"
fi
rm -f "$IP_TMP"
done
# sort -nu does not work as expected
sed -r -e '/^(0\.0\.0\.0|10\.|127\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.|192\.168\.|22[4-9]\.|23[0-9]\.)/d' "$IP_BLACKLIST_TMP" | sort -n | sort -mu >|"$IP_BLACKLIST"
if [[ ${DO_OPTIMIZE_CIDR} == yes ]]; then
if [[ ${VERBOSE:-no} == yes ]]; then
echo -e "\\nAddresses before CIDR optimization: $(wc -l "$IP_BLACKLIST" | cut -d' ' -f1)"
fi
iprange <"$IP_BLACKLIST" --optimize - >"$IP_BLACKLIST_TMP" 2>/dev/null
if [[ ${VERBOSE:-no} == yes ]]; then
echo "Addresses after CIDR optimization: $(wc -l "$IP_BLACKLIST_TMP" | cut -d' ' -f1)"
fi
cp "$IP_BLACKLIST_TMP" "$IP_BLACKLIST"
fi
rm -f "$IP_BLACKLIST_TMP"
# family = inet for IPv4 only
cat >|"$IP_BLACKLIST_RESTORE" <<EOF
create $IPSET_TMP_BLACKLIST_NAME -exist hash:net family inet hashsize ${HASHSIZE:-16384} maxelem ${MAXELEM:-65536}
create $IPSET_BLACKLIST_NAME -exist hash:net family inet hashsize ${HASHSIZE:-16384} maxelem ${MAXELEM:-65536}
EOF
# can be IPv4 including netmask notation
# IPv6 ? -e "s/^([0-9a-f:./]+).*/add $IPSET_TMP_BLACKLIST_NAME \1/p" \ IPv6
sed -rn -e '/^#|^$/d' \
-e "s/^([0-9./]+).*/add $IPSET_TMP_BLACKLIST_NAME \\1/p" "$IP_BLACKLIST" >>"$IP_BLACKLIST_RESTORE"
cat >>"$IP_BLACKLIST_RESTORE" <<EOF
swap $IPSET_BLACKLIST_NAME $IPSET_TMP_BLACKLIST_NAME
destroy $IPSET_TMP_BLACKLIST_NAME
EOF
ipset -file "$IP_BLACKLIST_RESTORE" restore
if [[ ${VERBOSE:-no} == yes ]]; then
echo
echo "Blacklisted addresses found: $(wc -l "$IP_BLACKLIST" | cut -d' ' -f1)"
fi