Created
May 29, 2019 23:50
-
-
Save digitalsanity/0ddf3c579f6b34013889576b0bf080d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# usage update-blacklist.sh <configuration file> | |
# eg: update-blacklist.sh /etc/ipset-blacklist/ipset-blacklist.conf | |
# | |
if [[ -z "$1" ]]; then | |
echo "Error: please specify a configuration file, e.g. $0 /etc/ipset-blacklist/ipset-blacklist.conf" | |
exit 1 | |
fi | |
if ! source "$1"; then | |
echo "Error: can't load configuration file $1" | |
exit 1 | |
fi | |
if ! which curl egrep grep ipset iptables sed sort wc &> /dev/null; then | |
echo >&2 "Error: searching PATH fails to find executables among: curl egrep grep ipset iptables sed sort wc" | |
exit 1 | |
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) | |
let 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|so | |
rt -mu >| "$IP_BLACKLIST" | |
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 "Number of blacklisted IP/networks found: `wc -l $IP_BLACKLIST | cut -d' ' -f1`" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment