Run CI/CD jobs that need private network access. This action starts an OpenVPN client inside a GitHub Actions runner, waits for the VPN connection to be ready, and automatically disconnects during the post-job cleanup phase.
It is built for modern GitHub Actions runners and uses the current node24
JavaScript action runtime.
- Connect GitHub Actions to private services, databases, APIs, Kubernetes clusters, staging environments, and internal deployment targets.
- Works with username/password authentication, client private keys, TLS Auth, TLS Crypt, and TLS Crypt V2.
- Cleans up the OpenVPN daemon and temporary credential files after the job.
- Uses the standard OpenVPN client, so your existing
.ovpnfiles continue to define routes, certificates, DNS hooks, and remote endpoints. - Keeps workflow YAML small while still letting you manage VPN credentials with GitHub Actions secrets.
name: Private Network Build
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install OpenVPN
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends openvpn openvpn-systemd-resolved
- name: Connect to private network
uses: Hackerbone/github-openvpn-connect-action@v1
with:
config_file: .github/workflows/client.ovpn
username: ${{ secrets.OVPN_USERNAME }}
password: ${{ secrets.OVPN_PASSWORD }}
echo_config: "false"
- name: Run private-network task
run: curl --fail https://internal.example.com/health| Input | Required | Description |
|---|---|---|
config_file |
yes | Path to the OpenVPN client configuration file. |
username |
no | Username for auth-user-pass authentication. |
password |
no | Password for auth-user-pass authentication. |
client_key |
no | Local peer private key. Written to a temporary 0600 file. |
tls_auth_key |
no | Pre-shared key for tls-auth. |
tls_crypt_key |
no | Pre-shared key for tls-crypt. |
tls_crypt_v2_key |
no | Per-client key for tls-crypt-v2. |
echo_config |
no | Print the final OpenVPN config to logs. Defaults to true; use false when configs contain secrets. |
- name: Connect to VPN
uses: Hackerbone/github-openvpn-connect-action@v1
with:
config_file: .github/workflows/client.ovpn
username: ${{ secrets.OVPN_USERNAME }}
password: ${{ secrets.OVPN_PASSWORD }}
echo_config: "false"- name: Connect to VPN
uses: Hackerbone/github-openvpn-connect-action@v1
with:
config_file: .github/workflows/client.ovpn
client_key: ${{ secrets.OVPN_CLIENT_KEY }}
echo_config: "false"- name: Connect to VPN
uses: Hackerbone/github-openvpn-connect-action@v1
with:
config_file: .github/workflows/client.ovpn
tls_auth_key: ${{ secrets.OVPN_TLS_AUTH_KEY }}
echo_config: "false"- name: Connect to VPN
uses: Hackerbone/github-openvpn-connect-action@v1
with:
config_file: .github/workflows/client.ovpn
tls_crypt_key: ${{ secrets.OVPN_TLS_CRYPT_KEY }}
echo_config: "false"- name: Connect to VPN
uses: Hackerbone/github-openvpn-connect-action@v1
with:
config_file: .github/workflows/client.ovpn
tls_crypt_v2_key: ${{ secrets.OVPN_TLS_CRYPT_V2_KEY }}
echo_config: "false"Store a normal OpenVPN client config in your repository, for example:
.github/workflows/client.ovpn
Inline certificates are supported because OpenVPN itself reads the file. Keep sensitive inline material out of logs by setting:
echo_config: "false"When secrets are provided through action inputs, this action writes them into a temporary directory with restrictive permissions and appends the matching OpenVPN directives to the config for the duration of the job.
The action starts OpenVPN with:
sudo openvpn --config <config> --daemon --log <log> --writepid <pid>During the post-job phase it:
- kills the OpenVPN daemon when it is still running,
- removes temporary credential files,
- restores the OpenVPN config file to its original size.
Install OpenVPN before running the action:
- name: Install OpenVPN
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends openvpn openvpn-systemd-resolvedThe action waits for Initialization Sequence Completed in the OpenVPN log.
If the connection times out, check:
- VPN server hostname and port reachability from GitHub-hosted runners,
- credentials and certificate validity,
- routes, DNS hooks, and
script-securitysettings in the.ovpnfile, - whether the VPN server allows connections from GitHub-hosted runner IPs.
DNS behavior is controlled by your OpenVPN config and the runner environment.
For Ubuntu runners, installing openvpn-systemd-resolved is often useful when
your config uses resolver update scripts.
- Prefer GitHub Actions secrets for usernames, passwords, and private keys.
- Set
echo_config: "false"when the config contains inline credentials, private keys, certificates, or internal hostnames. - Avoid printing VPN credentials in workflow steps.
- Pin production workflows to a major tag such as
@v1, or to a full commit SHA when you need maximum supply-chain control.
Credit to kota65535/github-openvpn-connect-action for the original idea and
input shape.
MIT