Skip to content

Instantly share code, notes, and snippets.

@ProducerMatt
Forked from jgoettsch/malware_block.ksh
Last active March 14, 2021 00:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ProducerMatt/c79e621bb4f02d8cb0a543830f012638 to your computer and use it in GitHub Desktop.
Save ProducerMatt/c79e621bb4f02d8cb0a543830f012638 to your computer and use it in GitHub Desktop.
Block malware with unbound on OpenBSD
#!/bin/ksh
#set -x #DEBUG
# Call with -d to leave a diff between the old and new files
[ `id -u` == 0 ] || { echo "Please run as root!" && exit 3 ; }
URL="https://urlhaus.abuse.ch/downloads/hostfile"
TMPDIR="/tmp"
HOSTFILE="$TMPDIR/hostfile"
UNBOUND_ETC="/var/unbound/etc"
MALWARE_CONF="$UNBOUND_ETC/malware.conf"
NEW_MALWARE_CONF="$TMPDIR/malware.conf"
LAST_DIFF="$UNBOUND_ETC/malware_conf_changes.diff"
CACHE_DUMP="$TMPDIR/cache.dump"
CONF_PERMISSIONS="660" # chmod permissions for final file. I have a DNS admin
CHANGES="" # group managing unbound.conf so there's what I use.
CURL="/usr/local/bin/curl"
# Enter working directory and turn off r/w for other users
cd "$TMPDIR" || { echo "can't cd to $TMPDIR" && exit 1 ; }
# Nobody else needs to use these, so...
umask 177
# Get the hostfile
$CURL -sS "$URL" -o "$HOSTFILE" || { echo "cURL error $?" && exit 2 ; }
# Add a little header to new file
echo "#$MALWARE_CONF generated from $URL on `date`" > "$NEW_MALWARE_CONF"
# Get hostfile, clean, sort, and construct a valid unbound config from it
grep -v "^#" "$HOSTFILE" \
| sed 's/ //g' \
| sort \
| awk '{print "local-zone: \""$2"\" redirect\nlocal-data: \""$2" A 0.0.0.0\""}' \
>> "$NEW_MALWARE_CONF"
# DIFF {
# If we will replace an old config, then record the diff of the two
# On OpenBSD, just add malware.conf to /etc/changelist for
# daily security mailings to do this for you.
if [ "(" "$1" = "-d" ")" -a "(" -s "$MALWARE_CONF" ")" ];
then
echo "making a diff"
CHANGES=`diff "$MALWARE_CONF" "$NEW_MALWARE_CONF"`
echo `[ -z "$CHANGES" ]` # DEBUG
if [ -z "$CHANGES" ]; # should be 0 if no differences
then
echo "No difference!"
rm -f "$HOSTFILE" "$CACHE_DUMP" "$NEW_MALWARE_CONF"
exit 0
fi
echo "$CHANGES" > "$LAST_DIFF"
echo "Diff size:"
wc -l "$LAST_DIFF"
else
echo "not making a diff"
fi
# }
# Check that the new malware.conf is formatted right
# Add "server" header so checkconf accepts it as
# a standalone file.
sed '1 a\
server:
' "$NEW_MALWARE_CONF" > "$NEW_MALWARE_CONF.check"
unbound-checkconf "$NEW_MALWARE_CONF.check" || { echo "new malware.conf malformed? error $?" && exit 7 ; }
# Replace the old file
mv -f "$NEW_MALWARE_CONF" "$MALWARE_CONF"
# Set permissions
chmod "$CONF_PERMISSIONS" "$MALWARE_CONF"
umask 022 # root.key seems to inherit umask when called from this script, rendering unbound unstartable
# Persist Unbound cache across reloads (it clears even without restart)
unbound-control dump_cache > "$CACHE_DUMP" || { echo "code $! with dump_cache" && exit 4 ; }
# only dumps from 1st thread as of Dec 28th 2020
# if you use multiple threads don't be surprised if it's empty :/
rcctl reload unbound || { echo "code $! with rcctl reload; continuing" ; }
# This turns off unbound on my system?
rcctl start unbound || { echo "code $! with rcctl start" && exit 5 ; } # Delete this part once reload isn't weird
unbound-control load_cache < "$CACHE_DUMP" || { echo "code $! with load_cache" && exit 6 ; }
# Cleanup
rm -f "$HOSTFILE" "$CACHE_DUMP" "$NEW_MALWARE_CONF" "$NEW_MALWARE_CONF.check"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment