The organization I work for uses a Cisco ASA VPN network appliance for managing
remote VPN access to the internal network. This is a common and popular choice
for many organizations. When you access it remotely for the first time, it
wants to detect your platform and then download and install the AnyConnect
Secure Mobility Client. This client application is how you then connect and
authenticate your VPN connection. Our organization assumes that everyone in
the world uses Microsoft Windows all the time. Of course, why not?
Anyway, the Java-based client and installer do not work too well on Linux
for some reason. And our organization in particular is not too keen on helping
anyone who is not using Windows. They do not prohibit the use of Linux or other
operating systems, but they will not help you with them either.
So a couple years ago, whatever black magic they had been performing to make
Linux clients work stopped. Our team uses Linux and we were suddenly locked out
of VPN access. And they did not care despite out best pleading. In fact, their
final, formal answer on the matter was to "just use Windows". Nice. Thanks.
So we started digging around the interwebs and found that a lot of other Linux
users had the same story in regards to the Cisco AnyConnect client. And some of
them had gotten fed up enough to devise their own solution. We discovered a
project called 'openconnect'. This is an open-source program that is compatible
with the Cisco VPN appliance.
OpenConnect is not part of most Linux distros including RHEL, but you can now
get an rpm from EPEL. You can also build it from source if you desire.
OpenConnect uses OpenSSL which must be able to validate the signing chains on al
l the certificates involved. Our organization uses smart cards with security
certificates, so a VPN connection involves you presenting a client-side SSL
certificate. This means you need to have all the signing certificates up to the
root installed in your local store.
These go under the /etc/pki/ca-trust/source/anchors directory.
You simply copy the .cer certificate files there and then update using the
'update-ca-trust' command.
Then the command line to use openconnect looks like this.
You will need root privilege.
sudo openconnect -c 'pkcs11:token=LAST.FIRST.MIDDLE.number;id=%02' https://vpn.foo.org
It prompts for the sudo password and then for the PIN on the smart card and
then it connects.
One tricky point is the 'pkcs11' parameter. You need to see exactly what your
token name and id number on the card are so you can reference them to the
openconnect command parameters.
With your card inserted, you can use 'p11tool' to get a list of all the
specific certificates on the card and their 'id' values.
p11tool --list-tokens
p11tool --list-all-certs pkcs11:token=LAST.FIRST.M.123456789
It should list some number of "objects", which are the certificates on your
card. If you don't know which one of these the VPN is expecting for
authentication, you can always use some trial-and-error experimenting.
There are not so many on there that this is prohibitive.
Now look at the 'ID' field for that object, e.g. "00:02".
You need to replace the "00:02" with "%02" in the 'id' portion of the pkcs11
string.
If you get the 'id=' syntax wrong, you will get some non-obvious errors from
openconnect and then a WebVPN cookie error and no connection.
We also ran into difficulty with some applications communicating over the VPN.
The problem is that the VPN tunnel uses DTLS over UDP. This requires a little
overhead for some protocol headers and starts eating up your MTU.
Your application has no idea it's using a somewhat limited connection and does
not account for this. So if its protocol also has some headers, you may have to
tweak the MTU down to account for that.
You can tweak the MTU on the tun0 device established by openconnect.
sudo ip link set mtu 1402 dev tun0
An example is newer versions of OpenSSH whose key exchange algorithms have
rather large payloads. When these get fragmented over the DTLS/UDP connection
while communicating with an older version of OpenSSH on the server side,
something goes wrong, the key exchange stalls, times out and then fails.
You can edit the SSH config to not offer so many choices in the key exchange,
but it is simpler to bump the MTU down until it's happy. This is easily done by iterative experiments until it works.
No comments:
Post a Comment