OPNsense TOTP and OpenVPN Configuration Export System
A web-based system that provides users with secure access to their TOTP (Time-based One-Time Password) QR codes and OpenVPN configuration files from OPNsense routers. The system connects directly to OPNsense routers via API to retrieve and manage user configurations.
Features
- Direct API integration with OPNsense routers
- Automatic generation of TOTP QR codes for two-factor authentication
- Multiple OpenVPN configuration file support per user
- Multi-router support with individual user configurations
- Secure password hashing using bcrypt
- Web interface for users to access their credentials
- Administrative tools for router configuration management
- Access logging with timestamps
- Support for multiple VPN configuration formats (TCP/UDP, different ports, etc.)
System Components
Main Scripts
opnsense-totp-ovpn-export
The primary script that connects to OPNsense routers via API to:
- Retrieve VPN user certificates and configurations
- Extract TOTP secrets from user accounts
- Generate QR codes for authenticator apps
- Create OpenVPN configuration files with custom formats
- Update user credentials and metadata
- Store data in JSON format
Usage:
./opnsense-totp-ovpn-export
Requirements:
- Router must be configured in
routers.json
- OPNsense API credentials required
configure
Interactive configuration tool for managing router definitions:
- Add/edit/delete router configurations
- Set API credentials (URL, API key, API secret)
- Configure VPN provider settings
- Define multiple OpenVPN configuration formats
- Manage filename templates and additional configuration strings
Usage:
./configure [configfile]
(defaults to routers.json if no file specified)
index.php
Web interface for end users:
- Username/password authentication
- Router selection dropdown
- Displays TOTP QR code and secret
- Provides download links for OpenVPN configuration files
- Supports multiple configuration files per user
- Request refresh functionality for router data
- Logs successful authentication attempts
Configuration Files
routers.json
Stores router connection details and settings:
{
"routername": {
"url": "https://router.example.com",
"apiKey": "your-api-key",
"apiSecret": "your-api-secret",
"ovpnIndex": "provider-id",
"template": "PlainOpenVPN",
"hostname": "vpn.example.com",
"localPort": "1194",
"downloadToken": "random-token",
"formats": {
"tcp": {
"filename": "ROUTER_USER_tcp.ovpn",
"additionalStrings": "proto tcp\\nport 443"
},
"udp": {
"filename": "ROUTER_USER_udp.ovpn",
"additionalStrings": "proto udp\\nport 1194"
}
}
}
}
Formats Configuration:
- Each format creates a separate OpenVPN configuration file
filename: Template with ROUTER and USER placeholders
additionalStrings: Configuration lines to append (\n for newlines)
- Multiple formats allow users to download different connection options
users.json
Generated automatically by opnsense-totp-ovpn-export:
{
"routername": {
"qrLocation": "./qrcodes",
"ovpnLocation": "./openvpn_configs",
"lastUpdate": 1234567890,
"users": {
"username": {
"otp_seed": "BASE32SECRET",
"password": "$2y$10$hashedpassword",
"certs": ["cert-id"],
"qrFile": "./qrcodes/router_user.png",
"ovpnFile": "./openvpn_configs/router_user.ovpn"
}
}
}
}
Note: ovpnFile can be a string (single file) or array (multiple files)
Directory Structure
.
├── configure # Router configuration tool
├── opnsense-totp-ovpn-export # Main export script
├── opnsense.pm # OPNsense API library
├── index.php # User web interface
├── dl.php # Download handler (legacy)
├── routers.json # Router configurations
├── users.json # User credentials (auto-generated)
├── updaterouters.cron # Cron job script
├── logs/ # Access logs directory
│ └── log_YYYY-MM-DD.log # Daily log files
├── qrcodes/ # Generated QR code images
│ └── *.png
└── openvpn_configs/ # Generated OpenVPN configs
└── *.ovpn
Installation
Prerequisites
- Apache/Nginx web server with PHP support
- Perl 5.x with required modules:
- Password hashing functions
- Root access for script execution
- OPNsense router with API access enabled
Setup Steps
- Clone/copy files to web-accessible directory:
cd /var/www/html/web_pages
svn co totp_opnsense
cd totp_opnsense
- Set permissions:
chmod 755 configure opnsense-totp-ovpn-export
chmod 600 routers.json # Will be created by configure
chmod 755 qrcodes openvpn_configs logs
- Configure routers:
sudo ./configure
- Select VPN provider index
- Configure formats (optional)
- Initial data pull:
sudo ./opnsense-totp-ovpn-export routername
- Set up cron job for automatic updates:
sudo crontab -e
Add line:
/15 * /var/www/html/web_pages/totp_opnsense/updaterouters.cron
- Configure web server:
- Ensure PHP has read access to all files
- Restrict direct access to sensitive files (routers.json, users.json)
- Consider HTTPS for production use
Usage
For Administrators
Add a new router:
sudo ./configure
Select "Add new router"
Enter configuration details
Update router data manually:
sudo ./opnsense-totp-ovpn-export routername
Configure VPN formats:
sudo ./configure
Select router
Select "formats"
Add format definitions with filename templates and additional strings
For End Users
- Navigate to the web interface (e.g.,
https://server/totp_opnsense/)
- Enter your username and password
- Select the router from the dropdown
- Click "Login"
- Scan the QR code with your authenticator app (first time only)
- Download your OpenVPN configuration file(s)
- Import the .ovpn file into your OpenVPN client
If multiple VPN configurations are available:
- Each configuration will be listed separately
- Choose based on your needs (TCP for restrictive networks, UDP for speed)
Security Considerations
Current Security Features
- Passwords hashed using bcrypt (cost factor 10-11)
- API credentials stored in root-only readable file
- TOTP secrets never transmitted in plain text
- Login attempts logged with IP addresses
- Lock file prevents concurrent script execution
Security Recommendations
- Use HTTPS: Always serve the web interface over HTTPS
- Restrict access: Use firewall rules or .htaccess to limit access
- Regular updates: Keep router data current but not too frequent
- Monitor logs: Review access logs regularly
- API key security: Use dedicated API keys with minimal permissions
- File permissions: Ensure sensitive files are not world-readable
Known Limitations
- QR codes are pre-generated and stored on disk
- TOTP secrets are accessible if filesystem is compromised
- No rate limiting on login attempts (implement at web server level)
- Sessions not implemented (stateless authentication)
API Integration
The system uses the OPNsense API module (opnsense.pm) to interact with routers:
Key API endpoints used:
- Get VPN user certificates
- Export VPN configuration files
- Retrieve user authentication data (including TOTP secrets)
API Setup in OPNsense:
- System → Access → Users
- Create API user with necessary permissions
- Generate API key and secret
- Use credentials in
configure script
Troubleshooting
Script won't run:
- Verify Perl modules are installed
- Check lock file:
/tmp/opnsense.lock
Users can't log in:
- Verify
users.json exists and is readable by web server
- Check password was properly hashed
- Review logs in
logs/ directory
QR codes not displaying:
- Check
qrcodes/ directory permissions
- Verify GD::Barcode::QRcode Perl module installed
- Ensure user has TOTP enabled in OPNsense
VPN configs not downloading:
- Check
openvpn_configs/ directory permissions
- Verify formats configuration in routers.json
- Check that user has valid VPN certificate
Refresh doesn't work:
- Verify web server can execute scripts as root (not recommended) or:
- Set up separate mechanism for administrators to trigger updates
- Check file permissions on opnsense-totp-ovpn-export
File Format Details
Log Format (logs/log_YYYY-MM-DD.log)
YYYY-MM-DD HH:MM:SSIP_ADDRESSSuccessUSERNAME
QR Code Encoding
- Format: TOTP URI (otpauth://totp/...)
- Includes: router name, username, TOTP secret
- Module size: 10 (configurable in script)
Version History
See individual script files for detailed version history.
Current Versions:
- opnsense-totp-ovpn-export: 1.1.0
License
Copyright (c) 2025, Daily Data, Inc.
All rights reserved.
See individual files for complete BSD 3-Clause license terms.
Support
For issues, questions, or contributions, contact your system administrator or Daily Data, Inc.
Tested Environments