Like many here, I remote into networks to work. I access organization X's network using Cisco's AnyConnect VPN client because that is what they use. When I first got involved, they told me to login to a given url in their webserver and get the client for my machine (a MacBook Air if you are curious; I do need to get a new Linux laptop but the Mac has been working great so far). Probably if my machine machine was a company-owned laptop they would have pushed the packaged using SCCM/Chocolatey (Windows) or Casper(now called jamf)/Munki (Mac). Or ansible, but that is another bag of cats. In any case, the point is I got their package, which was configured to work on their VPN. And, it works: double-click on the silly link, connect, enter my authentication info, and off I go.
Now also need to access organization B's machines. And they also chose to use AnyConnect. And just like X they also told me to install their package. Thing is if I do that it will wipe the X configuration, which would get annoying very quickly. I did try seeing if there was a way to add another profile from the client's menu but not luck. Maybe each company disabled the option so you can only use it to access their network; I do not know. Now what I could do since this is a Mac is rename Company X's VPN folder to, say, Cisco.Old (the default folder name is Cisco and then install Company B's VPN package.
This way, if I need to go to X, I would open Cisco.Old and then run that vpn client. If I then wanted to go to B, I would quit the client, go to Cisco, and then run that client. I do not know about you, but that looks a bit cumbersome to me. And, if my laptop was running Windows, I think it would not let me install 2 instances of the client that easily. There has to be a better way.
First of all, let's assume there is a configuration file somewhere for the AnyConnect VPN client. Since I am using OSX, chances are it has some plist-sounding name. And I found something called com.cisco.Cisco-AnyConnect-Secure-Mobility-Client.plist in my preferences folder, /Users/raub/Library/Preferences, but it does not look particularly legible from the command line (yes, I know there is probably an app to do that but I like to do things from the command line):
So we make a copy of it and then run
plutil -convert xml1 com.cisco.Cisco-AnyConnect-Secure-Mobility-Client.plistto convert it to something more legible, and then look inside it:
boris:~ raub$ cat com.cisco.Cisco-AnyConnect-Secure-Mobility-Client.plist
boris:~ raub$ UILogLocation /Users/raub/.cisco/vpn/log/UIHistory_2016.12.12.13.41.31.883.txt /Users/raub/.cisco/vpn/log/UIHistory_2016.12.12.13.58.40.264.txt /Users/raub/.cisco/vpn/log/UIHistory_2016.12.12.14.15.56.295.txt /Users/raub/.cisco/vpn/log/UIHistory_2017.02.14.06.03.40.692.txt /Users/raub/.cisco/vpn/log/UIHistory_2017.07.24.21.43.25.742.txt
Hmmm, that does not look like what I want. Maybe the AnyConnect client has a global configuration file somewhere. And it does, and it is called glvpn-anyconnect-profile.xml and is located in /opt/cisco/anyconnect/profile/:
boris:~ raub$ ls /opt/cisco/anyconnect/profile/ AnyConnectProfile.xsd glvpn-anyconnect-profile.xml boris:~ raub$
If we look into it, this xml file starts as expected with some system-wide config settings
cat /opt/cisco/anyconnect/profile/glvpn-anyconnect-profile.xml <?xml version="1.0" encoding="UTF-8"?> <AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/encoding/ AnyConnectProfile.xsd"> <ClientInitialization> <UseStartBeforeLogon UserControllable="true">false</UseStartBeforeLogon> <AutomaticCertSelection UserControllable="true">true</AutomaticCertSelection> <ShowPreConnectMessage>false</ShowPreConnectMessage> <CertificateStore>All</CertificateStore> <CertificateStoreOverride>false</CertificateStoreOverride> <ProxySettings>Native</ProxySettings> <AllowLocalProxyConnections>true</AllowLocalProxyConnections> <AuthenticationTimeout>60</AuthenticationTimeout> <AutoConnectOnStart UserControllable="true">false</AutoConnectOnStart> <MinimizeOnConnect UserControllable="true">true</MinimizeOnConnect> <LocalLanAccess UserControllable="true">true</LocalLanAccess> <ClearSmartcardPin UserControllable="true">true</ClearSmartcardPin> <IPProtocolSupport>IPv4,IPv6</IPProtocolSupport> <AutoReconnect UserControllable="true">true
But then get to the part we have been anxiously waiting for: how to access company X's vpn:
<ServerList> <HostEntry> <HostName>Company X VPN</HostName> <HostAddress>vpn.companyx.com</HostAddress> </HostEntry> </ServerList> </AnyConnectProfile>
It does not look very complicated to me: we probably could just add a new HostEntry for Company B, as in
<ServerList> <HostEntry> <HostName>Company X VPN</HostName> <HostAddress>vpn.companyx.com</HostAddress> </HostEntry> <HostEntry> <HostName>Company B VPN</HostName> <HostAddress>vpn.b-company.com</HostAddress> </HostEntry> </ServerList> </AnyConnectProfile>
and be done. And that will work. But, I think we can do one better; can we avoid cluttering the profile file? Long story short is yes. Just put something like this
cat > B-profile.xml << 'EOF' <?xml version="1.0" encoding="UTF-8"?> <AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/encoding/AnyConnectProfile.xsd"> <!-- This section contains the list of hosts the user will be able to select from. --> <ServerList> <!-- This is the data needed to attempt a connection to a specific host. --> <HostEntry> <!-- Can be an alias used to refer to the host or an FQDN or IP address. If an FQDN or IP address is used, a HostAddress is not required. --> <HostName>Company B VPN</HostName> <HostAddress>vpn.b-company.com</HostAddress> </HostEntry> </ServerList> </AnyConnectProfile>
boris:~ raub$ ls /opt/cisco/anyconnect/profile/ AnyConnectProfile.xsd glvpn-anyconnect-profile.xml B-profile.xml boris:~ raub$
Now when we run the client, we can select either company's VPN:
What about Windows
I've never tried but there is a file called (starting at your homedir) .\AppData\Local\Cisco\Cisco AnyConnect Secure Mobility Client\preferences.xml which would be my starting point. The global profile folder is c:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Profile.
I do not like that I have to configure the different profiles at the global level; I might share this laptop with other people and would like to have my profiles uncluttered away from theirs. But, at least now I can use multiple profiles to access different networks. Looking at the Windows configuration file, I wonder if I can do that int he Mac too. That will be the subject for another article.