-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvpn
More file actions
executable file
·121 lines (103 loc) · 3.19 KB
/
vpn
File metadata and controls
executable file
·121 lines (103 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/bin/sh
# Manage VPN connections via OpenConnect using credentials stored in secret-tool.
#
# Expected secret keys under SECRET_ATTR (default: UDC):
# USER -> VPN username
# PW -> VPN password
# VPN -> VPN server/portal URL
#
# For GlobalProtect, set protocol to "gp" (default below).
set -eu
PIDFILE="${PIDFILE:-/tmp/openconnect.vpn.pid}"
SECRET_ATTR="${SECRET_ATTR:-UDC}"
OPENCONNECT_PROTOCOL="${OPENCONNECT_PROTOCOL:-gp}"
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
printf 'Missing required command: %s\n' "$1" >&2
exit 1
}
}
supports_protocol() {
protocol="$1"
# openconnect -h output differs by version; match whole token where possible.
openconnect --help 2>&1 | grep -Eq "(^|[[:space:],])${protocol}([[:space:],]|$)"
}
get_secret() {
key="$1"
value=$(secret-tool lookup "$SECRET_ATTR" "$key" || true)
[ -n "$value" ] || {
printf 'Secret not found for key "%s" and attribute "%s".\n' "$key" "$SECRET_ATTR" >&2
exit 1
}
printf '%s' "$value"
}
status() {
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
printf 'Connected to VPN (pid: %s, protocol: %s).\n' "$(cat "$PIDFILE")" "$OPENCONNECT_PROTOCOL"
else
printf 'Disconnected from VPN.\n'
fi
}
up() {
require_cmd secret-tool
require_cmd sudo
require_cmd openconnect
if ! supports_protocol "$OPENCONNECT_PROTOCOL"; then
printf 'OpenConnect does not report support for protocol "%s".\n' "$OPENCONNECT_PROTOCOL" >&2
printf 'Try another protocol by setting OPENCONNECT_PROTOCOL (e.g. pulse, gp).\n' >&2
exit 1
fi
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
printf 'VPN already running (pid: %s).\n' "$(cat "$PIDFILE")"
return 0
fi
user=$(get_secret USER)
server=$(get_secret VPN)
printf 'Starting VPN connection to %s using protocol %s...\n' "$server" "$OPENCONNECT_PROTOCOL"
get_secret PW | sudo openconnect -q -b --pid-file="$PIDFILE" --protocol="$OPENCONNECT_PROTOCOL" \
-u "$user" --passwd-on-stdin "$server"
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
printf 'VPN connected to %s.\n' "$server"
else
printf 'VPN did not start successfully.\n' >&2
exit 1
fi
}
down() {
require_cmd sudo
[ -f "$PIDFILE" ] || {
printf 'You are not connected to the VPN.\n'
return 1
}
pid=$(cat "$PIDFILE")
if kill -0 "$pid" 2>/dev/null; then
printf 'Stopping VPN connection (pid: %s)...\n' "$pid"
sudo kill -2 "$pid"
else
printf 'Stale PID file found. Cleaning it up.\n'
fi
rm -f "$PIDFILE"
}
usage() {
printf 'Usage: %s {up|down|restart|status}\n' "$0"
printf 'Environment overrides:\n'
printf ' SECRET_ATTR=UDC Secret attribute/group used by secret-tool\n'
printf ' OPENCONNECT_PROTOCOL=gp OpenConnect protocol (gp for GlobalProtect)\n'
printf ' PIDFILE=/tmp/openconnect.vpn.pid\n'
}
case "${1:-}" in
up|start|open) up ;;
down|stop|close) down ;;
restart|reload)
down || true
up
;;
status) status ;;
help|-h|--help)
usage
;;
*)
usage
exit 1
;;
esac