- README: short overview, quick start, config table and links. - DOCS/General: Deployment_Docker.md and Deployment_Native.md (system services, HTTPS, host hardening); refresh Index.md. - DOCS/Changes: security hardening, admin username change and egress via Hysteria2 with results and verification. - Drop mentions of the built-in admin/password account. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2.2 KiB
2.2 KiB
Admin username change (2026-09-30)
Goal: get rid of the well-known admin login and of the built-in admin/password account.
Design
- The JWT carries
user_id, not the name, and no other table referencesusers.username, so a rename does not invalidate sessions. - Changing the username requires the current password and, when 2FA is enabled, a valid OTP. Wrong password/OTP counts toward the login rate limit.
Changes
| Area | Change |
|---|---|
API (APP_CORE/openvpn_api_v3.py) |
POST /api/auth/change-username: body new_username, current_password, optional otp. Rules: ^[A-Za-z][A-Za-z0-9_.-]{2,31}$, reserved names rejected (admin, administrator, root, user, test, guest), case-insensitive uniqueness (409). Helper _current_user_id() |
| 2FA | setup_2fa puts the real username into the authenticator URI (was hardcoded admin) |
| Bootstrap | ensure_default_admin no longer creates admin/password. With an empty users table it creates a user only from OVPMON_INITIAL_ADMIN_USER / OVPMON_INITIAL_ADMIN_PASSWORD; otherwise it logs an error |
UI (Account.vue) |
"Change Username" button and modal (OTP field shown only if 2FA is on) |
UI (App.vue) |
Header name synced from /user/me on start and on route change, and on the ovpmon-user-changed event; fixed the stale/hardcoded Admin |
Existing installations
Rename directly in the DB (stop nothing; sessions stay valid):
import sqlite3
c = sqlite3.connect("/var/lib/ovpmon/openvpn_monitor.db")
c.execute("UPDATE users SET username=? WHERE username='admin'", ("<new-login>",)); c.commit()
Take a DB backup first. Recovery when users is empty: temporarily set OVPMON_INITIAL_ADMIN_USER/PASSWORD, restart ovpmon-api, then remove the variables.
Verification
| Check | Result |
|---|---|
Login with new name / with admin |
200 / 401 |
| No token | 401 |
admin, root, ab, a/b, 1abc |
400 |
| Wrong current password | 401 |
| Rename to another valid name and back | 200, login with the new name works |
Empty users without / with seed variables (DB copy) |
no user / user created |
| Manual UI test (password change, 2FA enable) | passed; header-name bug found and fixed |