From e0fe0c4d342363f0566a40c1ebd88f73f81c349d Mon Sep 17 00:00:00 2001 From: DAProgs Date: Wed, 11 Mar 2026 10:43:23 -0400 Subject: [PATCH] Adding passwords and versionning --- README.md | 97 ++++++++++++++++++++++++++++++++++++++++++--- includes/auth.php | 57 ++++++++++++++++++++++++++ includes/footer.php | 4 ++ includes/style.php | 7 ++++ index.php | 7 ++++ login.php | 81 +++++++++++++++++++++++++++++++++++++ logout.php | 5 +++ nodes.php | 7 ++++ settings.php | 80 +++++++++++++++++++++++++++++++++++++ version.php | 2 + 10 files changed, 341 insertions(+), 6 deletions(-) create mode 100644 includes/auth.php create mode 100644 includes/footer.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 settings.php create mode 100644 version.php diff --git a/README.md b/README.md index 3558f34..9c4c89a 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,13 @@ Each portspoof_py instance runs independently and exposes a JSON API. portspoof_ 3. [Installation](#installation) 4. [Configuration](#configuration) 5. [Database schema](#database-schema) -6. [Adding nodes](#adding-nodes) -7. [Fetch cron](#fetch-cron) -8. [HTTP trigger endpoint](#http-trigger-endpoint) -9. [Dashboard](#dashboard) -10. [Upgrading](#upgrading) -11. [Troubleshooting](#troubleshooting) +6. [Web interface authentication](#web-interface-authentication) +7. [Adding nodes](#adding-nodes) +8. [Fetch cron](#fetch-cron) +9. [HTTP trigger endpoint](#http-trigger-endpoint) +10. [Dashboard](#dashboard) +11. [Upgrading](#upgrading) +12. [Troubleshooting](#troubleshooting) --- @@ -43,9 +44,16 @@ portspoof_concentrator/ ├── setup.php One-time install / migration script ├── index.php Aggregated dashboard ├── nodes.php Add / edit / delete portspoof_py nodes +├── login.php Login form +├── logout.php Session teardown +├── settings.php Change password via the web interface ├── trigger.php HTTP endpoint to trigger a fetch run (token-protected) +├── version.php Application version constant (bump on each release) +├── auth.passwd Live password hash (auto-created by settings.php, gitignore this) ├── includes/ +│ ├── auth.php Session management, login helpers, save_password() │ ├── db.php PDO singleton +│ ├── footer.php Shared footer with version number │ ├── functions.php Node CRUD, fetch helpers, run_fetch(), dashboard queries │ └── style.php Shared CSS (included inline by both pages) └── cron/ @@ -81,6 +89,19 @@ define('DB_USER', 'portspoof'); define('DB_PASS', 'strongpassword'); // match the password above ``` +Set a UI password (see [Web interface authentication](#web-interface-authentication) for details): + +```bash +php -r "echo password_hash('yourpassword', PASSWORD_DEFAULT) . PHP_EOL;" +``` + +Paste the output into `config.php`: + +```php +define('UI_USER', 'admin'); +define('UI_PASS_HASH', '$2y$12$...'); +``` + See [Configuration](#configuration) for the full list of constants. ### 4. Run the setup script @@ -161,6 +182,8 @@ All tunables are constants in `config.php`. | `FETCH_TIMEOUT` | `10` | cURL timeout (seconds) for outbound calls to portspoof_py nodes | | `FETCH_LIMIT` | `500` | Maximum connections pulled from a node per fetch run | | `TRIGGER_TOKEN` | `''` | Secret token for `trigger.php`. Empty string disables the endpoint entirely | +| `UI_USER` | `'admin'` | Username for the web interface | +| `UI_PASS_HASH` | `''` | Bcrypt hash of the UI password. Empty string disables authentication | --- @@ -203,6 +226,68 @@ One row per connection event ingested from any node. --- +## Web interface authentication + +The dashboard and node management pages are protected by a session-based login form. Authentication is controlled by two constants in `config.php`. + +### Setup + +Generate a bcrypt hash of your chosen password: + +```bash +php -r "echo password_hash('yourpassword', PASSWORD_DEFAULT) . PHP_EOL;" +``` + +Add it to `config.php`: + +```php +define('UI_USER', 'admin'); // change to any username you like +define('UI_PASS_HASH', '$2y$12$…'); // paste the hash from the command above +``` + +Restart your web server / PHP-FPM if it caches config files. On the next visit to `index.php` or `nodes.php` you will be redirected to `login.php`. + +### Changing the password + +**Via the web interface (recommended):** navigate to **Settings** in the nav bar, enter your current password and the new one, and submit. The new hash is written to `auth.passwd` in the project root and takes effect immediately — no server restart needed. + +**Via the CLI:** re-run the hash command and replace the value in `config.php` (or write directly to `auth.passwd`): + +```bash +php -r "echo password_hash('newpassword', PASSWORD_DEFAULT) . PHP_EOL;" > /var/www/portspoof_concentrator/auth.passwd +``` + +Existing sessions remain valid until they expire or the user signs out. + +### Password storage precedence + +On each request, `auth.php` checks for `auth.passwd` in the project root. If the file exists its contents are used as the hash; otherwise it falls back to `UI_PASS_HASH` in `config.php`. This means: + +- First-time setup: set `UI_PASS_HASH` in `config.php`. +- After the first web-interface password change: `auth.passwd` takes over and `UI_PASS_HASH` is ignored. + +Add `auth.passwd` to your `.gitignore` to avoid committing credentials: + +``` +auth.passwd +``` + +### Disabling authentication + +Set `UI_PASS_HASH` to an empty string: + +```php +define('UI_PASS_HASH', ''); +``` + +All pages become publicly accessible. Only do this on a private network or when another layer (firewall, VPN, web server auth) protects the interface. + +### Sign out + +A **Sign out** link appears in the navigation bar on every page when authentication is enabled. Visiting `logout.php` directly also works. + +--- + ## Adding nodes Open `http://yourserver/nodes.php` and fill in the form. diff --git a/includes/auth.php b/includes/auth.php new file mode 100644 index 0000000..534f136 --- /dev/null +++ b/includes/auth.php @@ -0,0 +1,57 @@ + + diff --git a/includes/style.php b/includes/style.php index bc9361d..9a866d9 100644 --- a/includes/style.php +++ b/includes/style.php @@ -86,3 +86,10 @@ button[type=submit]:hover { opacity: .85; } .bar { height: 6px; background: var(--accent); border-radius: 3px; min-width: 2px; } form { max-width: 480px; } + +footer { + text-align: center; padding: 1.25rem; margin-top: 1rem; + font-size: .75rem; color: var(--muted); + border-top: 1px solid var(--border); +} +footer span { color: var(--accent); } diff --git a/index.php b/index.php index 102b4a4..6520d37 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,6 @@ Dashboard Nodes + Settings + + Sign out +
@@ -195,5 +201,6 @@ $max_port_cnt = $t_ports ? max(array_column($t_ports, 'cnt')) : 1;

+ diff --git a/login.php b/login.php new file mode 100644 index 0000000..c8b6c64 --- /dev/null +++ b/login.php @@ -0,0 +1,81 @@ + + + + + + +Login – portspoof concentrator + + + +
+ +
+ + + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..d3d7ac1 --- /dev/null +++ b/logout.php @@ -0,0 +1,5 @@ + Dashboard Nodes + Settings + + Sign out +
@@ -163,5 +169,6 @@ if (isset($_GET['edit'])) {
+ diff --git a/settings.php b/settings.php new file mode 100644 index 0000000..ae331da --- /dev/null +++ b/settings.php @@ -0,0 +1,80 @@ + + + + + + +Settings – portspoof concentrator + + + +
+

portspoofconcentrator

+ +
+
+ + +
+ + +
+ + +
+

Change password

+ +

Authentication is disabled. Set UI_PASS_HASH in config.php to enable it.

+ +
+ + + + +
+ +
+ +
+ + + diff --git a/version.php b/version.php new file mode 100644 index 0000000..038b7a7 --- /dev/null +++ b/version.php @@ -0,0 +1,2 @@ +