Skip to content

Instantly share code, notes, and snippets.

@dchakro
Last active October 1, 2024 01:06
Show Gist options
  • Save dchakro/d6c8480ca00680cf9d9d951c4fdb6ed0 to your computer and use it in GitHub Desktop.
Save dchakro/d6c8480ca00680cf9d9d951c4fdb6ed0 to your computer and use it in GitHub Desktop.
CiscoVPN_splittunneling in MacOS without using Cisco Anyconnect

Split tunneling with Cisco Anyconnect VPN in CLI with minimal overhead

Cisco Anyconnect VPN is a popular enterprise VPN and is unfortunately the choice of my current workplace (instead of openVPN) 🤦‍♂️

This gist aims to alleviate these 3 issues I have Cisco's Anconnect Mobility client:

  1. On my Mac machines, it has a significant overhead (as compared to the solution in this gist)

  2. I ditched Anyconnect client wayback when I discovered that it installs and runs in the background as a daemon even if you exit the program. The battery takes a hit and it used to cause wakelocks on my macbook and cause the battery to die overnight, while my laptop was resting on the table with the lid closed.

    sudo launchctl unload /Library/LaunchDaemons/com.cisco.anyconnect.vpnagentd.plist this command was a life savior. But I got tired of having to remember running it again and again.

  3. Minor concern: Propreitary nature of Cisco's client

This script opens a tmux session to let openconnect establish a link to your work place VPN, while having the option of split-tunneling (using vpn-slice):

  1. To some designated IPs

  2. To the entire work subnet

  3. No split-tunneling, e.g. all traffic is routed via your workplace's Cisco VPN.

#!/usr/bin/env sh
# --- Install essential utilities for this script to work
# Homebrew - package manager for Mac
command -v brew >/dev/null 2>&1 || { curl -fsSL 'https://raw.githubusercontent.com/Homebrew/install/master/install.sh' | bash }
# OPTIONAL but useful:
# brewlog: a shell utility to maintain a local log file of all homebrew acivity.
# https://github.com/dchakro/brewlog
# If you don't want to use brewlog, just Find & Replace-All "brewlog" with "brew" in this script.
command -v brewlog >/dev/null 2>&1 || { curl -sSL 'https://raw.githubusercontent.com/dchakro/brewlog/master/install.sh' | bash }
# tmux : Terminal multiplexer
# https://github.com/tmux/tmux
command -v tmux >/dev/null 2>&1 || brewlog install tmux
# Openconnect: FOSS VPN client, for Cisco AnyConnect VPNs and others
# https://gitlab.com/openconnect/openconnect
command -v openconnect >/dev/null 2>&1 || brewlog install openconnect
# vpn-slice: Easy and secure split-tunnel VPN setup
# https://github.com/dlenski/vpn-slice
command -v vpn-slice >/dev/null 2>&1 || brewlog install vpn-slice
# ---- Define colors
RED='\033[91m'
GREEN='\033[92m'
NC='\033[0m'
# Define functions
CHECK_STATUS()
{
result=`ps -ax | grep -c '[o]penconnect'`
}
PRINT_STATUS()
{
CHECK_STATUS
if [ $result -ne 0 ]; then
echo "Status (openconnect): ${GREEN}Running${NC}. Connected to $(tmux list-sessions | grep VPN | awk {'print $1'} | tr ':' ' ' )"
else
echo "Status (openconnect): ${RED}Not running${NC}."
fi
}
# --- Core part of the script
while true
do
printf '
-------: Menu :--------
1) SSH Hosts only
2) Entire UTU subnet
3) All traffic
4) Connection status
5) Terminate VPN
6) Exit
Enter: ';
read var;
echo ""
case $var in
1)
PRINT_STATUS
if [ $result -ne 0 ]; then
echo "Here is the process info"
ps -ax | grep '[o]penconnect'
echo "Please terminate (using option #4) to try again."
else
# Connect only to specific hosts (specified by IP, here you can also use hostname, check out the manual for vpn-slice)
tmux new-session -s VPN_myHosts "sudo -k openconnect 'https://vpn.work.place.com' -u username -s 'vpn-slice 192.168.251.49 192.168.51.5'"
fi
;;
2)
PRINT_STATUS
if [ $result -ne 0 ]; then
echo "Here is the process info"
ps -ax | grep '[o]penconnect'
echo "Please terminate (using option #4) to try again."
else
# Connect to entire work subnet
tmux new-session -s VPN_UTU "sudo -k openconnect 'https://vpn.work.place.com' -u username -s 'vpn-slice 192.168.0.0/16'"
fi
;;
3)
PRINT_STATUS
if [ $result -ne 0 ]; then
echo "Here is the process info"
ps -ax | grep '[o]penconnect'
echo "Please terminate (using option #4) to try again."
else
# Pass all of the traffic through work VPN, useful for retreiving journal articles etc.
tmux new-session -s VPN_All_traffic "sudo -k openconnect 'https://vpn.work.place.com' -u username"
fi
;;
4)
PRINT_STATUS
;;
5)
PRINT_STATUS
if [ $result -ne 0 ]; then
ps -ax | grep '[o]penconnect' | awk '{print $1}' | xargs sudo -k kill -INT && sleep 1.5 && PRINT_STATUS
if [ $result -ne 0 ]; then
echo "${RED}Unsuccessful${NC} in terminating. Please kill these processes manually:"
ps -ax | grep '[o]penconnect'
continue
fi
else
echo "Can't terminate if the VPN isn't running."
fi
;;
6)
echo "Bye"
exit 0
;;
*)
echo
echo "Valid range of choices [1-5]."
echo "Try again..."
echo
sleep 0.5
continue
esac
done
exit 0
@niasie
Copy link

niasie commented Oct 1, 2024

Thank you so much for this extremely helpful script!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment