Using OpenConnect to Replace Global Protect VPN
Recently while working with some clients, I've encountered the prerequisite of being connected to their VPN network - whether to access their Git server or simply to reach resources that aren't public for security and privacy reasons. Here's where the problem comes in: one popular VPN solution used in the industry is provided by Palo Alto Networks, more specifically Global Protect. The issue is with the client itself.
The Problem with Global Protect
The Global Protect client has several issues with performance and GUI experience. For some reason, it feels unnecessarily bloated and the client installation weighs in at 120.8MB - for a simple VPN client, this feels excessive.
Another reason I prefer alternatives is that I like using the terminal in my daily workflow. So why shouldn't I connect to the VPN using the terminal? It's a cleaner way to do it, avoiding unnecessary use of memory and storage compared to a GUI client.
Enter OpenConnect
This is where OpenConnect comes in - a terminal client to connect to VPN networks. It works with different protocols, including Palo Alto and other protocols commonly used in the industry.
Installation
Here's a quick guide to get started. For macOS, you only need to use Homebrew:
brew install openconnect
Basic Usage
To connect to the VPN, you need to specify two parameters: the protocol and the server URL. For example:
sudo openconnect --protocol=gp vpn.example.com
Then it will ask for your credentials and you'll be connected. Simple and fast.
Split Tunneling with vpn-slice
Something very useful when using OpenConnect is the capability to pass traffic to a "script" program (as described in the documentation). This is especially interesting if you want to split the connection and redirect VPN traffic only to certain IPs or domains. This is where vpn-slice comes in - a useful script for OpenConnect that enables split-tunneling.
It can be installed just as we installed OpenConnect:
brew install vpn-slice
Now, let's say I want to connect as before, but suppose there's a Git server on this network and that's the only connection I want through the VPN. For example, if I'm watching videos on the internet, I don't want to stress the VPN server with that traffic - I only want to route connections for the Git server.
Let's say the Git server is at repo.example.com. We can use OpenConnect together with vpn-slice like this:
sudo openconnect --protocol=gp vpn.example.com -s 'vpn-slice repo.example.com'
Just like that! Now we have a VPN connection that only routes traffic for this hostname through the VPN network. We can also use IPs and create aliases - check out the official vpn-slice documentation for more complex scenarios.
Using Configuration Files
We can add more parameters to our connection, such as --servercert, --user, and --quiet. But we can go one step further and write a config file where all these arguments are stored. This way, we can create multiple config files for different connections.
For example, let's create a config file for our example.com connection:
example-vpn.conf
protocol=gp
server=vpn.example.com
user=myusername
script=vpn-slice repo.example.com
servercert=pin-sha256:xxxxxxxxxxxxx=
quiet
To use this config file, we add the --config parameter:
sudo openconnect --config=example-vpn.conf
This approach to OpenConnect works very well for most use cases.
Handling SAML/SSO Authentication
Now... what happens if the protocol requires SAML/SSO as part of the authentication? OpenConnect has the capability to manage this auth flow, but it's not ideal. The community has created an alternative called gp-saml-gui which helps automate this flow and allows connection through OpenConnect.
To install gp-saml-gui on macOS, you can use Homebrew based on the lkrms repository:
brew install lkrms/misc/gp-saml-gui
Here's an example of using gp-saml-gui, which will open your browser to authenticate with your designated provider (Microsoft, Google, etc.), and once authentication passes, it executes OpenConnect with the necessary tokens and data:
gp-saml-gui --gateway --allow-insecure-crypto --no-verify --sudo-openconnect vpn.example.com -- -s 'vpn-slice repo.example.com'
Notice that we can pass parameters to the OpenConnect command that will be executed after authentication. For example, we used the -s parameter here, but you can add parameters like --user or even use --config. However, for this case using --config doesn't make much sense since we're specifying the server domain explicitly when using gp-saml-gui.
Final Thoughts
OpenConnect provides a lightweight, flexible alternative to bulky GUI VPN clients. With split-tunneling capabilities and configuration file support, it's become an essential tool in my terminal-based workflow. Give it a try if you're looking for a more efficient way to manage your VPN connections.