Move to openconnet + vpnslice
This commit is contained in:
parent
119d9c0d38
commit
bb03283347
126
cvpn
126
cvpn
|
@ -15,7 +15,15 @@ VALID_VENDORS="cisco|f5"
|
||||||
cp -p "$LOGFILE" "${LOGFILE}.0"
|
cp -p "$LOGFILE" "${LOGFILE}.0"
|
||||||
cp /dev/null "$LOGFILE"
|
cp /dev/null "$LOGFILE"
|
||||||
|
|
||||||
VPN=/opt/cisco/anyconnect/bin/vpn
|
OPENCONNECT=$(which openconnect 2>/dev/null)
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
warn "Can't find openconnect binary - Cisco VPNs won't work."
|
||||||
|
fi
|
||||||
|
VPNSLICE=$(which vpn-slice 2>/dev/null)
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
warn "Can't find vpn-slice binary - Cisco VPNs won't work."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
mkdir -p "${CONFDIR}"
|
mkdir -p "${CONFDIR}"
|
||||||
|
|
||||||
|
@ -41,7 +49,7 @@ function alias_to_cmd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function load_config() {
|
function load_config() {
|
||||||
local CONFLINES line thisprofile thisuser thispw thisgroup
|
local CONFLINES line thisprofile thisuser thispw thisgroup thisroutes thisservercert
|
||||||
DEFAULTPROFILE=""
|
DEFAULTPROFILE=""
|
||||||
if [[ -e ${CONFFILE} ]]; then
|
if [[ -e ${CONFFILE} ]]; then
|
||||||
DEFAULTPROFILE=$(grep '^#default:' "${CONFFILE}" | sed 's/^#default://')
|
DEFAULTPROFILE=$(grep '^#default:' "${CONFFILE}" | sed 's/^#default://')
|
||||||
|
@ -55,6 +63,8 @@ function load_config() {
|
||||||
thisgroup=$(cut -d, -f4 <<< "${line}")
|
thisgroup=$(cut -d, -f4 <<< "${line}")
|
||||||
thisvendor=$(cut -d, -f5 <<< "${line}")
|
thisvendor=$(cut -d, -f5 <<< "${line}")
|
||||||
thisserver=$(cut -d, -f6 <<< "${line}")
|
thisserver=$(cut -d, -f6 <<< "${line}")
|
||||||
|
thisroutes=$(cut -d, -f7 <<< "${line}")
|
||||||
|
thisservercert=$(cut -d, -f8 <<< "${line}")
|
||||||
[[ -z $thisvendor ]] && thisvendor="cisco"
|
[[ -z $thisvendor ]] && thisvendor="cisco"
|
||||||
[[ -z $thisserver ]] && thisvendor="n/a"
|
[[ -z $thisserver ]] && thisvendor="n/a"
|
||||||
if [[ ! $thisvendor =~ $VALID_VENDORS ]]; then
|
if [[ ! $thisvendor =~ $VALID_VENDORS ]]; then
|
||||||
|
@ -68,6 +78,8 @@ function load_config() {
|
||||||
group[$nvpns]="${thisgroup}"
|
group[$nvpns]="${thisgroup}"
|
||||||
vendor[$nvpns]="${thisvendor}"
|
vendor[$nvpns]="${thisvendor}"
|
||||||
server[$nvpns]="${thisserver}"
|
server[$nvpns]="${thisserver}"
|
||||||
|
routes[$nvpns]="${thisroutes}"
|
||||||
|
servercert[$nvpns]="${thisservercert}"
|
||||||
nvpns=$((nvpns + 1))
|
nvpns=$((nvpns + 1))
|
||||||
done <<< "${CONFLINES}"
|
done <<< "${CONFLINES}"
|
||||||
else
|
else
|
||||||
|
@ -128,20 +140,15 @@ function get_vpn_status() { # populates vprofile vuser vstatus vserver vvendor,
|
||||||
vserver=$(echo "$pname" | sed 's/^.*--server //;s/ .*//g')
|
vserver=$(echo "$pname" | sed 's/^.*--server //;s/ .*//g')
|
||||||
vuser=$(echo "$pname" | sed 's/^.*--username //;s/ .*//g')
|
vuser=$(echo "$pname" | sed 's/^.*--username //;s/ .*//g')
|
||||||
vvendor=F5
|
vvendor=F5
|
||||||
fi
|
elif [[ $pname =~ openconnect ]]; then
|
||||||
else
|
vstatus="Connected"
|
||||||
# no f5 vpn, check anyconnect
|
vserver=$(echo "$pname" | awk '{ print $NF }')
|
||||||
res=$(${VPN} stats 2>&1)
|
vuser=$(echo "$pname" | sed 's/^.*-u //;s/ .*//g')
|
||||||
if [[ $? -eq 0 ]]; then
|
vvendor=Cisco
|
||||||
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
|
fi
|
||||||
else
|
else
|
||||||
rv=1
|
rv=1
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $vstatus == "Connected" ]]; then
|
if [[ $vstatus == "Connected" ]]; then
|
||||||
# find matching profile
|
# find matching profile
|
||||||
|
@ -232,25 +239,69 @@ elif [[ $cmd == "on" ]]; then
|
||||||
fi
|
fi
|
||||||
id=$(get_profile_id "${PROFILE}")
|
id=$(get_profile_id "${PROFILE}")
|
||||||
if [[ -n $id ]]; then
|
if [[ -n $id ]]; then
|
||||||
|
curprofile=${profile[$id]}
|
||||||
curuser=${user[$id]}
|
curuser=${user[$id]}
|
||||||
curpw=${pw[$id]}
|
curpw=${pw[$id]}
|
||||||
curgroup=${group[$id]}
|
curgroup=${group[$id]}
|
||||||
curvendor=${vendor[$id]}
|
curvendor=${vendor[$id]}
|
||||||
if [[ $curvendor == "f5" ]]; then
|
|
||||||
curserver=${server[$id]}
|
curserver=${server[$id]}
|
||||||
|
curservercert=${servercert[$id]}
|
||||||
|
curroutes=${routes[$id]}
|
||||||
else
|
else
|
||||||
curserver=""
|
error "Could not determine VPN ID for profile ^b${PROFILE}^p."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $curservercert && ${curvendor,,} == "cisco" ]]; then
|
||||||
|
inform "No server certificate is defined for ^b$curprofile^p."
|
||||||
|
notify "Trying to obtain server certificate"
|
||||||
|
foundcert=$(sudo ${OPENCONNECT} --non-inter --protocol=anyconnect -u "$curuser" --authgroup="$curgroup" "$curserver" 2>&1 | grep -- --servercert | awk '{ print $NF }')
|
||||||
|
if [[ -n $foundcert ]]; then
|
||||||
|
ok
|
||||||
|
inform "Got server certificate '^b${foundcert}^p'"
|
||||||
|
notify "Updating configuration file ^b$CONFFILE^p"
|
||||||
|
bakfile="${CONFFILE}".backup
|
||||||
|
prevlines=$(cat "$CONFFILE" | awk NF | wc -l | bc)
|
||||||
|
newconfig=$(cat "${CONFFILE}" | awk -v p="$curprofile" -v c="$foundcert" -F, '{ OFS=","; if ($1 == p) { $8 = c; } print }')
|
||||||
|
newlines=$(echo "$newconfig" | awk NF | wc -l | bc)
|
||||||
|
|
||||||
|
err=""
|
||||||
|
if [[ $newlines -ne $prevlines ]]; then
|
||||||
|
err="line count different"
|
||||||
|
elif ! grep -q pin-sha256 <<<"$newconfig"; then
|
||||||
|
err="new config missing server cert"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $err ]]; then
|
||||||
|
ok
|
||||||
|
cp -p "${CONFFILE}" "${bakfile}"
|
||||||
|
echo "$newconfig" > ${CONFFILE}
|
||||||
|
curservercert="$foundcert"
|
||||||
|
else
|
||||||
|
fail
|
||||||
|
error "Regenerated config file seems wrong ($err)"
|
||||||
|
cecho -s "$RED" "Current config:"
|
||||||
|
cecho -s "$RED" "$(cat "$CONFFILE")" | sed 's/^/ /'
|
||||||
|
echo
|
||||||
|
cecho -s "$RED" "Newly generated config:"
|
||||||
|
cecho -s "$RED" "$newconfig" | sed 's/^/ /'
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
fail
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
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}"
|
||||||
|
[[ -n $curserver ]] && nstr="${nstr} server ${curserver}"
|
||||||
|
|
||||||
notify "${nstr}"
|
notify "${nstr}"
|
||||||
|
|
||||||
if [[ $curvendor == "f5" ]]; then
|
|
||||||
rm -f "$VPNPIDFILE"
|
rm -f "$VPNPIDFILE"
|
||||||
|
if [[ $curvendor == "f5" ]]; then
|
||||||
nohup sudo gof5 --server "${curserver}" --username "${curuser}" --password "${curpw}" >>${LOGFILE} 2>&1 &
|
nohup sudo gof5 --server "${curserver}" --username "${curuser}" --password "${curpw}" >>${LOGFILE} 2>&1 &
|
||||||
f5pid=$!
|
f5pid=$!
|
||||||
nlines=0
|
nlines=0
|
||||||
|
@ -286,26 +337,29 @@ elif [[ $cmd == "on" ]]; then
|
||||||
echo "$f5pid" > "$VPNPIDFILE"
|
echo "$f5pid" > "$VPNPIDFILE"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [[ -n $curgroup ]]; then
|
if [[ -n $curroutes ]]; then
|
||||||
answers="y\n${curgroup}\n${curuser}\n${curpw}\n"
|
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=anyconnect -u "$curuser" --passwd-on-stdin --authgroup="$curgroup" -s "$VPNSLICE $routesarg" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
||||||
else
|
else
|
||||||
answers="y\n${curuser}\n${curpw}\n"
|
printf '%s' "$curpw" | sudo ${OPENCONNECT} --background --non-inter --protocol=anyconnect -u "$curuser" --passwd-on-stdin --authgroup="$curgroup" --servercert "$curservercert" "$curserver" >"${LOGFILE}" 2>&1
|
||||||
fi
|
fi
|
||||||
res=$(echo -e "$answers" | ${VPN} -s connect "$PROFILE" 2>&1 | tee ${LOGFILE})
|
|
||||||
grep -q 'state: Connected' <<< "$res$"
|
|
||||||
rv=$?
|
rv=$?
|
||||||
|
res=$(cat "$LOGFILE")
|
||||||
|
if [[ $rv -eq 0 ]]; then
|
||||||
|
cpid=$(pgrep openconnect)
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
echo "$cpid" > "$VPNPIDFILE"
|
||||||
|
else
|
||||||
|
rv=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if [[ $rv -eq 0 ]]; then
|
if [[ $rv -eq 0 ]]; then
|
||||||
ok "connected"
|
ok "connected"
|
||||||
else
|
else
|
||||||
fail
|
fail
|
||||||
if [[ $curvendor == "cisco" ]]; then
|
|
||||||
error "Connection failed, logs are in ^b${LOGFILE}^p."
|
|
||||||
else
|
|
||||||
error "Connection failed, logs are below:"
|
error "Connection failed, logs are below:"
|
||||||
cecho -s "$RED" "$res" | sed 's/^/ /'
|
cecho -s "$RED" "$res" | sed 's/^/ /'
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
elif [[ $cmd == "status" ]]; then
|
elif [[ $cmd == "status" ]]; then
|
||||||
BASECOL="$ORANGE"
|
BASECOL="$ORANGE"
|
||||||
notify "Checking VPN status"
|
notify "Checking VPN status"
|
||||||
|
@ -325,21 +379,33 @@ elif [[ $cmd == "off" ]]; then
|
||||||
get_vpn_status
|
get_vpn_status
|
||||||
if [[ $vstatus == "Connected" ]]; then
|
if [[ $vstatus == "Connected" ]]; then
|
||||||
notify "Disconnecting from ${vvendor} VPN ^b${vprofile}^p"
|
notify "Disconnecting from ${vvendor} VPN ^b${vprofile}^p"
|
||||||
|
errstring=""
|
||||||
|
errdata=""
|
||||||
|
|
||||||
if [[ ${vvendor,,} == "f5" ]]; then
|
thepid=$(cat $VPNPIDFILE)
|
||||||
#sudo gof5 --server ${s} --close-session
|
if [[ -n $thepid ]]; then
|
||||||
sudo kill $(cat $VPNPIDFILE)
|
sudo kill $thepid
|
||||||
|
sleep 2 # give it some time
|
||||||
|
res=$(ps -p $thepid 2>&1)
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
rm -f "${VPNPIDFILE}"
|
rm -f "${VPNPIDFILE}"
|
||||||
rv=0
|
rv=0
|
||||||
else
|
else
|
||||||
${VPN} disconnect > ${LOGFILE} 2>&1
|
errstring="could not kill pid $thepid:"
|
||||||
rv=$?
|
errdata="$res"
|
||||||
|
rv=1
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
errstring="Cannot determine current VPN PID to kill."
|
||||||
|
rv=1
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $rv -eq 0 ]]; then
|
if [[ $rv -eq 0 ]]; then
|
||||||
ok
|
ok
|
||||||
else
|
else
|
||||||
fail
|
fail
|
||||||
error "Connection failed, logs are in ^b${LOGFILE}^p."
|
error "$errstring"
|
||||||
|
[[ -n $errdata ]] && cecho -s "$RED" "$errdata" | sed 's/^/ /'
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
fail
|
fail
|
||||||
|
|
Loading…
Reference in New Issue