Blame | Last modification | View Log | Download | RSS feed
# Program Overview: totp_opnsense Suite (Updated)
This suite consists of four main programs/modules for managing TOTP and OpenVPN user access with OPNSense routers. Each has a distinct role in the workflow, from configuration parsing to user authentication and QR code delivery.
---
## 1. configure
**Purpose:**
- Reads and parses OPNSense configuration files.
- Loads settings and credentials for API access and OpenVPN configuration.
- Provides utility subs for configuration management.
**Key Features:**
- 3-space indentation and camelCase variable naming.
- Modular subroutines with headers for clarity.
- Loads the custom `Opnsense` Perl module for API interaction.
**Main Subroutines:**
- `usage`: Prints usage instructions.
- `readConfig`: Reads and parses the configuration file.
---
## 2. index.php
**Purpose:**
- Provides a web interface for users to log in and retrieve their TOTP QR code and OpenVPN configuration.
- Validates user credentials and displays relevant information.
**Key Features:**
- 3-space indentation and camelCase variable naming for PHP code.
- Function headers for all major operations.
- Reads configuration generated by `processOPNSense.pl`.
**Main Functions:**
- `validateUser`: Validates user credentials against stored data.
- `displayQRCode`: Shows the QR code for the user's OTP.
- `displayOTPSeed`: Displays the OTP seed for manual entry.
- `downloadOvpnFile`: Provides a download link for the user's OpenVPN configuration.
- Displays the last time users.json was updated and allows a request for that from the webui. If user requests an update, a file is placed in /tmp which can be managed by a cron job
- see `updaterouters.cron` for an example of allowing users to request a rescan of a router.
---
## 3. opnsense-totp-ovpn-export
**Purpose:**
- Creates a lock file and checks there is only one instance running to decrease chance of corruption
- Loads router and user configuration from JSON files.
- Uses the `opnsense` module to interact with the OPNSense API.
- Generates QR codes and OpenVPN configuration files for users.
**Key Features:**
- 3-space indentation and camelCase variable naming.
- Clearly marked subroutine headers for maintainability.
- Uses `GD::Barcode::QRcode` for QR code generation and `MIME::Base64` for decoding OpenVPN files.
**Main Subroutines:**
- `loadConfig`: Loads router configuration from a JSON file.
- `loadUsers`: Loads user data from a JSON file.
- Additional subs for QR code and OpenVPN file management.
---
## 4. opnsense.pm (Perl Module)
**Purpose:**
- Provides an object-oriented interface for interacting with the OPNSense API.
- Handles API requests using either curl or LWP::UserAgent, with SSL verification disabled for compatibility.
**Key Features:**
- 3-space indentation and camelCase variable naming.
- Clearly marked subroutine headers for maintainability.
- Flexible API request handling (curl or LWP).
**Main Subroutines:**
- `new`: Constructor for the Opnsense object.
- `apiRequest`: Dispatches API requests to curl or LWP handler.
- `apiRequestCurl`: Handles API requests using curl.
- `apiRequestLwp`: Handles API requests using LWP::UserAgent.
---
## Datafile Structures
**user configuration file**
- The users configuration file (users.json) contains sensitive information (totp codes and password hash)
- The users configuration file is used by both index.php and loadOpnSense.pl, so should be owned by root, but with read access to others
- The users configuration file is a json file with the following structure
```json
{
"router1" : {
"qrLocationFileystem": "/file/system/path/to/qrcode/directory",
"qrLocation": "./qrcodes", # relative path to qrcode directory
"ovpnLocationFileSystem": "/file/system/path/to/ovpn/directory",
"ovpnLocation": "./openvpn_configs", # relative path to ovpn file directory
"lastUpdate": 1759817343, # unix timestamp of last update
"users" : {
"user1" : {
"password" : "<hashed password>",
"otp_seed" : "<otp seed>",
"qrFile" : "<path to qr code image file (relative)>",
"ovpnFile" : "<path to openvpn config file (relative)>"
},
"user2" : {
...
}
}
},
"router2" : {
...
}
}
```
**router configuration file**
- The router configuration file contains the apiSecret and apiKey that could allow black hats to access and modify your router
- The router configuration file is owned by root and set with permissions 0600, allowing access only to the root user
- The router configuration file is a json file with the following structure
```json
{
"routername": {
"hostname": "router.example.org", # hostname written to ovpn files
"localPort": "1194", # port number written to ovpn files
"apiSecret": "secret API key from opnSense Router",
"apiKey": "public API key from openSense Router",
"url": "https://192.168.1.1", # how the scripts connect to router
"template": "PlainOpenVPN", # valid template from opnsense, PlainOpenVPN is used exclusively so far
"ovpnIndex": "1" # the index into the OVPN instance. In older systems, a single digit, in newer ones a long hash
}
}
```
# Workflow Summary
1. Get API Key from router and save
2. Run `configure` to set up router
3. run `opnsense-totp-ovpn-export` to export the .ovpn files and generate the totp QR code image
4. Users access `index.php` to log in, view their QR code, OTP seed, and download OpenVPN config.
# Security Note
All scripts treat OTP secrets and user data as sensitive. It is recommended to keep generated files and QR codes on a secure internal network.