After moving to a new office location, a lot changed – including the network setup. Different than before, we have to use Cisco AnyConnect now to connect to the VPN. Still, there are different VPNs depending on what I’m working on but everything else is quite different.
First of all, this means I can neither use
scutil which I have used in my previous script to manage my VPN any longer.
For obvious reasons, this means my script suddenly became useless.
My personal requirement is still the same, though: I want to be able to connect to any of the VPNs from the command line (and also disconnect again), without having to enter a password. The password should be retrieved from the keychain.
The good news: The Cisco AnyConnect client comes with a command line interface:
Nevertheless, I want it to work exactly as before.
This means: I want using the VPN to be as easy as this:
$ vpn list $ vpn connect "myVPN" $ vpn status "myVPN" $ vpn disconnect "myVPN"
Drawback using Cisco AnyConnect
The AnyConnect CLI requires quite some arguments to connect to the VPN:
- group ID
- user name
Unfortunately, this does not align with what previously was either configured for the VPN or stored in the keychain, i.e., we will not be able to connect using just some name of a configured VPN.
For instance, the following command could be used to connect to a VPN:
$ /opt/cisco/anyconnect/bin/vpn -s connect myvpn.example.com <<"EOF" 1 myUserAccount@myVPN mySuperStrongPassword y exit EOF
Be aware that, when used in a script, this will print your password in clear text to the terminal.
I found no way around this, in some way the passwort, etc. was always printed.
So it is really recommended to eventually hide the output from the command by passing it on to
/dev/null, which is, for sure, less than ideal.
In order to make this work with some name like
myVPN as before,
we either need to add some hardcoded stuff to our script, or we add a configuration file similar to the
~/.ssh/config for instance.
Set up a VPN Configuration File
Let’s really use the SSH config at
~/.ssh/config as an example, and create a config file for our VPNs at
$ mkdir ~/.vpn $ touch ~/.vpn/config
Then, add something like the following to this file:
VPN myVPN GroupId 1 User myUserAccount@myVPN Host myvpn.example.com
You will find the
GroupId values to use when you start to connect to a VPN via AnyConnect CLI manually:
$ /opt/cisco/anyconnect/bin/vpn connect myvpn.example.com Cisco AnyConnect Secure Mobility Client (version 4.6.00362) . Copyright (c) 2004 - 2018 Cisco Systems, Inc. All Rights Reserved. >> state: Disconnected >> state: Disconnected >> notice: Ready to connect. >> registered with local VPN subsystem. >> contacting host (myvpn.example.com) for login information... >> notice: Contacting myvpn.example.com. >> Please enter your username and password. 0) anycon 1) myVPN Group: [myVPN]
You should see some similar output as in the snippet above.
With the config file at
~/.vpn/config we have everything in place to create the VPN connection utility we aim for.
The only missing piece is the password which we will add to the Keychain next.
Add the VPN Account Password to the Keychain
At first, we will make sure to have the new credentials available in the login keychain:
$ security add-generic-password \ -D "VPN account password" \ -s "myVPN" \ -a "myUserAccount@myVPN" \ -w "mySuperStrongPassword" \ -T "/usr/bin/security"
-aspecifies your VPN account name (required)
-Dspecifies the kind of the keychain entry (optional, default is “application password”)
-sspecifies the service name (the name of the keychain entry, required)
-Tspecifies an application which may access the keychain entry (multiple
-Toptions are possible)
-wspecified your VPN account password
-s option should match the VPN name from your configuration file because we will use it to retrieve the account password from the keychain.
Create a new Utility Script
Next, we will create a utility script that uses the keychain entry we just created:
$ echo '#!/bin/bash' > ~/.vpn/anyVpnConnection.sh && chmod +x ~/.vpn/anyVpnConnection.sh
Open the script in an editor, and add this code:
With that script, you can particularly use a convenient command to connect to a VPN identified by a configured name and reading the password from the keychain:
$ ~/.vpn/anyVpnConnection.sh connect "myVPN"
Besides that, the
stats command from AnyConnect basically is aliased as
Every other command will just be passed on to the original AnyConnect CLI.
Thus, the capabilities are a bit different than with the previous utility script, and the only actual addition is the more convenient way to connect to a VPN.
In my mind, that is still worth it, the basic requirements are fulfilled.
Set an Alias
In order to make it yet another bit nicer and more convenient,
we also add an alias so that we can type
vpn instead of
Add the following line to the configuration of your shell, e.g.,
Now, using VPN connections is as easy as this:
$ vpn connect "myVPN" $ vpn status $ vpn info $ vpn disconnect