OpenCRVS
v1.5
v1.5
  • 👋Welcome!
  • CRVS Systems
    • Understanding CRVS
    • Effective digital CRVS systems
    • OpenCRVS within a government systems architecture
    • OpenCRVS Value Proposition
  • Product Specifications
    • Functional Architecture
    • Workflow management
    • Status Flow Diagram
    • Users
      • Examples
    • Core functions
      • 1. Notify event
      • 2. Declare event
      • 3. Validate event
      • 4. Register event
      • 5. Print certificate
      • 6. Issue certificate
      • 7. Search for a record
      • 8. View record
      • 9. Correct record
      • 10. Verify record
      • 11. Archive record
      • 12. Vital statistics export
    • Support functions
      • 13. Login
      • 14. Audit
      • 15. Deduplication
      • 16. Performance management
      • 17. Payment
      • 18. Learning
      • 19. User support
      • 20. User onboarding
    • Admin functions
      • 21. User management
      • 22. Comms management
      • 23. Content management
      • 24. Config management
    • Data functions
      • 25. Legacy data import
      • 26. Legacy paper import
  • Technology
    • Architecture
      • Performance tests
    • Standards
      • FHIR Documents
        • Event Composition
        • Person
        • Registration Task
        • Event Observations
        • Locations
    • Security
    • Interoperability
      • Create a client
      • Authenticate a client
      • Event Notification clients
      • Record Search clients
      • Webhook clients
      • National ID client
      • FHIR Location REST API
      • Other ways to interoperate
  • Default configuration
    • Intro to Farajaland
    • Civil registration in Farajaland
    • OpenCRVS configuration in Farajaland
      • Application settings
      • User / role mapping
      • Declaration forms
      • Certificate templates
    • Business process flows in Farajaland
  • Setup
    • 1. Planning an OpenCRVS Implementation
    • 2. Establish project and team
    • 3. Gather requirements
      • 3.1 Mapping business processes
      • 3.2 Mapping offices and user types
      • 3.3 Define your application settings
      • 3.4 Designing event declaration forms
      • 3.5 Designing a certificate template
    • 4. Installation
      • 4.1 Set-up a local development environment
        • 4.1.1 Install the required dependencies
        • 4.1.2 Install OpenCRVS locally
        • 4.1.3 Starting and stopping OpenCRVS
        • 4.1.4 Log in to OpenCRVS locally
        • 4.1.5 Tooling
          • 4.1.5.1 WSL Support
      • 4.2 Set-up your own, local, country configuration
        • 4.2.1 Fork your own country configuration repository
        • 4.2.2 Set up administrative address divisions
          • 4.2.2.1 Prepare source file for administrative structure
          • 4.2.2.2 Prepare source file for statistics
        • 4.2.3 Set up CR offices and Health facilities
          • 4.2.3.1 Prepare source file for CRVS Office facilities
          • 4.2.3.2 Prepare source file for health facilities
        • 4.2.4 Set up employees & roles for testing or production
          • 4.2.3.1 Prepare source file for employees
          • 4.2.3.2 Configure role titles
        • 4.2.5 Set up application settings
          • 4.2.5.1 Managing language content
            • 4.2.5.1.1 Informant and staff notifications
          • 4.2.5.2 Configuring Metabase Dashboards
        • 4.2.6 Configure certificate templates
        • 4.2.7 Configure declaration forms
          • 4.2.7.1 Configuring an event form
        • 4.2.8 Seeding & clearing your local databases
        • 4.2.9 Countryconfig API endpoints explained
      • 4.3 Set-up a server-hosted environment
        • 4.3.1 Verify servers & create a "provision" user
        • 4.3.2 TLS / SSL & DNS
          • 4.3.2.1 LetsEncrypt https challenge in development environments
          • 4.3.2.2 LetsEncrypt DNS challenge in production
          • 4.3.2.3 Static TLS certificates
        • 4.3.3 Configure inventory files
        • 4.3.4 Create a Github environment
          • 4.3.4.1 Environment secrets and variables explained
          • 4.3.4.2 VPN Recipes
        • 4.3.5 Provisioning servers
          • 4.3.5.1 SSH access
          • 4.3.5.2 Building, pushing & releasing your countryconfig code
          • 4.3.5.3 Ansible tasks when provisioning
        • 4.3.6 Deploy
          • 4.3.6.1 Running a deployment
          • 4.3.6.2 Seeding a server environment
          • 4.3.6.3 Login to an OpenCRVS server
          • 4.3.6.5 Resetting a server environment
        • 4.3.7 Backup & Restore
          • 4.3.7.1 Restoring a backup
          • 4.3.7.2 Off-boarding from OpenCRVS
    • 5. Functional configuration
      • 5.1 Configure application settings
      • 5.2 Configure registration periods and fees
      • 5.3 Managing system users
    • 6. Quality assurance testing
    • 7. Go-live
      • 7.1 Pre-Deployment Checklist
    • 8. Operational Support
    • 9. Monitoring
      • 9.1 Application logs
      • 9.2 Infrastructure health
      • 9.3 Routine monitoring checklist
      • 9.4 Setting up alerts
      • 9.5 Managing a Docker Swarm
  • General
    • Community
    • Contributing
    • Releases
      • v1.5.1: Release notes
      • v1.5.0: Release notes
      • v1.4.1: Release notes
      • v1.4.0 to v1.4.1 Migration notes
      • v1.4.0 Release notes
      • v1.3.* to v1.4.* Migration notes
      • v1.3.5: Release notes
      • v1.3.4: Release notes
      • v1.3.3: Release notes
      • v1.3.1: Release notes
      • v1.3.0: Release notes
      • v1.2.1: Release notes
      • Patch: Elasticsearch 7.10.2
      • v1.2.0: Release notes
      • v.1.1.2: Release notes
      • v.1.1.1: Release notes
      • v1.1.0: Release notes
    • Roadmap
Powered by GitBook
On this page
  • Openconnect compatible VPN
  • Common learnings regarding IP ranges used by Github
  • Wireguard VPN
  • Jump / Bastion server option
  1. Setup
  2. 4. Installation
  3. 4.3 Set-up a server-hosted environment
  4. 4.3.4 Create a Github environment

4.3.4.2 VPN Recipes

Previous4.3.4.1 Environment secrets and variables explainedNext4.3.5 Provisioning servers

Last updated 6 months ago

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 .

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

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.

https://countryconfig.<production-domain>/content/country-logo
https://countryconfig.<staging-domain>/content/country-logo

The following Github Action 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

Openconnect compatible VPN

openconnect compatible VPNs are:

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. "fortinet"

Refer to note below the snippet for an explanation regarding this secret.

Github Action workflow snippet:


- name: Update apt
  run: sudo apt update

- name: Install openconnect
  run: sudo apt install -y openconnect

- name: Connect to VPN
  run: |
    echo "${{ secrets.VPN_PWD }}" | sudo openconnect --syslog -u ${{ secrets.VPN_USER }} --passwd-on-stdin --protocol=${{ secrets.VPN_PROTOCOL }} ${{ secrets.VPN_HOST }}:${{ secrets.VPN_PORT }} --servercert ${{ secrets.VPN_SERVERCERT }} --background -v
    sleep 3

- name: Test if IP is reachable
  run: |
    ping -c4 ${{ vars.SSH_HOST }}

VPN_SERVERCERT

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.

sudo openconnect --user=$VPN_USER --passwd-on-stdin --verbose $VPN_HOST_ADDRESS

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.

openssl s_client -connect $VPN_HOST_ADDRESS:443 </dev/null 2>/dev/null | openssl x509 -outform PEM > servercert.pem

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:

openssl x509 -in servercert.pem -noout -fingerprint -sha256

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

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:

- name: Update apt
  run: sudo apt update

- name: Install openconnect
  run: sudo apt install -y openconnect

- name: Install virtualenv
  run: |
    sudo apt install virtualenvwrapper
    sudo apt install virtualenv
    virtualenv vpn-slice
    source vpn-slice/bin/activate
    pip3 install https://github.com/dlenski/vpn-slice/archive/master.zip

- name: Connect to VPN
  run: |
    echo "${{ secrets.VPN_PWD }}" | sudo openconnect --syslog -u ${{ secrets.VPN_USER }} --passwd-on-stdin --protocol=${{ secrets.VPN_PROTOCOL }} ${{ secrets.VPN_HOST }}:${{ secrets.VPN_PORT }} --servercert ${{ secrets.VPN_SERVERCERT }} --background -v -s 'vpn-slice/bin/vpn-slice <ENTER YOUR IP RANGE HERE>'
    sleep 3
    ip_addr=$(ip -f inet addr show tun0 |sed -En -e 's/.*inet ([0-9.]+).*/\1/p')
    sudo ip route add <ENTER YOUR IP RANGE HERE> via $ip_addr dev tun0

- name: Test if IP is reachable
  run: |
    ping -c4 ${{ vars.SSH_HOST }}

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

- name: Read wireguard file from secret
  id: read-wg-file
  run: echo "##[set-output name=wg_file;]${{ secrets.WG_CONFIG_FILE }}"

- name: Set up wireguard connection
  if: ${{ steps.read-wg-file.outputs.wg_file != '' }}
  uses: niklaskeerl/easy-wireguard-action@v2
  with:
    WG_CONFIG_FILE: ${{ secrets.WG_CONFIG_FILE }}

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.

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.

ssh -J jump@<your vpn server> provision@<your server>

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. .

The following VPN providers are compatible with which allows you to programatically connect in the Github Action.

(--protocol=anyconnect)

(--protocol=array)

(--protocol=nc)

(--protocol=pulse)

(--protocol=gp)

(--protocol=f5)

(--protocol=fortinet)

You may encounter that the dynamically created for the worker conflict with internal IP ranges that you are using in your network.

The following snippet accesses the config file and connects using Github Action library.

The VPN company, "Tailscale" has great explanation about what a jump host is and how to safely configure one.

VPN_PROTOCOL
VPN_SERVERCERT
MDM
4.3.1 Verify servers
https://api.github.com/meta
workflows
here
openconnect
Cisco AnyConnect
Array Networks SSL VPN
Juniper SSL VPN
Pulse Connect Secure
Palo Alto Networks GlobalProtect SSL VPN
F5 Big-IP SSL VPN
Fortinet Fortigate SSL VPN
Github IP ranges
this
this