-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreadme.txt
More file actions
381 lines (300 loc) · 16.4 KB
/
Copy pathreadme.txt
File metadata and controls
381 lines (300 loc) · 16.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# DBTN Live Traffic
Contributors: your-wordpress-org-username
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.0.21
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
A real-time server-log dashboard with secure downloads, Turnstile validation, and local MaxMind GeoIP lookups.
## Description
DBTN Live Traffic is a standalone WordPress plugin that provides a real-time
server-log dashboard, Cloudflare Turnstile visitor validation, daily
validated-visitor counts, secure log downloads, and local MaxMind GeoLite2
City lookups.
It is designed solely for WPMU DEV hosting environments and single-site
WordPress installations. WordPress Multisite is not currently supported because
server logs may contain traffic from multiple sites in the same network.
## Screenshots
The following screenshots show the main administrator features of DBTN Live Traffic.
### Live Traffic dashboard

The Live Traffic panel displays parsed access-log entries with location,
status, duration, browser information, and sorting/filtering controls.
### IP inspection

Clicking an IP displays additional information about the address.

Administrators can view recent traffic from a specific IP address.
### Sorting and filtering

Traffic rows can be sorted by IP, path, browser/bot, or location.
### Log reports

The 403-404 tab summarizes blocked and missing requests from the previous day.

The WAF tab displays recent ModSecurity events in a readable format.
### Secure downloads

The Download tab lists available log files and streams downloads through
WordPress authentication.
## Features
### Live Traffic dashboard
- Adds a top-level **Live Traffic** admin menu for users with the
`manage_options` capability.
- Reads the current access log and refreshes the table every five seconds.
- Supports pause/resume and selectable tail sizes from 50 to 2,500 lines.
- Bridges the midnight UTC rotation with cached lines from `access.log.1.gz`,
keeping the display populated while the new `access.log` is still short.
- Filters static assets, the current administrator's traffic, validation REST
requests, and HTTP status groups (2xx, 3xx, and 4xx).
- Filters the displayed rows by a case-insensitive full-URL search.
- Displays request time, IP or known WordPress username, GeoIP location,
method, request path and referrer, response status, response size and request
duration, and a summarized browser or bot user agent.
- Highlights Turnstile-validated visitors, supports configurable URL/text/regular-expression row highlights, and flags non-canonical hostnames.
- Sorts the visible rows by IP, path, browser/bot, or location when the
corresponding column header is selected.
- Lets administrators inspect recent requests from a selected IP.
- Lets administrators inspect or search recent requests for a URL path;
query strings are ignored when matching non-root paths.
- Copies the visible IP- or URL-specific traffic rows to the clipboard as
tab-separated data.
- Provides a browser-side IP information card and copy-IP action using
`ipinfo.io`.
### Log reports
| Tab | Data source | Description |
|---|---|---|
| Live Traffic | `access.log` | Real-time, parsed access-log rows with visitor and location data |
| 403-404 | `access.log.1.gz` | Yesterday's compressed-log 403/404 totals, grouped by request and hostname |
| PHP Errors | `php_errors.log` | PHP errors from the last seven days |
| PHP Slow | `php_slow.log` | PHP slow-log entries from the last seven days, grouped into timestamped blocks |
| WAF Log | `waf.log` | Recent ModSecurity JSON events rendered as readable cards |
| WP-Cron | `wp-cron.log` | Recent cron runs grouped by timestamp, status, and details |
| Visitors | WordPress options | Latest 100 daily validated-human counts; shown only when Turnstile is configured |
| Download | Configured logs directory | Readable files with name, size, modified time, and a download action |
Report tabs can be refreshed manually without reloading the admin page.
### Secure log downloads
- Lists readable regular files directly inside the configured logs directory.
- Shows each file's name, size, and last-modified time.
- Streams the selected file through WordPress instead of exposing the logs
directory as a public URL.
- Requires the `manage_options` capability and a valid per-download nonce.
- Rejects directory traversal, nested paths, missing files, unreadable files,
and files that resolve outside the configured logs directory.
### Cloudflare Turnstile visitor validation
- Loads the invisible Turnstile client on public pages when a site key is
configured; server-side validation also requires the secret key.
- Defers the first challenge until visitor interaction, with a three-second
fallback for visitors who do not interact.
- Stores validated IPs in WordPress transients for seven days.
- Issues a signed, HttpOnly, SameSite=Lax `dbtn_human` grant cookie after a
successful challenge.
- Reasserts the signed grant during later page activity so a validated visitor
remains identified when Private Relay, mobile networks, or Wi-Fi transitions
change the visitor's egress IP.
- Associates a logged-in WordPress username with its current IP for eight hours
so the Live Traffic table can identify that user.
### Daily validated visitors
- Counts each validated IP once per WordPress calendar day.
- Stores counts as `dbtn_human_visits_YYYY-MM-DD` options.
- Displays today's count in the **Visitors** tab label.
- Shows the latest 100 daily records in a table sortable by date or count.
### Credential validation and settings
The **Live Traffic → Settings** page provides:
- Cloudflare Turnstile site key and secret key fields.
- A **Validate Turnstile** action that tests the entered, unsaved keys.
- MaxMind account ID and license key fields.
- A **Validate MaxMind** action that tests the entered, unsaved credentials.
- An optional absolute logs-directory override.
- Ordered traffic-row highlight rules with Contains, Exact, or Regular Expression matching, a background color, and optional bold text.
- Configuration status and client-IP diagnostics.
All settings are stored in the `dbtn_lt_settings` WordPress option. Secret
values are used server-side and are not exposed to public visitors.
### MaxMind GeoLite2 City
- Downloads the GeoLite2 City database with configured MaxMind credentials.
- Installs database updates atomically into
`GeoLite2/GeoLite2-City.mmdb`.
- Checks the remote `Last-Modified` value before downloading an update.
- Schedules a weekly WordPress cron update and queues an immediate update when
the admin dashboard detects a newer database.
- Shows the installed database build date and update status in the toolbar.
- Caches each IP lookup in a WordPress transient for 24 hours.
- Emails the WordPress administration address after a successful database
update.
## Requirements
- PHP 8.1 or newer
- WordPress 6.4 or newer
- Server logs in the formats expected by the report parsers
- Cloudflare Turnstile keys for visitor validation and the Visitors report
- A MaxMind account ID and license key for GeoLite2 City installation and
updates
- WordPress cron, outbound HTTPS, and a writable `GeoLite2/` directory for
automatic database updates
- A single-site WordPress installation
- WordPress Multisite is not currently supported
The client-IP resolver prefers `CF-Connecting-IP` and falls back to
`REMOTE_ADDR`. Configure the web server or trusted proxy layer so visitors
cannot spoof forwarded IP headers.
## Installation
1. Copy the plugin folder to `wp-content/plugins/dbtn-live-traffic/`.
2. Activate **DBTN Live Traffic** in **WP Admin → Plugins**.
3. Open **Live Traffic → Settings**.
4. Enter and validate the Cloudflare Turnstile credentials.
5. Enter and validate the MaxMind credentials.
6. Save the settings.
7. If the logs are not in the default location, enter their absolute directory
path in **Logs Directory**.
### Turnstile setup
1. Open the [Cloudflare Turnstile dashboard](https://dash.cloudflare.com/?to=/:account/turnstile).
2. Create a widget with **Widget type** set to **Invisible**.
3. Add the site's hostname to the widget's allowed hostnames.
4. Enter the site key and secret key on the plugin settings page.
5. Select **Validate Turnstile**, then save the settings.
### Log directory
By default, logs are read from a `logs` directory one level above the document
root:
```text
dirname($_SERVER['DOCUMENT_ROOT'])/logs/
```
For example, a document root of `/home/user/public_html` resolves to
`/home/user/logs/`.
To use a different location, enter the absolute path in
**Live Traffic → Settings → Logs Directory**. A trailing slash is optional.
## REST API
Public validation routes use a Turnstile token or signed human-grant cookie.
All admin routes require the `manage_options` capability.
| Method | Route | Access | Purpose |
|---|---|---|---|
| POST | `/dbtn/v2/validation/ip` | Public; Turnstile token required | Validate the current IP and issue a human-grant cookie |
| POST | `/dbtn/v2/validation/assert` | Public; signed cookie required | Re-mark the current IP after an IP change |
| POST | `/dbtn/v2/admin/credentials/turnstile` | Administrator | Validate entered Turnstile credentials |
| POST | `/dbtn/v2/admin/credentials/maxmind` | Administrator | Validate entered MaxMind credentials |
| GET | `/dbtn/v2/admin/live-traffic` | Administrator | Return parsed live access-log rows |
| GET | `/dbtn/v2/admin/ip-traffic` | Administrator | Return recent access-log rows for one IP |
| GET | `/dbtn/v2/admin/url-traffic` | Administrator | Return recent access-log rows for one URL path |
| GET | `/dbtn/v2/admin/log-403-404` | Administrator | Return the 403/404 report |
| GET | `/dbtn/v2/admin/php-errors` | Administrator | Return the PHP errors report |
| GET | `/dbtn/v2/admin/php-slow` | Administrator | Return the PHP slow-log report |
| GET | `/dbtn/v2/admin/waf-log` | Administrator | Return the WAF report |
| GET | `/dbtn/v2/admin/wp-cron` | Administrator | Return the WP-Cron report |
| GET | `/dbtn/v2/admin/visitors` | Administrator; Turnstile configured | Return daily validated-visitor counts |
| GET | `/dbtn/v2/admin/downloads` | Administrator | List readable files in the configured logs directory |
Actual file downloads use WordPress's authenticated `admin-post.php` handler
with the `dbtn_traffic_download` action and a download nonce.
## File structure
The following map lists the plugin's first-party files that are loaded or
served by version 1.0.20. The `vendor/` directory contains bundled third-party
Composer dependencies and is summarized separately.
```text
dbtn-live-traffic/
├── dbtn-live-traffic.php
│ Plugin metadata, constants, class loading, and bootstrap
├── README.md
│ Plugin documentation
├── admin/
│ ├── class-dbtn-lt-admin.php
│ │ Admin menus, settings, validation controls, and diagnostics
│ ├── class-dbtn-geoip.php
│ │ Local GeoLite2 City lookup and 24-hour result caching
│ └── traffic/
│ ├── README.md
│ │ Internal Traffic module documentation
│ ├── class-dbtn-traffic.php
│ │ Dashboard shell, tabs, toolbar, asset loading, and secure downloads
│ ├── class-dbtn-traffic-rest.php
│ │ Administrator REST routes, tables, reports, and download listing
│ ├── class-dbtn-traffic-log-reader.php
│ │ Access-log parsing, tailing, user-agent summaries, and statuses
│ ├── class-dbtn-traffic-report-403-404.php
│ │ Compressed access-log 403/404 report
│ ├── class-dbtn-traffic-report-php-errors.php
│ │ Seven-day PHP error report
│ ├── class-dbtn-traffic-report-php-slow.php
│ │ Seven-day PHP slow-log report
│ ├── class-dbtn-traffic-report-waf.php
│ │ ModSecurity JSON/WAF report
│ ├── class-dbtn-traffic-report-wp-cron.php
│ │ Grouped WP-Cron report
│ ├── class-dbtn-traffic-report-visitors.php
│ │ Daily validated-human report
│ ├── css/
│ │ └── dbtn-traffic.css
│ │ Dashboard and report styles
│ └── js/
│ └── dbtn-traffic.js
│ Polling, tabs, filters, searches, sorting, details, and copying
├── assets/
│ ├── css/
│ │ └── dbtn-credential-validation.css
│ │ Settings-page credential status styles
│ └── js/
│ ├── dbtn-passport.js
│ │ Invisible Turnstile loader and token creation
│ ├── dbtn-visitor-validate.js
│ │ First-time validation and signed-grant reassertion
│ └── dbtn-credential-validation.js
│ Turnstile and MaxMind settings-page validation
├── includes/
│ ├── class-dbtn-utilities.php
│ │ Client-IP resolution and Turnstile verification
│ ├── class-dbtn-geoip-update.php
│ │ GeoLite2 download, installation, version check, and WP-Cron update
│ ├── class-dbtn-visitor-validator.php
│ │ Validation state, daily counts, user/IP mapping, and signed grants
│ ├── class-dbtn-validation-rest.php
│ │ Public validation REST routes
│ ├── class-dbtn-credentials-rest.php
│ │ Administrator credential-validation REST routes
│ ├── class-dbtn-emails.php
│ │ Administration email helpers
│ └── class-dbtn-passport.php
│ Reserved compatibility class; browser token logic is in the JS file
├── GeoLite2/
│ └── GeoLite2-City.mmdb
│ Runtime database downloaded after MaxMind setup; not bundled initially
└── vendor/
├── autoload.php
├── composer/
├── geoip2/geoip2/
├── maxmind-db/reader/
└── maxmind/web-service-common/
Bundled Composer autoloader, certificate bundle, and MaxMind libraries
```
## Data storage
| Key or path | Storage | Lifetime or purpose |
|---|---|---|
| `dbtn_lt_settings` | WordPress option | Plugin settings |
| `dbtn_valid_ip_{md5}` | WordPress transient | Validated IP, seven days |
| `dbtn_login_ip_{md5}` | WordPress transient | Username associated with IP, eight hours |
| `dbtn_human_visit_YYYY-MM-DD_{md5}` | WordPress transient | Per-IP daily-count guard, until next WordPress midnight |
| `dbtn_human_visits_YYYY-MM-DD` | WordPress option | Daily validated-human total |
| `dbtn_geoip_{md5}` | WordPress transient | GeoIP lookup result, 24 hours |
| `dbtn_geoip_update_available` | WordPress transient | MaxMind update-check result, 15 minutes |
| `dbtn_human` | Browser cookie | Signed human grant, seven days |
| `GeoLite2/GeoLite2-City.mmdb` | Local file | Installed MaxMind GeoLite2 City database |
## Code quality
The first-party PHP source uses strict types, WordPress capability and nonce
checks for administrator actions, and WordPress escaping and sanitization APIs
at input and output boundaries.
The codebase is analyzed with PHPStan at level 8 using WordPress stubs and
follows WordPress Coding Standards through PHPCS.
## Changelog
### 1.0.21
- Renamed 'Hide Me' filter to 'Hide my ip' filter in Live Traffic. This filter hides
traffic from the same ip as the user watching Live Traffic.
### 1.0.20
- Added F-key click filtering: hold **F** and click an IP address, request
path, browser/bot, or location to show only matching traffic; repeat the
action to clear that filter.
- Added a **Type** selector with **All**, **Bots**, and **Verified** options for
viewing all traffic, unverified traffic, or Turnstile-verified visitors.
### 1.0.19
- Added configurable live-traffic row highlights with Contains, Exact, and Regular Expression matching, selectable background colors, and optional bold text.

### 1.0.18
- The most recently selected Line Count setting is saved in local storage and reused in subsequent sessions.
### 1.0.17
- Clicking a request path now copies it without filtering or pausing live traffic.
- Option-clicking a path copies the path and referrer on separate lines.
- Clicking a request time copies the full row as tab-separated values.