|
#!/usr/bin/env bash |
|
# vim: ai ts=2 sw=2 et sts=2 ft=sh |
|
|
|
# Exit on error unless '|| true'. |
|
#set -o errexit |
|
# Exit on error inside subshells functions. |
|
set -o errtrace |
|
# Do not use undefined variables. |
|
set -o nounset |
|
# Catch errors in piped commands. |
|
set -o pipefail |
|
|
|
# Enable case-insensitive globbing |
|
shopt -s nocaseglob |
|
# Allow empty globs. |
|
shopt -s nullglob |
|
|
|
# Globals. |
|
export Z_APPNAME="Zscaler" |
|
export Z_PLUGINS="ZDP" |
|
export Z_APP="/Applications/Zscaler/Zscaler.app" |
|
export Z_BIN="${Z_APP}/Contents/MacOS/Zscaler" |
|
export Z_TNL="${Z_APP}/Contents/PlugIns/ZscalerTunnel" |
|
export Z_SRV="${Z_APP}/Contents/PlugIns/ZscalerService" |
|
|
|
## Stop Zscaler |
|
# |
|
# Prevents Zscaler from being executed or restarted by removing execute |
|
# permissions and stopping all associated services and processes. |
|
# |
|
stop () |
|
{ |
|
local _zslaunchd |
|
local _plist_file |
|
|
|
# Prevent Zscaler from being executed or restarted. |
|
echo -e "--- Disable: Zscaler app executables" |
|
sudo chmod -vv a-x "${Z_BIN}" |
|
sudo chmod -vv a-x "${Z_TNL}" |
|
sudo chmod -vv a-x "${Z_SRV}" |
|
|
|
echo -e "--- Kill: Zscaler" |
|
sudo lsof -nP -t -c "/${Z_APPNAME}|${Z_PLUGINS}/i" | xargs -I{} sudo kill -9 {} |
|
sudo launchctl list | grep -i -e "${Z_APPNAME}" -e "${Z_PLUGINS}" | cut -f 3 | xargs -I{} sudo launchctl bootout "system/{}" |
|
launchctl list | grep -i -e "${Z_APPNAME}" -e "${Z_PLUGINS}" | cut -f 3 | xargs -I{} sudo launchctl bootout "gui/$(id -u)/{}" |
|
killall "${Z_APPNAME}" 2>/dev/null || true |
|
} |
|
|
|
## Start Zscaler |
|
# |
|
# Enables Zscaler by restoring binary execute permissions and restarts the |
|
# app. A system reboot is recommended for a full service restoration. |
|
# |
|
start () |
|
{ |
|
# Allow Zscaler to be executed or restarted. |
|
echo -e "--- Enable: Zscaler app executables" |
|
sudo chmod -vv a+x "${Z_BIN}" |
|
sudo chmod -vv a+x "${Z_TNL}" |
|
sudo chmod -vv a+x "${Z_SRV}" |
|
|
|
local _zs_plist_files _plist_file |
|
|
|
echo -e "--- Kill: Zscaler app" |
|
killall "${Z_APPNAME}" 2>/dev/null || true |
|
|
|
echo -e "--- Restart: Zscaler LaunchDaemons" |
|
_zs_plist_files="$(sudo find /Library/LaunchDaemons /System/Library/LaunchDaemons -name 'com.zscaler.*.plist' 2>/dev/null)" |
|
for _plist_file in $_zs_plist_files; do |
|
_service_name="system/$(basename "${_plist_file}" ".plist")"; |
|
echo -e "--- Unload: ${_service_name}" |
|
sudo launchctl unload "${_plist_file}" || true |
|
echo -e "--- Bootstrap: ${_service_name}" |
|
sudo launchctl bootstrap system "${_plist_file}" || true |
|
echo -e "--- Kickstart: ${_service_name}" |
|
sudo launchctl kickstart -k "${_service_name}" || true |
|
done |
|
|
|
echo -e "--- Restart: Zscaler LaunchAgents" |
|
_zs_plist_files="$(sudo find /Library/LaunchAgents /System/Library/LaunchAgents -name 'com.zscaler.*.plist' 2>/dev/null)" |
|
for _plist_file in $_zs_plist_files; do |
|
_service_name="gui/$(id -u)/$(basename "${_plist_file}" ".plist")"; |
|
echo -e "--- Bootout: ${_service_name}" |
|
sudo launchctl bootout "${_service_name}" || true |
|
echo -e "--- Bootstrap: ${_service_name}" |
|
sudo launchctl bootstrap "gui/$(id -u)" "${_plist_file}" || true |
|
echo -e "--- Kickstart: ${_service_name}" |
|
sudo launchctl kickstart -k "${_service_name}" || true |
|
done |
|
|
|
echo -e "--- Open: Zscaler app" |
|
open -a "${Z_APP}" -g |
|
} |
|
|
|
## Check Zscaler status |
|
# |
|
# Displays active Zscaler network connections, running processes, and the |
|
# current execution status of its core binaries. |
|
# |
|
check () |
|
{ |
|
echo -e "--- Check: Zscaler open network connections" |
|
sudo lsof +c0 -Pi -a -c "/${Z_APPNAME}/i" |
|
echo -e "" |
|
|
|
echo -e "--- Check: Zscaler running processes" |
|
sudo lsof -nP -t -c "/${Z_APPNAME}|${Z_PLUGINS}/i" | xargs -n1 -I{} ps -p {} -o pid=,command= |
|
echo -e "" |
|
|
|
echo -e "--- Check: Zscaler app binary" |
|
local bin |
|
for bin in "${Z_BIN}" "${Z_TNL}" "${Z_SRV}"; do |
|
if [[ -x "${bin}" ]]; then |
|
echo "ENABLED: ${bin}" |
|
else |
|
echo "DISABLED: ${bin}" |
|
fi |
|
done |
|
echo -e "" |
|
echo -e "--- Check: end" |
|
echo -e "" |
|
} |
|
|
|
## Main entry point. |
|
# |
|
# Parse command-line arguments to execute script operations. |
|
# |
|
# @param $1 The operation to perform. Defaults to "help". |
|
# |
|
# @example |
|
# main "stop" |
|
# main "start" |
|
# main "help" |
|
main () |
|
{ |
|
if [[ "${1:-}" = "stop" ]]; then |
|
check |
|
stop |
|
elif [[ "${1:-}" = "start" ]]; then |
|
start |
|
else |
|
check |
|
echo "Usage: $0 [stop|start|help]" 1>&2 |
|
exit 1 |
|
fi |
|
} |
|
|
|
main "$@" |
@elykrk the script could be used outside the terminal with something like Automator for Mac, or with a Launch Daemon plist file to run at boot time (RunAtLoad) or on a set interval (StartInterval), etc.. However you choose, in all cases the script does need elevated privileges in order to do what it needs to do.
In Automator you can run a shell script with elevated privileges using
oascriptwhich will ask for a password before it runs the script. This might not work though if you don't want to enter the password every time it is run.Another option would be to configure your system's
sudoersto allow elevated privileges, just for this script, without asking for a password. This would allow you (or anyone) to run the script and not ask for a password. With that in place, you can then use Automator and not have to enter a password at all. The only thing to be careful with here, is locking down the script file itself, so nobody can edit it without your knowledge. A shell script that runs as root without a password is a dangerous thing if left open for anyone to edit.Does that help?