OpenConnect

From ArchWiki

OpenConnect is a client for Cisco's AnyConnect SSL VPN[dead link 2022-09-22 ⓘ] and Pulse Secure's Pulse Connect Secure.

Installation

Install the openconnect package.

Usage

See openconnect(8). Simply run openconnect as root and enter your username and password when prompted:

# openconnect vpnserver

More advanced invocation with username and password. Input the password after running the command.

# openconnect -u user --passwd-on-stdin vpnserver

Often VPN providers are offering different authentication groups for different access configurations like for example for a full tunnel or split tunnel connection. To show the different offered auth-groups and to get more information about the connection to the server in general use:

# openconnect --authenticate vpnserver

Sometimes, connecting to a Cisco VPN, the CSD (Cisco Secure Desktop) mechanism is required (see: https://www.infradead.org/openconnect/csd.html). In that case using the "--csd-wrapper" parameter can help, the wrappers are stored under "/usr/lib/openconnect/".

# openconnect --csd-wrapper=/usr/lib/openconnect/csd-post.sh vpnserver

Juniper Pulse Client

In order to connect to a Pulse Connect Secure server you need to know the SHA-1 of its certificate.

# openconnect --servercert=sha1:<HASH> --authgroup="single-Factor Pulse Clients" --protocol=nc <VPN_SERVER_ADDRESS>/dana-na/auth/url_6/welcome.cgi --pid-file="/var/run/work-vpn.pid" --user=<USERNAME>

GlobalProtect

Connecting to a GlobalProtect VPN server where the address is usually "https://vpn.your-domain.tld", simply do

# openconnect --protocol=gp <VPN_SERVER_ADDRESS>

Some VPN server requires you to use the alternative address

# openconnect --protocol=gp <VPN_SERVER_ADDRESS>/gateway

also your VPN might require you to generate a HIP report (gathers information about your computer), you can do that by passing in

# openconnect --csd-wrapper /usr/lib/openconnect/hipreport.sh --protocol=gp <VPN_SERVER_ADDRESS>/gateway

Split routing

Split routing can be achieved using vpn-slice-gitAUR in place of vpnc-script, so that you can selectively access hosts over the VPN but otherwise remain on your own LAN. Example:

   sh
   # openconnect gateway.bigcorp.com -u user1234 \
       -s 'vpn-slice 192.168.1.0/24 hostname1 alias2=alias2.bigcorp.com=192.168.1.43'
   $ cat /etc/hosts
   ...
   192.168.1.1 dns0.tun0					# vpn-slice-tun0 AUTOCREATED
   192.168.1.2 dns1.tun0					# vpn-slice-tun0 AUTOCREATED
   192.168.1.57 hostname1 hostname1.bigcorp.com		# vpn-slice-tun0 AUTOCREATED
   192.168.1.43 alias2 alias2.bigcorp.com		# vpn-slice-tun0 AUTOCREATED

Integration

NetworkManager

Install the networkmanager-openconnect package, then restart NetworkManager.service.

Configure and connect with nm-applet (NetworkManager's icon tray utility from network-manager-applet) or similar utility.

See NetworkManager for details.

netctl

A simple tuntap netctl.profile(5) can be used to integrate OpenConnect in the normal Netctl workflow. For example:

/etc/netctl/vpn
Description='VPN'
Interface=vpn
Connection=tuntap
Mode=tun
#User=root
#Group=root

BindsToInterfaces=(enp0s25 wlp2s0)
IP=no

PIDFILE=/run/openconnect_${Interface}.pid
SERVER=vpn.example.net
AUTHGROUP='<AUTHGROUP>'
LOCAL_USERNAME=<USERNAME>
REMOTE_USERNAME=<VPN_USERNAME>
# Assuming the use of pass(1): 
PASSWORD_CMD="su ${LOCAL_USERNAME} -c \"pass ${REMOTE_USERNAME} | head -n 1\""

ExecUpPost="${PASSWORD_CMD} | /usr/bin/openconnect --background --pid-file=${PIDFILE} --interface='${Interface}' --authgroup='${AUTHGROUP}' --user='${REMOTE_USERNAME}' --passwd-on-stdin ${SERVER}"
ExecDownPre="kill -INT $(cat ${PIDFILE}) ; resolvconf -d ${Interface} ; ip link delete ${Interface}"

This allows execution like:

$ netctl start vpn
$ netctl restart vpn
$ netctl stop vpn

Note that this relies on LOCAL_USERNAME having a gpg-agent running, with the passphrase for the PGP key already cached.

If pass's interactive query is wanted, use the following line for PASSWORD_CMD:

DISPLAY=":0"
PASSWORD_CMD="su ${LOCAL_USERNAME} -c \"DISPLAY=${DISPLAY} pass ${REMOTE_USERNAME} | head -n 1\""

Adjust the DISPLAY variable as necessary.