Establish a Pritunl VPN connection using Pritunl Client supporting OpenVPN (ovpn) and WireGuard (wg) modes on GitHub Actions.
This utility helps you with tasks like automated internal endpoint testing, periodic backups, builds distribution for cross-platform multi-architecture platforms, and anything that requires private access inside the corporate infrastructure using Pritunl VPN Enterprise Servers.
Compatibility and Common Issues between the Runners and VPN Mode.
Runner | OpenVPN | WireGuard |
---|---|---|
ubuntu-22.04 |
✅ yes | ✅ yes |
ubuntu-20.04 |
✅ yes | ✅ yes |
macos-13 |
✅ yes | ✅ yes |
macos-12 |
✅ yes | ✅ yes |
windows-2022 |
✅ yes | ✅ yes |
windows-2019 |
✅ yes | ✅ yes |
Tip
Kindly check out the comprehensive connection tests matrix available on our GitHub Actions page.
As of the most recent updates and releases, we have confirmed compatibility with Pritunl v1.32.3805.95 Server through rigorous testing. Server clusters are deployed on both AWS and Azure cloud platforms.
The configuration is declarative and relatively simple to use.
- uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ''
# REQUIRED: Pritunl Profile File
# TYPE: Wrapping String (Base64 text format)
profile-pin: ''
# OPTIONAL: Profile Pin
# TYPE: String (Numerical values)
# If not supplied, which defaults No Pin.
profile-server: ''
# OPTIONAL: Profile Server
# TYPE: String (Single string or Comma-separated for multiple names)
# If not supplied, which defaults to the first or only server in the profile.
vpn-mode: ''
# OPTIONAL: VPN Connection Mode
# TYPE: String
# CHOICES: ['ovpn', 'openvpn', 'OpenVPN'] or ['wg', 'wireguard', 'WireGuard']
# If not supplied, which defaults to 'ovpn'.
client-version: ''
# OPTIONAL: Pritunl Client Version
# TYPE: String (Numerical dot separated identifiers)
# For example, using the later version `1.3.3814.40`.
# If not supplied, which defaults to the latest version from the Package Manager.
start-connection: ''
# OPTIONAL: Start the Connection
# TYPE: Boolean
# If not supplied, which defaults to `true`.
# If `true` the VPN connection starts within the setup step.
ready-profile-timeout: ''
# OPTIONAL: Ready Profile Timeout
# TYPE: Natural Numbers (Unit of time in Second)
# If not supplied, which defaults to `3` seconds.
established-connection-timeout: ''
# OPTIONAL: Established Connection Timeout
# TYPE: Natural Numbers (Unit of time in Second)
# If not supplied, which defaults to `60` seconds.
Important
Kindly check the subsection Working with Pritunl Profile File on converting tar
archive file format to base64
text file format for the profile-file
input.
client-id
— is a string of key-value pairs associated with a profile, with an identifier the client randomly generates during the profile setup process.
The step output
retrieving example is '${{ steps.pritunl-connection.outputs.client-id }}'
where the pritunl-connection
is the Setup Step ID
.
Show the Example Output.
[
{
"name": "pritunl.profile.1 (pritunl.server.1)",
"id": "uykk46qpju3topgh"
},
{
"name": "pritunl.profile.1 (pritunl.server.2)",
"id": "za4c6gkjqbetkpwj"
}
]
Tip
Kindly check the subsection Manually Controlling the Connection for example.
Provided that profile-file
is available, we have the flexibility to generate multiple scenarios.
- name: Setup Pritunl Profile and Start VPN Connection
uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
Then your other steps are below.
- name: Your CI/CD Core Logic
shell: bash
run: |
cat <<EOF
##
# EXAMPLES:
# * Integration Test,
# * End-to-End Test,
# * Endpoint Reachability Test,
# * Backup Tasks,
# * And more.
##
EOF
- name: Example Cypress E2E Test
uses: cypress-io/github-action@v5
working-directory: e2e
Tip
Kindly check the GitHub Action workflow file connection-tests-basic.yml for the basic running example.
- name: Setup Pritunl Profile and Start VPN Connection
uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
profile-pin: ${{ secrets.PRITUNL_PROFILE_PIN }}
You can connect to a specific server by specifying its name.
- name: Setup Pritunl Profile and Start VPN Connection
uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
profile-server: qa-team
The feature allows us to connect to multiple servers by their names, separated by commas.
- name: Setup Pritunl Profile and Start VPN Connection
uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
profile-server: qa-team, dev-team
You can use the full profile name as well, it is also acceptable.
- name: Setup Pritunl Profile and Start VPN Connection
uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
profile-server: cicd.automation (qa-team), cicd.automation (dev-team)
Tip
Kindly check the GitHub Action workflow file connection-tests-multi-server-profile.yml for the multi-server profile connections example.
- name: Setup Pritunl Profile and Start VPN Connection
uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
client-version: 1.3.3814.40
vpn-mode: wg
- name: Setup Pritunl Profile
id: pritunl-connection # A `Setup Step ID` has been added as a reference identifier for the output `client-id`.
uses: nathanielvarona/pritunl-client-github-action@v1
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
start-connection: false # Do not establish a connection in this step.
- name: Starting a VPN Connection Manually
shell: bash
run: |
# Starting a VPN Connection Manually
pritunl-client start "$(echo '${{ steps.pritunl-connection.outputs.client-id }}' | jq -r 'sort_by(.name) | .[0].id')" \
--password ${{ secrets.PRITUNL_PROFILE_PIN || '' }}
- name: Show VPN Connection Status Manually
shell: bash
run: |
# Show VPN Connection Status Manually
sleep 10
pritunl-client list -j | jq 'sort_by(.name) | .[0] | { "Profile Name": .name, "Client Address": .client_address }'
- name: Your CI/CD Core Logic
shell: bash
run: |
# Your CI/CD Core Logic
##
# Below is our simple example for VPN connectivity test.
##
# Install IP Calculator
if [ "$RUNNER_OS" == "Linux" ]; then
sudo apt-get install -qq -o=Dpkg::Use-Pty=0 -y ipcalc
elif [ "$RUNNER_OS" == "macOS" ]; then
brew install -q ipcalc
elif [ "$RUNNER_OS" == "Windows" ]; then
# Retry up to 3 times in case of failure
for attempt in $(seq 3); do
if curl -sSL "https://raw.githubusercontent.com/kjokjo/ipcalc/0.51/ipcalc" \
-o $HOME/bin/ipcalc && chmod +x $HOME/bin/ipcalc; then
break
else
echo "Attempt $attempt failed. Retrying..." && sleep 1
# If all retries fail, exit with an error
if [ $attempt -eq 3 ]; then
echo "Failed to install ipcalc after 3 attempts." && exit 1
fi
fi
done
fi
# Validate the IP Calculator Installation
echo "ipcalc version $(ipcalc --version)"
# VPN Gateway Reachability Test
ping_count_number=5
profile_ip=$(pritunl-client list -j | jq -r 'sort_by(.name) | .[0].client_address')
vpn_gateway="$(ipcalc $profile_ip | awk 'NR==6{print $2}')"
ping_flags="$([[ "$RUNNER_OS" == "Windows" ]] && echo "-n $ping_count_number" || echo "-c $ping_count_number")"
# Ping VPN Gateway
ping $vpn_gateway $ping_flags
- name: Stop VPN Connection Manually
if: ${{ always() }}
shell: bash
run: |
# Stop VPN Connection Manually
pritunl-client stop "$(echo '${{ steps.pritunl-connection.outputs.client-id }}' | jq -r 'sort_by(.name) | .[0].id')"
Tip
Kindly check the GitHub Action workflow file connection-tests-manual-readme-example.yml for the readme example manual test. And the workflow file connection-tests-complete.yml for the complete tests matrix example.
The Pritunl Client CLI won't allow us to load profiles from the plain ovpn
file, and GitHub doesn't have a feature to upload binary files such as the tar
archive file for the GitHub Actions Secrets.
To store Pritunl Profile to GitHub Secrets, maintaining the raw state of the tar
archive file format, we need to convert it to base64
text file format.
If the Infrastructure Team
provided you with a tar
file, proceed to Step 2
.
curl -sSL https://vpn.domain.tld/key/a1b2c3d4e5.tar -o ./pritunl.profile.tar
base64 --wrap 0 ./pritunl.profile.tar > ./pritunl.profile.base64
# For macOS:
# Using `pbcopy`
cat ./pritunl.profile.base64 | pbcopy
# For Linux:
# Using `xclip`
cat ./pritunl.profile.base64 | xclip -selection clipboard
# Using `xsel`
cat ./pritunl.profile.base64 | xsel --clipboard --input
Or you can easily access the file data by opening it with your preferred code editor:
code ./pritunl.profile.base64 # or,
vim ./pritunl.profile.base64
Then, copy the entire base64
text data.
Such as Secrets Key PRITUNL_PROFILE_FILE
from the Examples.
Show the one-liner shorthand script for the first three steps.
# For macOS
encode_profile_and_copy() { curl -sSL $1 | base64 -w 0 | pbcopy }
# For Linux
encode_profile_and_copy() { curl -sSL $1 | base64 -w 0 | xclip -selection clipboard } # Or,
encode_profile_and_copy() { curl -sSL $1 | base64 -w 0 | xsel --clipboard --input }
# Usage
encode_profile_and_copy https://vpn.domain.tld/key/a1b2c3d4e5.tar
Runner | OpenVPN | WireGuard |
---|---|---|
macos-13-xlarge *w1 |
✅ yes | ✅ yes |
Warning
*w1 — "These runner will always be charged for, including in public repositories."
For a comprehensive overview of your billing details, we recommend starting with the "About billing for GitHub Actions" page for thorough insights.
Tip
Kindly check the GitHub Action workflow file connection-tests-arm64.yml for the Arm64 running example.
If you have any suggestions for improvement, please don't hesitate to fork the project and submit a Pull Request.
- name: Setup Pritunl Profile and Start VPN Connection
uses: <YOUR GITHUB USERNAME>/pritunl-client-github-action@<YOUR FEATURE BRANCH>
with:
profile-file: ${{ secrets.PRITUNL_PROFILE_FILE }}
...
<YOUR FEATURE INPUTS>
...