OpenConnect Launch Daemon
Eric Bailey
Written on 17 June, 2019
Tags: darwin, vpn, openconnect, launchd, daemon
What follows is a sparsely documented literate program to manage an OpenConnect
VPN connection with launchd
on macOS. Many thanks to Ashley Gilman for their
blog post, Managing an Openconnect VPN Connection with launchd on OSX, upon
which this is based.
OpenConnect Wrapper
Define a function handler
to send an INT
signal to $PID
, then trap
TERM
signals and call handler
instead, which will enable ending an
openconnect
process gracefully with launchd
.
handler() { kill -INT "$PID" 2>/dev/null } trap handler SIGTERM
Pipe STDIN
and pass any given arguments to /usr/local/bin/openconnect
, and
send to the background.
cat | /usr/local/bin/openconnect "$@" &
Keep the wrapper process alive as long as the openconnect
process is, by
capturing its PID and wait
-ing for it.
PID=$! wait "$PID"
Password File
Store the password (without a trailing newline) in a file,
/etc/openconnect/passwd
, owned by root
.
Remove read/write access from all but root
.
sudo chmod og-rw /etc/openconnect/passwd
Launch Daemon
Set up a launch daemon by creating a property list file,
/Library/LaunchDaemons/me.ericb.openconnect.plist
.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>me.ericb.openconnect-example</string>
Specify that the password, stored in /etc/openconnect/passwd-example
, will be
supplied via stdin.
<key>StandardInPath</key> <string>/etc/openconnect/passwd-example</string>
Use the wrapper defined above.
<key>ProgramArguments</key> <array> <string>/etc/openconnect-wrapper</string>
Tell openconnect
we're supplying the password via stdin.
<string>--passwd-on-stdin</string>
Set the OpenConnect protocol to AnyConnect.
<string>--protocol=anyconnect</string>
Set the reconnect timeout to 1800
seconds.
<string>--reconnect-timeout=1800</string>
Set the username.
<string>--user=alice</string>
Finally, specify the VPN server hostname.
<string>vpn.example.com</string> </array>
Configure log files for debugging.
<key>StandardOutPath</key> <string>/var/log/me.ericb.openconnectconsole.log</string> <key>StandardErrorPath</key> <string>/var/log/me.ericb.openconnect/error.log</string>
Close the open XML tags.
</dict> </plist>