Handle f5 vpns via gof5 (https://github.com/kayrus/gof5)
This commit is contained in:
parent
9307b7cb66
commit
c86fdcd72b
241
cvpn
241
cvpn
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
. ${HOME}/code/bashtools/bashtools.sh
|
. ${HOME}/code/bashtools/bashtools.sh
|
||||||
if [[ -z $HAVE_BASHTOOLS ]]; then
|
if [[ -z $HAVE_BASHTOOLS ]]; then
|
||||||
|
@ -7,8 +7,13 @@ if [[ -z $HAVE_BASHTOOLS ]]; then
|
||||||
fi
|
fi
|
||||||
CONFDIR=${HOME}/.vpn
|
CONFDIR=${HOME}/.vpn
|
||||||
LOGFILE=${CONFDIR}/log
|
LOGFILE=${CONFDIR}/log
|
||||||
|
VPNPIDFILE=${CONFDIR}/f5pid
|
||||||
DEFAULTCONF=${CONFDIR}/config
|
DEFAULTCONF=${CONFDIR}/config
|
||||||
CONFFILE=${DEFAULTCONF}
|
CONFFILE=${DEFAULTCONF}
|
||||||
|
VALID_VENDORS="cisco|f5"
|
||||||
|
|
||||||
|
cp -p "$LOGFILE" "${LOGFILE}.0"
|
||||||
|
cp /dev/null "$LOGFILE"
|
||||||
|
|
||||||
VPN=/opt/cisco/anyconnect/bin/vpn
|
VPN=/opt/cisco/anyconnect/bin/vpn
|
||||||
|
|
||||||
|
@ -40,9 +45,6 @@ function load_config() {
|
||||||
DEFAULTPROFILE=""
|
DEFAULTPROFILE=""
|
||||||
if [[ -e ${CONFFILE} ]]; then
|
if [[ -e ${CONFFILE} ]]; then
|
||||||
DEFAULTPROFILE=$(grep '^#default:' "${CONFFILE}" | sed 's/^#default://')
|
DEFAULTPROFILE=$(grep '^#default:' "${CONFFILE}" | sed 's/^#default://')
|
||||||
if [[ -n ${DEFAULTPROFILE} ]]; then
|
|
||||||
inform "[default VPN: ^b$DEFAULTPROFILE^p]"
|
|
||||||
fi
|
|
||||||
CONFLINES=$(egrep -v "^#" ${CONFFILE} 2>/dev/null | awk NF)
|
CONFLINES=$(egrep -v "^#" ${CONFFILE} 2>/dev/null | awk NF)
|
||||||
nvpns=0
|
nvpns=0
|
||||||
while read line; do
|
while read line; do
|
||||||
|
@ -51,12 +53,23 @@ function load_config() {
|
||||||
thisuser=$(cut -d, -f2 <<< "${line}")
|
thisuser=$(cut -d, -f2 <<< "${line}")
|
||||||
thispw=$(cut -d, -f3 <<< "${line}")
|
thispw=$(cut -d, -f3 <<< "${line}")
|
||||||
thisgroup=$(cut -d, -f4 <<< "${line}")
|
thisgroup=$(cut -d, -f4 <<< "${line}")
|
||||||
|
thisvendor=$(cut -d, -f5 <<< "${line}")
|
||||||
|
thisserver=$(cut -d, -f6 <<< "${line}")
|
||||||
|
[[ -z $thisvendor ]] && thisvendor="cisco"
|
||||||
|
[[ -z $thisserver ]] && thisvendor="n/a"
|
||||||
|
if [[ ! $thisvendor =~ $VALID_VENDORS ]]; then
|
||||||
|
error "invalid VPN vendor '$thisvendor', must be $VALID_VENDORS"
|
||||||
|
cecho -s "$RED" "^bBad line:^p $line"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
profile[$nvpns]="${thisprofile}"
|
profile[$nvpns]="${thisprofile}"
|
||||||
user[$nvpns]="${thisuser}"
|
user[$nvpns]="${thisuser}"
|
||||||
pw[$nvpns]="${thispw}"
|
pw[$nvpns]="${thispw}"
|
||||||
group[$nvpns]="${thisgroup}"
|
group[$nvpns]="${thisgroup}"
|
||||||
|
vendor[$nvpns]="${thisvendor}"
|
||||||
|
server[$nvpns]="${thisserver}"
|
||||||
nvpns=$((nvpns + 1))
|
nvpns=$((nvpns + 1))
|
||||||
done <<< ${CONFLINES}
|
done <<< "${CONFLINES}"
|
||||||
else
|
else
|
||||||
error "Config file '$CONFFILE' not found"
|
error "Config file '$CONFFILE' not found"
|
||||||
return 1
|
return 1
|
||||||
|
@ -74,11 +87,14 @@ function usage() {
|
||||||
echo " -c file Use selected config file (default is ${DEFAULTCONF})"
|
echo " -c file Use selected config file (default is ${DEFAULTCONF})"
|
||||||
echo
|
echo
|
||||||
echo "Config file format:"
|
echo "Config file format:"
|
||||||
|
echo " #Specify default profile like this:"
|
||||||
echo " #default:myvpn2"
|
echo " #default:myvpn2"
|
||||||
echo " myvpn1,username_1,password_1,vpngroup_1"
|
echo " #Profile,Username,Password,VPNGroup,VPNType,ServerIP"
|
||||||
echo " myvpn2,username_2,password_2,vpngroup_2"
|
echo " # Cisco VPNs have just user 'server' for status, and group is optional"
|
||||||
echo " # This one has no 'group'"
|
echo " myvpn1,username_1,password_1,vpngroup_1,cisco,3.3.3.3"
|
||||||
echo " myvpn3,username_3,password_3"
|
echo " myvpn2,username_2,password_2,vpngroup_2,cisco,1.1.1.1"
|
||||||
|
echo " # F5 VPNs must have a 'server'"
|
||||||
|
echo " myvpn3,username_3,password_3,,f5,1.2.3.4"
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +112,49 @@ function get_profile_id() { #1=profile_to_check
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_vpn_status() { # populates vprofile vuser vstatus vserver vvendor, return 0 if vpn up
|
||||||
|
local rv=0 fpid pname
|
||||||
|
vprofile=""
|
||||||
|
vuser=""
|
||||||
|
vstatus="Disconnected"
|
||||||
|
vserver=""
|
||||||
|
vvendor=""
|
||||||
|
|
||||||
|
if [[ -e $VPNPIDFILE ]]; then
|
||||||
|
fpid=$(cat $VPNPIDFILE 2>/dev/null)
|
||||||
|
pname=$(ps -p $fpid -o command="" 2>/dev/null)
|
||||||
|
if [[ $pname =~ gof5 ]]; then
|
||||||
|
vstatus="Connected"
|
||||||
|
vserver=$(echo "$pname" | sed 's/^.*--server //;s/ .*//g')
|
||||||
|
vuser=$(echo "$pname" | sed 's/^.*--username //;s/ .*//g')
|
||||||
|
vvendor=F5
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# no f5 vpn, check anyconnect
|
||||||
|
res=$(${VPN} stats 2>&1)
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
vstatus=$(grep 'Connection State:' <<< "$res" | grep -v Manage | awk '{ print $3 }' )
|
||||||
|
if [[ $vstatus == "Connected" ]]; then
|
||||||
|
vvendor="Cisco"
|
||||||
|
vserver=$(grep 'Server Address:' <<< "$res" | awk '{ print $3 }' )
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
rv=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $vstatus == "Connected" ]]; then
|
||||||
|
# find matching profile
|
||||||
|
for x in ${!profile[@]}; do
|
||||||
|
if [[ $vserver == ${server[$x]} ]]; then
|
||||||
|
vprofile="${profile[$x]}"
|
||||||
|
[[ -z $vuser ]] && vuser=${user[$x]}
|
||||||
|
[[ -z $vvendor ]] && vvendor=${vvendor[$x]}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
return $rv
|
||||||
|
}
|
||||||
|
|
||||||
PROFILE=""
|
PROFILE=""
|
||||||
|
|
||||||
|
@ -126,20 +185,47 @@ fi
|
||||||
cmd=$(alias_to_cmd "$1")
|
cmd=$(alias_to_cmd "$1")
|
||||||
|
|
||||||
load_config || exit 1
|
load_config || exit 1
|
||||||
PROFILE="$DEFAULTPROFILE"
|
|
||||||
|
usingdefault=0
|
||||||
|
PROFILE="$2"
|
||||||
|
if [[ -z $PROFILE ]]; then
|
||||||
|
if [[ -n ${DEFAULTPROFILE} ]]; then
|
||||||
|
PROFILE="${DEFAULTPROFILE}"
|
||||||
|
usingdefault=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
pgrep -q gof5 && f5up=1 || f5up=0
|
||||||
|
|
||||||
if [[ $cmd == "list" ]]; then
|
if [[ $cmd == "list" ]]; then
|
||||||
F="%s,%s,%s,%s\n"
|
F="%s,%s,%s,%s,%s,%s\n"
|
||||||
(
|
table=$(
|
||||||
printf "${F}" "Profile" "Username" "Password" "Group"
|
(
|
||||||
for x in ${!profile[@]}; do
|
printf "${F}" "Profile" "Username" "Password" "Group" "Server" "Type"
|
||||||
printf "${F}" "${profile[$x]}" "${user[$x]}" "${pw[$x]}" "${group[$x]:-(n/a)}"
|
for x in ${!profile[@]}; do
|
||||||
done
|
p="${pw[$x]:0:2}....${pw[$x]: (-2)}"
|
||||||
) | column -s, -t
|
prof="${profile[$x]}"
|
||||||
|
[[ $prof == $DEFAULTPROFILE ]] && prof="*${prof}"
|
||||||
|
printf "${F}" "${prof}" "${user[$x]}" "${p}" "${group[$x]:-(n/a)}" "${server[$x]:-(n/a)}" "${vendor[$x]}"
|
||||||
|
done
|
||||||
|
) | column -s, -t
|
||||||
|
)
|
||||||
|
table=$(echo "$table" | sed "s/^\(Profile.*\)$/^b^u\1^p/;s/\(n\/a\)/^i\1^p/g")
|
||||||
|
csecho "$WHITE" "$table"
|
||||||
|
echo
|
||||||
|
echo "(* = default VPN)"
|
||||||
exit 0
|
exit 0
|
||||||
elif [[ $cmd == "on" ]]; then
|
elif [[ $cmd == "on" ]]; then
|
||||||
|
[[ $usingdefault -eq 1 ]] && inform "[using default VPN: ^b$DEFAULTPROFILE^p]"
|
||||||
|
get_vpn_status
|
||||||
|
if [[ $vstatus == "Connected" ]]; then
|
||||||
|
error "VPN profile $vprofile is already connected"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z ${PROFILE} ]]; then
|
if [[ -z ${PROFILE} ]]; then
|
||||||
error "No default VPN is set."
|
error "No VPN profile provided and no default VPN profile set."
|
||||||
csecho "$RED" "Either specify on commandline, or add this to ^b${CONFFILE}^p:"
|
csecho "$RED" "Either specify on commandline, or add this to ^b${CONFFILE}^p:"
|
||||||
csecho "$RED" "#default:^ivpn_name^p"
|
csecho "$RED" "#default:^ivpn_name^p"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -149,6 +235,12 @@ elif [[ $cmd == "on" ]]; then
|
||||||
curuser=${user[$id]}
|
curuser=${user[$id]}
|
||||||
curpw=${pw[$id]}
|
curpw=${pw[$id]}
|
||||||
curgroup=${group[$id]}
|
curgroup=${group[$id]}
|
||||||
|
curvendor=${vendor[$id]}
|
||||||
|
if [[ $curvendor == "f5" ]]; then
|
||||||
|
curserver=${server[$id]}
|
||||||
|
else
|
||||||
|
curserver=""
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -156,49 +248,102 @@ elif [[ $cmd == "on" ]]; then
|
||||||
nstr="Connecting to ^b${PROFILE}^p as user ^b${curuser}^p"
|
nstr="Connecting to ^b${PROFILE}^p as user ^b${curuser}^p"
|
||||||
[[ -n $curgroup ]] && nstr="${nstr} group ${curgroup}"
|
[[ -n $curgroup ]] && nstr="${nstr} group ${curgroup}"
|
||||||
notify "${nstr}"
|
notify "${nstr}"
|
||||||
if [[ -n $curgroup ]]; then
|
|
||||||
answers="y\n${curgroup}\n${curuser}\n${curpw}\n"
|
if [[ $curvendor == "f5" ]]; then
|
||||||
|
rm -f "$VPNPIDFILE"
|
||||||
|
nohup sudo gof5 --server "${curserver}" --username "${curuser}" --password "${curpw}" >>${LOGFILE} 2>&1 &
|
||||||
|
f5pid=$!
|
||||||
|
nlines=0
|
||||||
|
res=""
|
||||||
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
|
nlines=$((nlines + 1))
|
||||||
|
if [[ ${line,,} =~ stablished ]]; then
|
||||||
|
rv=0
|
||||||
|
res="$line"
|
||||||
|
break
|
||||||
|
elif [[ ${line,,} =~ failed ]]; then
|
||||||
|
rv=1;
|
||||||
|
res="$line"
|
||||||
|
break;
|
||||||
|
elif [[ ${nlines} -ge 30 ]]; then
|
||||||
|
rv=4;
|
||||||
|
res="$line"
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
ps -p $f5pid >/dev/null 2>&1
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
rv=2;
|
||||||
|
res="$line"
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
done < <(timeout 300 tail -f ${LOGFILE} )
|
||||||
|
|
||||||
|
if [[ -z $res ]]; then
|
||||||
|
rv=3;
|
||||||
|
res="$(tail -n 10 ${LOGFILE})"
|
||||||
|
fi
|
||||||
|
if [[ $rv -eq 0 ]]; then
|
||||||
|
echo "$f5pid" > "$VPNPIDFILE"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
answers="y\n${curuser}\n${curpw}\n"
|
if [[ -n $curgroup ]]; then
|
||||||
|
answers="y\n${curgroup}\n${curuser}\n${curpw}\n"
|
||||||
|
else
|
||||||
|
answers="y\n${curuser}\n${curpw}\n"
|
||||||
|
fi
|
||||||
|
res=$(echo -e "$answers" | ${VPN} -s connect "$PROFILE" 2>&1 | tee ${LOGFILE})
|
||||||
|
grep -q 'state: Connected' <<< "$res$"
|
||||||
|
rv=$?
|
||||||
fi
|
fi
|
||||||
res=$(echo -e "$answers" | ${VPN} -s connect "$PROFILE" 2>&1 | tee ${LOGFILE})
|
if [[ $rv -eq 0 ]]; then
|
||||||
grep -q 'state: Connected' <<< "$res$"
|
|
||||||
if [[ $? -eq 0 ]]; then
|
|
||||||
ok "connected"
|
ok "connected"
|
||||||
else
|
else
|
||||||
fail
|
fail
|
||||||
error "Connection failed, logs are in ^b${LOGFILE}^p."
|
if [[ $curvendor == "cisco" ]]; then
|
||||||
|
error "Connection failed, logs are in ^b${LOGFILE}^p."
|
||||||
|
else
|
||||||
|
error "Connection failed, logs are below:"
|
||||||
|
cecho -s "$RED" "$res" | sed 's/^/ /'
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
elif [[ $cmd == "status" ]]; then
|
elif [[ $cmd == "status" ]]; then
|
||||||
|
BASECOL="$ORANGE"
|
||||||
notify "Checking VPN status"
|
notify "Checking VPN status"
|
||||||
res=$(${VPN} stats 2>&1)
|
get_vpn_status
|
||||||
if [[ $? -eq 0 ]]; then
|
[[ $? -eq 0 ]] && ok || fail
|
||||||
ok
|
if [[ $vstatus == "Connected" ]]; then
|
||||||
echo "$res" > z
|
col="$GREEN"
|
||||||
status=$(grep 'Connection State:' <<< "$res" | grep -v Manage | awk '{ print $3 }' )
|
|
||||||
[[ -z $status ]] && status="Unknown"
|
|
||||||
if [[ $status == "Connected" ]]; then
|
|
||||||
col="$GREEN"
|
|
||||||
dst=$(grep 'Server Address:' <<< "$res" | awk '{ print $3 }' )
|
|
||||||
else
|
|
||||||
col="$RED"
|
|
||||||
dst=""
|
|
||||||
fi
|
|
||||||
BASECOL="$ORANGE"
|
|
||||||
csecho -n "$BASECOL" "VPN status: ${col}${BOLD}${status}^p"
|
|
||||||
[[ -n $dst ]] && csecho "$BASECOL" " to ${dst}" || echo
|
|
||||||
else
|
else
|
||||||
fail
|
col="$RED"
|
||||||
error "Status check failed."
|
fi
|
||||||
|
csecho -n "$BASECOL" "VPN status: ${col}${BOLD}${vstatus}^p"
|
||||||
|
if [[ ${vstatus,,} =~ "connected" ]]; then
|
||||||
|
[[ -n $vserver ]] && csecho "$BASECOL" " to ^b${vprofile}^p (${vvendor}:${vuser}@${vserver})" || echo
|
||||||
fi
|
fi
|
||||||
elif [[ $cmd == "off" ]]; then
|
elif [[ $cmd == "off" ]]; then
|
||||||
notify "Disconnecting from VPN"
|
rv=1
|
||||||
${VPN} disconnect > ${LOGFILE} 2>&1
|
get_vpn_status
|
||||||
if [[ $? -eq 0 ]]; then
|
if [[ $vstatus == "Connected" ]]; then
|
||||||
ok
|
notify "Disconnecting from ${vvendor} VPN ^b${vprofile}^p"
|
||||||
|
|
||||||
|
if [[ ${vvendor,,} == "f5" ]]; then
|
||||||
|
#sudo gof5 --server ${s} --close-session
|
||||||
|
sudo kill $(cat $VPNPIDFILE)
|
||||||
|
rm -f "${VPNPIDFILE}"
|
||||||
|
rv=0
|
||||||
|
else
|
||||||
|
${VPN} disconnect > ${LOGFILE} 2>&1
|
||||||
|
rv=$?
|
||||||
|
fi
|
||||||
|
if [[ $rv -eq 0 ]]; then
|
||||||
|
ok
|
||||||
|
else
|
||||||
|
fail
|
||||||
|
error "Connection failed, logs are in ^b${LOGFILE}^p."
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
fail
|
fail
|
||||||
error "Connection failed, logs are in ^b${LOGFILE}^p."
|
error "All VPNs are already disconnected"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
usage
|
usage
|
||||||
|
|
Loading…
Reference in New Issue