Files
OpenVPN-Monitoring-Simple/DOCS/Changes/2026-09-30_Admin_Username_Change.md
iclaoudezinandClaude Sonnet 5.5 9b2882d5f4 Docs: concise README, split deployment guides, add change records
- 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>
2026-09-30 12:12:09 +00:00

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 references users.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