Implementing OpenVPN Authentication via Google OAuth/OpenID Connect: Certificate-Based Auth Alternatives


3 views

Traditional OpenVPN authentication typically relies on:

  • Username/password credentials
  • Certificate-based authentication
  • Two-factor authentication (2FA) methods

While Google 2FA exists as mentioned, native OAuth/OpenID Connect integration would provide better SSO capabilities for Google Workspace environments.

Here are three viable approaches to implement this:

1. OAuth Proxy with PAM Module

This method uses an OAuth proxy server that authenticates users against Google's OAuth endpoint, then passes the authentication to OpenVPN via PAM:

# oauth2-proxy configuration example
provider = "google"
email_domains = ["yourdomain.com"]
upstreams = ["file:///var/run/openvpn.sock"]
client_id = "YOUR_CLIENT_ID.apps.googleusercontent.com"
client_secret = "YOUR_CLIENT_SECRET"
cookie_secret = "SECURE_RANDOM_STRING"

2. Certificate-Based Auth with Google Identity

Similar to your GitLab reference, we can implement certificate-based auth where:

  1. Users authenticate via Google OAuth
  2. System issues short-lived client certificates
  3. OpenVPN accepts these certificates

Example OpenVPN server config:

client-cert-not-required
username-as-common-name
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn

3. Custom Auth Script Using Google's API

For more control, you can write a custom auth script:

#!/bin/bash
# auth_script.sh
GOOGLE_TOKEN=$1
USER_EMAIL=$(curl -s https://www.googleapis.com/oauth2/v1/userinfo?access_token=$GOOGLE_TOKEN | jq -r '.email')

if [[ $USER_EMAIL =~ @yourdomain\.com$ ]]; then
  exit 0
else
  exit 1
fi

Key considerations when implementing this:

  • Token validation latency
  • Certificate revocation handling
  • Session timeout alignment between Google and OpenVPN
  • Mobile client compatibility

If building in-house seems complex, consider:

  • Twingate (supports Google Workspace integration)
  • Pritunl (enterprise OpenVPN with OAuth support)
  • Perimeter 81 (cloud-based VPN with SSO)

When implementing any OAuth solution:

# Always:
- Use PKCE for OAuth flows
- Validate token signatures
- Implement proper scope validation
- Set appropriate token lifetimes
- Monitor authentication logs

Traditional OpenVPN authentication methods (PAM, LDAP, or local auth) don't meet modern SSO requirements for enterprises using Google Workspace. While Google's 2FA adds security, it doesn't provide true OAuth/SAML integration that IT teams increasingly demand.

We can achieve this through three approaches:


1. OAuth2 Proxy Middleware
   [Client] -> [OAuth2 Proxy] -> [OpenVPN Auth Script]

2. SAML SP Module
   [OpenVPN] <-SAML-> [Google IdP]

3. Custom PAM Module
   [OpenVPN PAM] -> [python-social-auth] -> [Google OAuth]

This is the most maintainable approach using oauth2-proxy:

# oauth2-proxy.cfg
provider = "google"
email_domains = ["yourdomain.com"]
client_id = "YOUR_GOOGLE_CLIENT_ID"
client_secret = "YOUR_CLIENT_SECRET"
cookie_secret = "SECURE_RANDOM_STRING"
upstreams = "file:///etc/openvpn/auth-control.sock"

Then configure OpenVPN to use the auth script:

# server.conf
script-security 2
auth-user-pass-verify "/path/to/oauth_verify.py" via-file

For enterprises using Google as IdP:

# Using mod_auth_mellon for Apache
<Location /vpn-auth>
    MellonEnable "info"
    MellonSPPrivateKeyFile /etc/apache2/mellon/sp.key
    MellonSPCertFile /etc/apache2/mellon/sp.crt
    MellonIdPMetadataFile /etc/apache2/mellon/google_metadata.xml
    MellonEndpointPath /mellon
    MellonVariable "cookie"
</Location>

For certificate + OAuth combination:

# openvpn-custom-auth.py
def verify_google_token(token):
    # Use google-auth library to verify
    from google.oauth2 import id_token
    from google.auth.transport import requests
    
    try:
        idinfo = id_token.verify_oauth2_token(
            token, requests.Request(), CLIENT_ID)
        if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
            raise ValueError("Wrong issuer")
        return idinfo['email']
    except:
        return None
  • Always validate token audience (client_id)
  • Implement proper session timeout (match Google token expiry)
  • Use dedicated OAuth credentials for VPN service
  • Monitor failed authentication attempts