Last active
November 8, 2022 03:16
-
-
Save rfairburn/b078be55f0be255add27 to your computer and use it in GitHub Desktop.
Mac OS X command-line VPN Helpers
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
#!/bin/bash | |
# Source this file in your .bash_profile e.g.: | |
# | |
# source ~/gitcheckouts/vpn_heplers/.vpn_helpers.sh | |
# | |
# Note: This script works best with NOPASSWD: ALL configured in your sudoers file: | |
# /etc/sudoers: | |
# %admin ALL=(ALL) NOPASSWD: ALL | |
# | |
# Usage: | |
# | |
# vpn_connect - Connect to VPN and force DNS into place | |
# vpn_disconnect - Disconnect and reset DNS to defaults | |
# update_resolver - Force VPN DNS into place (good for already established connections) | |
# update_resolver delete - Reset DNS to defaults (good if VPN is already disconnected) | |
function obtain_service_ids { | |
scutil <<<"list" | awk -F/ '/DNS$/ { if (length($(NF-1)) == 36 ) { print $(NF-1) } }' | sort -u | |
} | |
function obtain_service_id { | |
scutil <<EOF | awk -F' : ' '/PrimaryService/ { print $2 }' | |
open | |
get State:/Network/Global/IPv4 | |
d.show | |
quit | |
EOF | |
} | |
function modify_scutil_dns { | |
declare -a DOMAINS=("${!1}") | |
shift | |
local RESOLVERS=$@ | |
sudo scutil <<EOF | |
open | |
d.init | |
d.add ServerAddresses * ${RESOLVERS} | |
$(for DOMAIN in ${DOMAINS[@]}; do echo d.add DomainName ${DOMAIN}; done) | |
set State:/Network/Service/${SERVICE_ID}/DNS | |
quit | |
EOF | |
} | |
function modify_networksetup_dns { | |
declare -a DOMAINS=("${!1}") | |
shift | |
local RESOLVERS=$@ | |
local INTERFACE="${NETWORK_INTERFACE}" | |
sudo networksetup -setsearchdomains "${INTERFACE}" ${DOMAINS[@]} | |
sudo networksetup -setdnsservers "${INTERFACE}" ${RESOLVERS} | |
} | |
function obtain_scutil_dns { | |
scutil <<EOF | awk -F' : ' 'BEGIN { resolvers = ""}; { if ($1 ~ "[0-9]$") { resolvers = resolvers OFS $2 }}; END { print resolvers }' | |
open | |
get State:/Network/Service/${SERVICE_ID}/DNS | |
d.show | |
quit | |
EOF | |
} | |
function update_resolver { | |
if [ "$1" == "delete" ]; then | |
local RESOLVERS="${DEFAULT_DNS}" | |
local DOMAINS=("${DEFAULT_SEARCH_DOMAINS[@]}") | |
else | |
local DOMAINS=("${OFFICE_SEARCH_DOMAINS[@]}") | |
local ADD_RESOLVER=${OFFICE_DNS} | |
local SCUTIL_RESOLVERS="$(obtain_scutil_dns)" | |
local RESOLVERS="${ADD_RESOLVER} ${SCUTIL_RESOLVERS/${WORK_RESOLVER}/}" | |
fi | |
# modify_scutil_dns ${RESOLVERS} | |
modify_networksetup_dns DOMAINS[@] ${RESOLVERS} | |
} | |
function vpn_disconnect { | |
scutil --nc stop "${OFFICE_VPN_NAME}" | |
update_resolver delete | |
} | |
function vpn_connect { | |
vpn_disconnect | |
scutil -t 30 --nc start "${OFFICE_VPN_NAME}" | |
COUNT=0 | |
while true; do | |
STATUS="$(scutil --nc status "${OFFICE_VPN_NAME}" | head -n1 | awk '{ print $1 }')" | |
if [ "${STATUS}" == "Connected" ]; then | |
break | |
elif [ "${COUNT}" -eq "30" ]; then | |
echo "Too many attempts, exiting." | |
break | |
else | |
echo "VPN is ${STATUS}." | |
fi | |
((COUNT++)) | |
sleep 1 | |
done | |
update_resolver | |
} | |
# Set these to "empty" for DHCP | |
export DEFAULT_DNS="empty" | |
# Use a bash array to support multiple search domains | |
export DEFAULT_SEARCH_DOMAINS=( empty ) | |
# Used in the scripts above | |
export SERVICE_ID=$(obtain_service_id) | |
# Configure these for your settings | |
export OFFICE_DNS="192.168.5.50" | |
export OFFICE_VPN_NAME="Office VPN" | |
# Use a bash style array for OFFICE_SEARCH_DOMAINS | |
export OFFICE_SEARCH_DOMAINS=( c2fo.com corp.c2fo.com ) | |
export NETWORK_INTERFACE="Wi-Fi" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment