Subversion Repositories web_pages

Rev

Rev 16 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 16 Rev 20
Line 1... Line 1...
1
# Program Overview: totp_opnsense Suite (Updated)
1
# Program Overview: totp_opnsense Suite
2
 
2
 
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 parsing to user authentication and QR code delivery.
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.
4
 
4
 
5
---
5
---
6
 
6
 
7
## 1. configure
7
## 1. configure
8
 
8
 
9
**Purpose:**
9
**Purpose:**
10
- Reads and parses OPNSense configuration files.
10
- Interactive tool for managing router configurations stored in `routers.json`.
11
- Loads settings and credentials for API access and OpenVPN configuration.
11
- Allows adding, editing, and removing router definitions.
12
- Provides utility subs for configuration management.
12
- Manages API credentials, VPN provider settings, and OpenVPN configuration formats.
13
 
13
 
14
**Key Features:**
14
**Key Features:**
15
- 3-space indentation and camelCase variable naming.
15
- 3-space indentation and camelCase variable naming.
16
- Modular subroutines with headers for clarity.
16
- Menu-driven interface for easy configuration management.
17
- Loads the custom `Opnsense` Perl module for API interaction.
17
- Supports multiple OpenVPN configuration formats per router.
-
 
18
- Direct integration with OPNsense API to select VPN providers.
18
 
19
 
19
**Main Subroutines:**
20
**Main Subroutines:**
20
- `usage`: Prints usage instructions.
21
- `usage`: Prints usage instructions.
21
- `readConfig`: Reads and parses the configuration file.
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.
-
 
29
 
-
 
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)
22
 
41
 
23
---
42
---
24
 
43
 
25
## 2. index.php
44
## 2. index.php
26
 
45
 
27
**Purpose:**
46
**Purpose:**
28
- Provides a web interface for users to log in and retrieve their TOTP QR code and OpenVPN configuration.
47
- Web interface for users to authenticate and retrieve their TOTP QR code and OpenVPN configurations.
29
- Validates user credentials and displays relevant information.
48
- Validates user credentials against password hashes stored in `users.json`.
-
 
49
- Displays QR codes, TOTP seeds, and provides download links for VPN configurations.
30
 
50
 
31
**Key Features:**
51
**Key Features:**
32
- 3-space indentation and camelCase variable naming for PHP code.
52
- 3-space indentation and camelCase variable naming for PHP code.
33
- Function headers for all major operations.
53
- Password verification using bcrypt hashes.
-
 
54
- Support for multiple OpenVPN configuration files per user.
34
- Reads configuration generated by `processOPNSense.pl`.
55
- Router selection dropdown populated from available routers.
-
 
56
- Request refresh functionality for router data.
-
 
57
- Automatic logging of successful logins to `logs/` directory.
35
 
58
 
36
**Main Functions:**
59
**Main Functionality:**
37
- `validateUser`: Validates user credentials against stored data.
60
- Reads configuration from `users.json` generated by `opnsense-totp-ovpn-export`.
38
- `displayQRCode`: Shows the QR code for the user's OTP.
61
- Displays QR code image for TOTP setup.
39
- `displayOTPSeed`: Displays the OTP seed for manual entry.
62
- Shows TOTP seed for manual entry into authenticator apps.
40
- `downloadOvpnFile`: Provides a download link for the user's OpenVPN configuration.
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.
41
- 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
68
- Allows users to request router data refresh via web interface.
-
 
69
 
-
 
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:**
42
- see `updaterouters.cron` for an example of allowing users to request a rescan of a router.
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.
43
 
78
 
44
---
79
---
45
 
80
 
46
## 3. opnsense-totp-ovpn-export
81
## 3. opnsense-totp-ovpn-export
47
 
82
 
48
**Purpose:**
83
**Purpose:**
49
- Creates a lock file and checks there is only one instance running to decrease chance of corruption
84
- Connects to OPNsense router via API to retrieve user credentials and VPN configurations.
50
- Loads router and user configuration from JSON files.
85
- Generates QR codes for TOTP authentication.
51
- Uses the `opnsense` module to interact with the OPNSense API.
86
- Creates OpenVPN configuration files based on defined formats.
52
- Generates QR codes and OpenVPN configuration files for users.
87
- Updates `users.json` with current user data.
53
 
88
 
54
**Key Features:**
89
**Key Features:**
55
- 3-space indentation and camelCase variable naming.
90
- 3-space indentation and camelCase variable naming.
-
 
91
- Lock file mechanism prevents concurrent execution and data corruption.
56
- Clearly marked subroutine headers for maintainability.
92
- Clearly marked subroutine headers for maintainability.
57
- Uses `GD::Barcode::QRcode` for QR code generation and `MIME::Base64` for decoding OpenVPN files.
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.
58
 
96
 
59
**Main Subroutines:**
97
**Main Subroutines:**
-
 
98
- `slurpFile`: Reads entire file contents into a string.
-
 
99
- `dumpFile`: Writes string contents to a file.
60
- `loadConfig`: Loads router configuration from a JSON file.
100
- `loadConfig`: Loads router configuration from JSON file (`routers.json`).
61
- `loadUsers`: Loads user data from a JSON file.
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.
-
 
110
 
-
 
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`)
62
- Additional subs for QR code and OpenVPN file management.
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.
63
 
131
 
64
---
132
---
65
 
133
 
66
## 4. opnsense.pm (Perl Module)
134
## 4. opnsense.pm (Perl Module)
67
 
135
 
Line 77... Line 145...
77
**Main Subroutines:**
145
**Main Subroutines:**
78
- `new`: Constructor for the Opnsense object.
146
- `new`: Constructor for the Opnsense object.
79
- `apiRequest`: Dispatches API requests to curl or LWP handler.
147
- `apiRequest`: Dispatches API requests to curl or LWP handler.
80
- `apiRequestCurl`: Handles API requests using curl.
148
- `apiRequestCurl`: Handles API requests using curl.
81
- `apiRequestLwp`: Handles API requests using LWP::UserAgent.
149
- `apiRequestLwp`: Handles API requests using LWP::UserAgent.
-
 
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.
82
 
154
 
83
---
155
---
84
 
156
 
85
## Datafile Structures
157
## Datafile Structures
86
 
158
 
87
**user configuration file**
159
**user configuration file (users.json)**
88
- The users configuration file (users.json) contains sensitive information (totp codes and password hash)
160
- Contains sensitive information (TOTP codes and password hashes).
89
- 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
161
- Used by both `index.php` and `opnsense-totp-ovpn-export`.
90
- The users configuration file is a json file with the following structure
162
- Should be owned by root with read access for web server.
-
 
163
- JSON structure:
91
```json
164
```json
92
   {
165
{
93
      "router1" : {
166
  "router1": {
94
         "qrLocationFileystem": "/file/system/path/to/qrcode/directory",
167
    "qrLocationFileystem": "/file/system/path/to/qrcode/directory",
95
         "qrLocation": "./qrcodes", # relative path to qrcode directory
168
    "qrLocation": "./qrcodes",
96
         "ovpnLocationFileSystem": "/file/system/path/to/ovpn/directory",
169
    "ovpnLocationFileSystem": "/file/system/path/to/ovpn/directory",
97
         "ovpnLocation": "./openvpn_configs", # relative path to ovpn file directory
170
    "ovpnLocation": "./openvpn_configs",
98
         "lastUpdate": 1759817343, # unix timestamp of last update
171
    "lastUpdate": 1759817343,
99
         "users" : {
172
    "users": {
100
            "user1" : {
173
      "user1": {
101
               "password" : "<hashed password>",
174
        "password": "<bcrypt hashed password>",
102
               "otp_seed" : "<otp seed>",
175
        "otp_seed": "<TOTP seed in base32>",
-
 
176
        "certs": ["cert-id-1"],
103
               "qrFile" : "<path to qr code image file (relative)>",
177
        "qrFile": "./qrcodes/router1_user1.png",
104
               "ovpnFile" : "<path to openvpn config file (relative)>"
178
        "ovpnFile": "./openvpn_configs/router1_user1.ovpn"
105
            },
-
 
106
            "user2" : {
-
 
107
               ...
-
 
108
            }
-
 
109
         }
-
 
110
      },
179
      },
111
      "router2" : {
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"
112
         ...
188
        ]
113
      }
189
      }
114
   }
190
    }
-
 
191
  },
-
 
192
  "router2": {
-
 
193
    ...
-
 
194
  }
-
 
195
}
115
```
196
```
-
 
197
 
116
**router configuration file**
198
**Note on ovpnFile:**
117
- The router configuration file contains the apiSecret and apiKey that could allow black hats to access and modify your router
199
- Can be a string (single configuration file) or array (multiple configuration files).
118
- The router configuration file is owned by root and set with permissions 0600, allowing access only to the root user
200
- Multiple files are automatically displayed as separate download links in web interface.
-
 
201
 
119
- The router configuration file is a json file with the following structure
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:
120
```json
206
```json
121
{
207
{
122
  "routername": {
208
  "routername": {
123
    "hostname": "router.example.org", # hostname written to ovpn files
209
    "url": "https://192.168.1.1",
124
    "localPort": "1194", # port number written to ovpn files
210
    "apiKey": "public API key from OPNsense Router",
125
    "apiSecret": "secret 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",
126
    "apiKey": "public API key from openSense Router",
216
    "downloadToken": "random-token-string",
-
 
217
    "formats": {
-
 
218
      "tcp": {
-
 
219
        "filename": "ROUTER_USER_tcp.ovpn",
127
    "url": "https://192.168.1.1", # how the scripts connect to router
220
        "additionalStrings": "proto tcp\\nport 443\\nauth-nocache"
-
 
221
      },
-
 
222
      "udp": {
-
 
223
        "filename": "ROUTER_USER_udp.ovpn",
128
    "template": "PlainOpenVPN", # valid template from opnsense, PlainOpenVPN is used exclusively so far
224
        "additionalStrings": "proto udp\\nport 1194\\nauth-nocache"
-
 
225
      },
-
 
226
      "tcp-alt": {
-
 
227
        "filename": "ROUTER_USER_tcp_alt.ovpn",
129
    "ovpnIndex": "1" # the index into the OVPN instance. In older systems, a single digit, in newer ones a long hash
228
        "additionalStrings": "proto tcp\\nport 8443\\nauth-nocache"
-
 
229
      }
-
 
230
    }
130
  }
231
  }
131
}
232
}
132
```
233
```
133
 
234
 
-
 
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
-
 
246
 
-
 
247
---
134
 
248
 
135
# Workflow Summary
249
# Workflow Summary
-
 
250
 
-
 
251
1. **Initial Setup:**
136
1. Get API Key from router and save
252
   - Obtain API key and secret from OPNsense router (System → Access → Users).
137
2. Run `configure` to set up router
253
   - Run `./configure` to set up router configuration.
-
 
254
   - Define OpenVPN formats if multiple configurations needed.
-
 
255
 
-
 
256
2. **Data Export:**
138
3. run `opnsense-totp-ovpn-export` to export the .ovpn files and generate the totp QR code image
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.
139
4. Users access `index.php` to log in, view their QR code, OTP seed, and download OpenVPN config.
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
---
140
 
277
 
141
# Security Note
278
# Security Note
-
 
279
 
142
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.
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