Last active
April 26, 2018 19:43
-
-
Save fitz123/b7dcfb6fe91c88a93719a1b87b1a0a9d to your computer and use it in GitHub Desktop.
Disable interface if target IP became unavailable
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
#!/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