Skip to content

Hackerbone/github-openvpn-connect-action

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenVPN Connect for GitHub Actions

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.

Why Use This Action?

  • 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 .ovpn files 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.

Quick Start

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

Inputs

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.

Authentication Examples

Username And Password

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

Client Private Key

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

TLS Auth

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

TLS Crypt

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

TLS Crypt V2

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

Configuration File

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.

Cleanup

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.

Troubleshooting

openvpn: command not found

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

VPN Connection Timeout

The 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-security settings in the .ovpn file,
  • whether the VPN server allows connections from GitHub-hosted runner IPs.

DNS Does Not Resolve Private Hostnames

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.

Security Notes

  • 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

Credit to kota65535/github-openvpn-connect-action for the original idea and input shape.

License

MIT

About

OpenVPN Connect for GitHub Actions - Node 24 VPN action for private network CI/CD

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors