Subversion Repositories web_pages

Rev

Rev 16 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
20 rodolico 1
# Program Overview: totp_opnsense Suite
16 rodolico 2
 
20 rodolico 3
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 management to user authentication and credential delivery.
16 rodolico 4
 
5
---
6
 
7
## 1. configure
8
 
9
**Purpose:**
20 rodolico 10
- Interactive tool for managing router configurations stored in `routers.json`.
11
- Allows adding, editing, and removing router definitions.
12
- Manages API credentials, VPN provider settings, and OpenVPN configuration formats.
16 rodolico 13
 
14
**Key Features:**
15
- 3-space indentation and camelCase variable naming.
20 rodolico 16
- Menu-driven interface for easy configuration management.
17
- Supports multiple OpenVPN configuration formats per router.
18
- Direct integration with OPNsense API to select VPN providers.
16 rodolico 19
 
20
**Main Subroutines:**
21
- `usage`: Prints usage instructions.
20 rodolico 22
- `readConfig`: Reads router configuration from JSON file.
23
- `writeConfig`: Writes router configuration to JSON file with proper permissions (0600, root-only).
24
- `trim`: Removes leading/trailing whitespace from strings.
25
- `menuSelect`: Displays interactive menu and captures user selection.
26
- `selectOvpnIndex`: Retrieves VPN provider list from router and allows selection.
27
- `editFormats`: Manages the formats hash for creating multiple OpenVPN configurations.
28
- `editRouter`: Main editor for router configuration fields.
16 rodolico 29
 
20 rodolico 30
**Formats Configuration:**
31
- Each format defines a unique OpenVPN configuration variant.
32
- Format structure: `{ "filename": "ROUTER_USER_format.ovpn", "additionalStrings": "proto tcp\\nport 443" }`
33
- ROUTER and USER placeholders in filename are replaced with actual values.
34
- `additionalStrings` supports `\n` for line breaks in configuration directives.
35
 
36
**Usage:**
37
```bash
38
./configure [configfile]
39
```
40
(defaults to `routers.json` in script directory if not specified)
41
 
16 rodolico 42
---
43
 
44
## 2. index.php
45
 
46
**Purpose:**
20 rodolico 47
- Web interface for users to authenticate and retrieve their TOTP QR code and OpenVPN configurations.
48
- Validates user credentials against password hashes stored in `users.json`.
49
- Displays QR codes, TOTP seeds, and provides download links for VPN configurations.
16 rodolico 50
 
51
**Key Features:**
52
- 3-space indentation and camelCase variable naming for PHP code.
20 rodolico 53
- Password verification using bcrypt hashes.
54
- Support for multiple OpenVPN configuration files per user.
55
- Router selection dropdown populated from available routers.
56
- Request refresh functionality for router data.
57
- Automatic logging of successful logins to `logs/` directory.
16 rodolico 58
 
20 rodolico 59
**Main Functionality:**
60
- Reads configuration from `users.json` generated by `opnsense-totp-ovpn-export`.
61
- Displays QR code image for TOTP setup.
62
- Shows TOTP seed for manual entry into authenticator apps.
63
- Provides download links for OpenVPN configuration files:
64
  - Single file: displays one download link
65
  - Multiple files: displays separate links for each configuration
66
- Logs successful authentication with timestamp, IP address, and username.
67
- Displays last update timestamp for selected router.
68
- Allows users to request router data refresh via web interface.
16 rodolico 69
 
20 rodolico 70
**Log Files:**
71
- Location: `./logs/log_YYYY-MM-DD.log`
72
- Format: `YYYY-MM-DD HH:MM:SS<tab>IP_ADDRESS<tab>Success<tab>USERNAME<tab>`
73
- Log directory created automatically if it doesn't exist.
74
 
75
**Refresh Mechanism:**
76
- See `updaterouters.cron` for an example of allowing users to request a rescan of a router.
77
- Refresh request creates a marker file in `/tmp` that cron job processes.
78
 
16 rodolico 79
---
80
 
81
## 3. opnsense-totp-ovpn-export
82
 
83
**Purpose:**
20 rodolico 84
- Connects to OPNsense router via API to retrieve user credentials and VPN configurations.
85
- Generates QR codes for TOTP authentication.
86
- Creates OpenVPN configuration files based on defined formats.
87
- Updates `users.json` with current user data.
16 rodolico 88
 
89
**Key Features:**
90
- 3-space indentation and camelCase variable naming.
20 rodolico 91
- Lock file mechanism prevents concurrent execution and data corruption.
16 rodolico 92
- Clearly marked subroutine headers for maintainability.
20 rodolico 93
- Uses `GD::Barcode::QRcode` for QR code generation.
94
- Uses `MIME::Base64` for decoding OpenVPN files from API.
95
- Supports multiple OpenVPN configuration formats per user.
16 rodolico 96
 
97
**Main Subroutines:**
20 rodolico 98
- `slurpFile`: Reads entire file contents into a string.
99
- `dumpFile`: Writes string contents to a file.
100
- `loadConfig`: Loads router configuration from JSON file (`routers.json`).
101
- `loadUsers`: Loads user data from JSON file (`users.json`).
102
- `saveUsers`: Saves user data to JSON file with proper structure.
103
- `makeQR`: Generates QR code image from TOTP seed and account information.
104
- `makeVPNConfigFile`: Creates OpenVPN configuration file with custom settings:
105
  - Accepts filename template with ROUTER and USER placeholders
106
  - Expands `\n` in additionalStrings to actual newlines
107
  - Appends configuration directives to base VPN config
108
  - Returns relative path to created file
109
- `cleanOldDataFiles`: Removes obsolete data files from previous runs.
16 rodolico 110
 
20 rodolico 111
**Format Processing:**
112
- Reads formats from `routers.json` for each router.
113
- Iterates through all defined formats to create multiple .ovpn files.
114
- Each format specifies:
115
  - Filename template (e.g., `ROUTER_USER_tcp.ovpn`)
116
  - Additional configuration strings (e.g., `proto tcp\nport 443`)
117
- Falls back to default single file if no formats defined.
118
- Stores result as array if multiple files, or string if single file.
119
 
120
**Lock File:**
121
- Location: `/tmp/opnsense.lock`
122
- Prevents concurrent execution.
123
- Retries: 6 attempts with 10-second intervals.
124
- Automatically removed on successful completion.
125
 
126
**Usage:**
127
```bash
128
./opnsense-totp-ovpn-export <routername>
129
```
130
Must be run as root.
131
 
16 rodolico 132
---
133
 
134
## 4. opnsense.pm (Perl Module)
135
 
136
**Purpose:**
137
- Provides an object-oriented interface for interacting with the OPNSense API.
138
- Handles API requests using either curl or LWP::UserAgent, with SSL verification disabled for compatibility.
139
 
140
**Key Features:**
141
- 3-space indentation and camelCase variable naming.
142
- Clearly marked subroutine headers for maintainability.
143
- Flexible API request handling (curl or LWP).
144
 
145
**Main Subroutines:**
146
- `new`: Constructor for the Opnsense object.
147
- `apiRequest`: Dispatches API requests to curl or LWP handler.
148
- `apiRequestCurl`: Handles API requests using curl.
149
- `apiRequestLwp`: Handles API requests using LWP::UserAgent.
20 rodolico 150
- `getVpnProviders`: Retrieves list of VPN providers from router.
151
- `getVpnUsers`: Gets VPN user certificates from router.
152
- `getAllUsers`: Retrieves all users with authentication data (including TOTP secrets).
153
- `getVpnConfig`: Exports VPN configuration file for a specific certificate.
16 rodolico 154
 
155
---
156
 
157
## Datafile Structures
158
 
20 rodolico 159
**user configuration file (users.json)**
160
- Contains sensitive information (TOTP codes and password hashes).
161
- Used by both `index.php` and `opnsense-totp-ovpn-export`.
162
- Should be owned by root with read access for web server.
163
- JSON structure:
16 rodolico 164
```json
20 rodolico 165
{
166
  "router1": {
167
    "qrLocationFileystem": "/file/system/path/to/qrcode/directory",
168
    "qrLocation": "./qrcodes",
169
    "ovpnLocationFileSystem": "/file/system/path/to/ovpn/directory",
170
    "ovpnLocation": "./openvpn_configs",
171
    "lastUpdate": 1759817343,
172
    "users": {
173
      "user1": {
174
        "password": "<bcrypt hashed password>",
175
        "otp_seed": "<TOTP seed in base32>",
176
        "certs": ["cert-id-1"],
177
        "qrFile": "./qrcodes/router1_user1.png",
178
        "ovpnFile": "./openvpn_configs/router1_user1.ovpn"
16 rodolico 179
      },
20 rodolico 180
      "user2": {
181
        "password": "<bcrypt hashed password>",
182
        "otp_seed": "<TOTP seed in base32>",
183
        "certs": ["cert-id-2"],
184
        "qrFile": "./qrcodes/router1_user2.png",
185
        "ovpnFile": [
186
          "./openvpn_configs/router1_user2_tcp.ovpn",
187
          "./openvpn_configs/router1_user2_udp.ovpn"
188
        ]
16 rodolico 189
      }
20 rodolico 190
    }
191
  },
192
  "router2": {
193
    ...
194
  }
195
}
16 rodolico 196
```
20 rodolico 197
 
198
**Note on ovpnFile:**
199
- Can be a string (single configuration file) or array (multiple configuration files).
200
- Multiple files are automatically displayed as separate download links in web interface.
201
 
202
**router configuration file (routers.json)**
203
- Contains apiSecret and apiKey that provide access to router management.
204
- Owned by root with permissions 0600 (root-only access).
205
- JSON structure:
16 rodolico 206
```json
207
{
208
  "routername": {
20 rodolico 209
    "url": "https://192.168.1.1",
210
    "apiKey": "public API key from OPNsense Router",
211
    "apiSecret": "secret API key from OPNsense Router",
212
    "ovpnIndex": "1",
213
    "template": "PlainOpenVPN",
214
    "hostname": "router.example.org",
215
    "localPort": "1194",
216
    "downloadToken": "random-token-string",
217
    "formats": {
218
      "tcp": {
219
        "filename": "ROUTER_USER_tcp.ovpn",
220
        "additionalStrings": "proto tcp\\nport 443\\nauth-nocache"
221
      },
222
      "udp": {
223
        "filename": "ROUTER_USER_udp.ovpn",
224
        "additionalStrings": "proto udp\\nport 1194\\nauth-nocache"
225
      },
226
      "tcp-alt": {
227
        "filename": "ROUTER_USER_tcp_alt.ovpn",
228
        "additionalStrings": "proto tcp\\nport 8443\\nauth-nocache"
229
      }
230
    }
16 rodolico 231
  }
232
}
233
```
234
 
20 rodolico 235
**Configuration Fields:**
236
- `url`: Router management URL (how scripts connect).
237
- `apiKey` / `apiSecret`: API credentials from OPNsense.
238
- `ovpnIndex`: VPN provider index (single digit in older systems, long hash in newer versions).
239
- `template`: OpenVPN template type (typically "PlainOpenVPN").
240
- `hostname`: Hostname written to .ovpn files (external VPN endpoint).
241
- `localPort`: Port number written to .ovpn files (can be overridden by format strings).
242
- `downloadToken`: Authentication token for download requests.
243
- `formats`: Hash of configuration format definitions:
244
  - Key: Format identifier (e.g., "tcp", "udp", "tcp-alt")
245
  - Value: Hash with `filename` template and `additionalStrings` for configuration directives
16 rodolico 246
 
20 rodolico 247
---
248
 
16 rodolico 249
# Workflow Summary
250
 
20 rodolico 251
1. **Initial Setup:**
252
   - Obtain API key and secret from OPNsense router (System → Access → Users).
253
   - Run `./configure` to set up router configuration.
254
   - Define OpenVPN formats if multiple configurations needed.
255
 
256
2. **Data Export:**
257
   - Run `./opnsense-totp-ovpn-export routername` to:
258
     - Connect to router via API
259
     - Retrieve user credentials and TOTP secrets
260
     - Generate QR code images
261
     - Create OpenVPN configuration files for all formats
262
     - Update `users.json`
263
 
264
3. **User Access:**
265
   - Users navigate to `index.php` web interface.
266
   - Log in with username, password, and router selection.
267
   - View QR code for TOTP setup (first time).
268
   - Download OpenVPN configuration file(s).
269
   - Import .ovpn file into OpenVPN client.
270
 
271
4. **Automated Updates:**
272
   - Set up cron job to run `opnsense-totp-ovpn-export` periodically.
273
   - Users can request on-demand refresh via web interface.
274
   - See `updaterouters.cron` for implementation example.
275
 
276
---
277
 
16 rodolico 278
# Security Note
20 rodolico 279
 
280
All scripts treat OTP secrets and user data as sensitive information:
281
 
282
- **Router configuration:** Root-only access (0600 permissions).
283
- **User configuration:** Root-owned, world-readable for web server.
284
- **QR codes:** Pre-generated and stored on filesystem (consider access restrictions).
285
- **Passwords:** Hashed using bcrypt with cost factor 10-11.
286
- **API credentials:** Stored in protected configuration file.
287
- **Logs:** Record successful authentication attempts with timestamps and IP addresses.
288
 
289
**Recommendations:**
290
- Host system on secure internal network or behind firewall.
291
- Use HTTPS for web interface.
292
- Implement web server access controls (.htaccess, IP restrictions).
293
- Regularly review access logs.
294
- Use dedicated API keys with minimal required permissions.
295
- Consider implementing rate limiting for login attempts.
296
 
297
---
298
 
299
# Version Information
300
 
301
- **configure:** v1.1.0
302
- **opnsense-totp-ovpn-export:** v1.1.0
303
- **index.php:** v1.3.0
304
- **opnsense.pm:** (see module for version)
305
 
306
See individual script headers for detailed version history and changes.
307