Juniper SSL VPN / Pulse Connect Secure

Support for Juniper's Network Connect protocol was added to OpenConnect in early 2015, for the 7.05 release. It is still experimental, and is quite likely to be deprecated in favour of the newer Junos Pulse protocol.

For the time being, Juniper mode is requested by adding --juniper to the command line:

  openconnect --juniper vpn.example.com

Network Connect works very similarly to AnyConnect — initial authentication is made over HTTP, resulting in an HTTP cookie which is used to make the actual VPN connection. That connection is also made over HTTP, and the IP address and routing information are provided by the VPN server. The client then attempts to bring up a UDP transport, which in the case of Juniper is ESP.

Authentication

The authentication stage with Juniper is what is expected to cause most problems. Unlike AnyConnect which has a relatively simple XML schema for interacting with the user, the Juniper VPN expects a full web browser environment and uses HTML forms with JavaScript and even full-blown Java support.

The common case is relatively simple, and OpenConnect supports the common forms defined by the Juniper-provided templates. However, administrators have the facility to put arbitrary HTML pages into the login sequence and full compatibility may require actually using a web browser to log in — ironically, since much of the reason users have been asking for OpenConnect to support Juniper is because they didn't want to have to use a web browser.

For NetworkManager we may end up putting a full HTML renderer into the GUI authentication dialog, while the command line client continues to parse the common login forms and make a best attempt at handling anything non-standard.

External authentication

There are a number of perl and python scripts which handle authentication to Juniper servers to bypass the web browser. One such script has been ported to invoke OpenConnect instead of Juniper's own ncsvc client and can be found here.

Any of these scripts which authenticate and obtain a DSID cookie representing a VPN session can be used with OpenConnect. Just pass the cookie to OpenConnect with its -C option, for example:

  openconnect --juniper -C "DSID=foobar12345" vpn.example.com

Host Checker (tncc.jar)

Many sites require a Java applet to run certain tests as a precondition of authentication. This works by sending a DSPREAUTH cookie to the client which is attempting to authenticate, and the Java code in tncc.jar then runs and communicates with the server, handing back a new value for the DSPREAUTH cookie to be used when autnentication continues.

OpenConnect supports this with a little assistance. There is a python script tncc-wrapper.py in the git repository which can be used along with the tncc-preload.so from this repository. It may also be necessary to pass a Mozilla-compatible user agent string:

  ./openconnect --juniper --useragent  'Mozilla/5.0 (Linux) Firefox' --csd-wrapper=./tncc-wrapper.py vpn.example.com

Connectivity

Once authentication is complete, the VPN connection can be established. At the time of writing much of the configuration for Legacy IP addressing and routes is understood and implemented. IPv6 is not yet implemented, and test reports from someone with an IPv6-capable server would be greatly appreciated.

The data transport is functional both over the HTTPS session and also over ESP. Servers with compression enabled should also be supported, as LZO decompression is working and although we lack compression support it appears acceptable to simply send packets uncompressed.

At the time of writing, keepalive for the ESP connection has been implemented and extremely lightly tested, while it isn't yet known if the VPN supports keepalive on the HTTPS connection. Reconnection of both the HTTPS and ESP links is implemented. The current implementation is basically usable and is definitely ready for some more widespread testing.