4.3.4.2 VPN Recipes
We advise that OpenCRVS be hosted behind a government VPN and that all staff that access OpenCRVS use a VPN Client to connect before browsing to OpenCRVS. This keeps OpenCRVS from being on the public internet. Mobile device management (MDM) solutions can be used to deploy and configure VPN clients on staff devices to mitigate this challenge at scale. The Digital Public Good, "DHIS2" has this excellent documentation on MDM.
VPN is government wide networking security infrastructure, and its selection and configuration is outside the scope of the OpenCRVS platform.
This page documents "recipes". Code snippets that we have used in the past to connect to different kinds of VPN programmatically from Github Actions - where the environment "provision" user is a virtual staff member with VPN client access details. Your networking team may be required to assist you debug the provision user's VPN connection depending on your unique government network requirements.
OUTBOUND
When connected to your VPN, users should have outbound internet access. But in some cases, governments restrict this. Refer to the list of required domains that must be whitelisted in section 4.3.1 Verify servers
INBOUND
OpenCRVS uses Github Actions to connect through your VPN. Github publishes the following IP addresses which you should ensure can access as a VPN Client.
The URL to your country logo which appears in HTML emails should be accessible from the public internet.
The following Github Action workflows require to be amended for the "provision" user to connect to your VPN:
.github/workflows/clear-environment.yml
.github/workflows/deploy-prod.yml
.github/workflows/deploy.yml
.github/workflows/provision.yml
.github/workflows/reset-2fa.yml
.github/workflows/seed-data.yml
Place your required snippets for the steps you need at the beginning of the workflows, before any connection attempt is made, such as immediately after the repository is cloned. E.G. here.
Openconnect compatible VPN
The following VPN providers are compatible with openconnect which allows you to programatically connect in the Github Action.
openconnect compatible VPNs are:
Cisco AnyConnect (--protocol=anyconnect)
Array Networks SSL VPN (--protocol=array)
Juniper SSL VPN (--protocol=nc)
Pulse Connect Secure (--protocol=pulse)
Palo Alto Networks GlobalProtect SSL VPN (--protocol=gp)
F5 Big-IP SSL VPN (--protocol=f5)
Fortinet Fortigate SSL VPN (--protocol=fortinet)
The snippet below is a basic example of how to use openconnect to access a compatible VPN.
To use this snippet, you must also manually create 2 additional environment secrets in Github that are not automatically generated by our Create Github Environment script as they are custom to this approach.
Secret name | Notes |
---|---|
A string compatible with openconnect to understand which VPN provider you are using. E.G. | |
Refer to note below the snippet for an explanation regarding this secret. |
Github Action workflow snippet:
When using openconnect
, you will need to retrieve the server's certificate (often referred to as --servercert
) to ensure that you're connecting to the correct VPN server.
To retrieve the existing --servercert
(the server's SSL certificate) as an OpenConnect client, you can follow these steps:
1. Use OpenConnect with Verbose Output
Run openconnect
with the --verbose
flag to display detailed information about the connection process, including the server's certificate.
Enter your VPN password when prompted. During the connection process, OpenConnect will display details about the server certificate, including the fingerprint.
2. Manually Extract the Server Certificate
If you need the full certificate and not just the fingerprint, you can manually extract it using OpenSSL or openssl s_client
.
This command connects to the VPN server on port 443, retrieves the certificate, and saves it in PEM format to a file named servercert.pem
.
3. Find the Certificate Fingerprint
If you only need the fingerprint (which is what --servercert
expects), you can extract it using:
This command will output the SHA256 fingerprint of the server certificate, which you can use directly with the --servercert
option in OpenConnect
Common learnings regarding IP ranges used by Github
You may encounter that the Github IP ranges dynamically created for the worker conflict with internal IP ranges that you are using in your network.
Should you be unable to connect due to this issue you can make use of split-tunelling by creating a virtual machine in the Github runner that uses the range you need.
Here is a snippet using openconnect that does this:
Replace <ENTER YOUR IP RANGE HERE> appropriately in the snippet above.
Wireguard VPN
If Wireguard is your chosen VPN solution each user receives a config file to connect. The config fil contents should be added as a secret to your environment like this:
Secret name | Notes |
---|---|
WG_CONFIG_FILE | Pasted content from the config file |
The following snippet accesses the config file and connects using this Github Action library.
Jump / Bastion server option
An approach which is debatably less secure, is to expose a Jump or Bastion server outside of the VPN that permits SSH access from a list of static IP addresses and the Github IPs. The jump server acts as an intermediary to pass your SSH connection through to the VPN secured network.
This approach requires significant effort in security hardening the jump server and SSH connection processes.
The VPN company, "Tailscale" has this great explanation about what a jump host is and how to safely configure one.
Please note that when using a jump server, OpenCRVS Github Actions connect to your servers like this requiring further editing of your workflows.
Using a jump server should be considered a last resort.