Skip to content

Instantly share code, notes, and snippets.

@fitz123
Last active April 26, 2018 19:43
Show Gist options
  • Save fitz123/b7dcfb6fe91c88a93719a1b87b1a0a9d to your computer and use it in GitHub Desktop.
Save fitz123/b7dcfb6fe91c88a93719a1b87b1a0a9d to your computer and use it in GitHub Desktop.
Disable interface if target IP became unavailable
#!/usr/bin/env bash
set -u
IFS=$'\n\t'
## Author: anton.lugovoi
#/
#/ Description: Move interface into the drop zone
#/ if monitored IP became unreachable
#/ Restores interface original zone
#/ if monitored IP became reachable
#/
#/ Expected followed mandatory parameters:
#/ -i interface which exists and has to have firewalld zone assigned
#/ -t valid IP address which will be used as Lockdown trigger
#/ -m available mods: watch, lock, unlock
#/
#/ Example of usage: lockdown.sh -i eth0 -t 8.8.8.8 -m watch
#/
usage() { grep '^#/' "$0" | cut -c4- ; exit 0 ; }
expr "$*" : ".*--help" > /dev/null && usage
lock='/root/lockdown.lock'
statef='/tmp/lockdown.state'
pid='/tmp/lockdown.pid'
# set params
set +u
while getopts ":i:t:m:" o; do
case "${o}" in
i)
int=${OPTARG}
firewall-cmd --get-zone-of-interface=$int &>/dev/null \
|| { echo "ERR: bad -i parameter. Must to be assigned to firewalld zone"; usage; }
;;
t)
trigger=${OPTARG}
echo $trigger | grep -woE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" &>/dev/null \
|| { echo "ERR: bad -t parameter. Must be ipv4 address"; usage; }
;;
m)
mode=${OPTARG}
;;
*)
echo "ERR: wrong parameter: ${OPTARG}"
usage
;;
esac
done
shift $((OPTIND-1))
if [ -z "${int}" ] || [ -z "${trigger}" ] || [ -z "${mode}" ]; then
echo "ERR: missing parameter"
usage
fi
set -u
function cleanup() {
rm -f /tmp/lockdown.pid
exit
}
function trimlog() {
[[ $(find $log -size +100M 2>/dev/null) ]] \
&& gzip -f $log &>/dev/null
}
function lock() {
if [ -f $lock ]; then
echo "Lockdown mode is forced, remove $lock to change"
sleep 10
continue
fi
echo "Entering Lockdown mode..."
firewall-cmd --zone=drop --change-interface=${int} &>/dev/null
echo 1 > $statef
echo "Lockdown mode ON"
}
function unlock() {
if [ -f $lock ]; then
echo "Lockdown mode is forced, remove $lock to change"
sleep 10
continue
fi
echo "Exiting Lockdown mode..."
firewall-cmd --zone=${origzone} --change-interface=${int} &>/dev/null
echo 0 > $statef
echo "Lockdown mode OFF"
}
function watch() {
# Infinite loop of checks
echo "Watching lock trigger..."
while true; do
state=$(<$statef)
if ping -w1 -qnc3 -i0.3 $trigger &>/dev/null; then
if [ "$state" = "1" ]; then
echo "Detected connection to trigger IP: $trigger"
unlock
echo "Watching lock trigger..."
fi
else
if [ "$state" = "0" ]; then
echo "Lost connection to trigger IP: $trigger"
lock
echo "Watching lock trigger..."
fi
fi
done
}
trap cleanup EXIT INT TERM
# main
echo $$ > $pid
echo 0 > $statef
origzone=$(firewall-cmd --get-zone-of-interface=${int} &>/dev/null)
[ "$origzone" = "drop" ] && echo 1 > $statef
case "${mode}" in
"lock")
rm $lock 2>/dev/null
lock
touch $lock
;;
"unlock")
rm $lock 2>/dev/null
unlock
touch $lock
;;
"watch")
watch
;;
*)
echo "ERR: bad mode. Expected lock, unlock or watch"
usage
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment