3.8 KiB
| title | aliases | tags | sources | created | updated | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Nginx Proxy Manager — Admin Password Reset via SQLite bcrypt Injection |
|
|
|
2026-04-29 | 2026-04-29 |
Nginx Proxy Manager — Admin Password Reset via SQLite bcrypt Injection
When locked out of Nginx Proxy Manager (NPM), the admin password can be reset by directly modifying the SQLite database. NPM stores user credentials in a database.sqlite file. The process requires stopping NPM first to prevent data corruption, generating a bcrypt hash of the new password, and writing it into the auth table.
Key Points
- NPM must be stopped before editing the DB — modifying a live SQLite file risks corruption
- Always back up the database first —
cp database.sqlite database.sqlite.bak.YYYY-MM-DD - Password is stored as a bcrypt hash in the
authtable - Restart NPM after the edit — NPM reads credentials from the DB at runtime
- Default admin email is typically
admin@example.com; in this homelab it isadmin@ai-impress.com
Details
Step-by-Step Reset Process
# 1. Stop NPM to prevent corruption
docker compose stop npm
# 2. Navigate to the NPM data directory
cd /opt/npm/data
# 3. Back up the database
cp database.sqlite database.sqlite.bak.$(date +%Y-%m-%d)
# 4. Generate a bcrypt hash for the new password
# Option A: Python
python3 -c "import bcrypt; print(bcrypt.hashpw(b'admin', bcrypt.gensalt(rounds=10)).decode())"
# Option B: Node.js (if available)
node -e "const bcrypt = require('bcrypt'); bcrypt.hash('admin', 10).then(h => console.log(h))"
# Option C: use htpasswd
htpasswd -bnBC 10 "" admin | tr -d ':\n'
# 5. Open the database
sqlite3 database.sqlite
# 6. Find the admin user row
SELECT id, name, email FROM user;
-- or, depending on NPM version:
SELECT id, name, email FROM auth;
# 7. Update the password hash
UPDATE auth SET secret = '$2b$10$YOUR_BCRYPT_HASH_HERE' WHERE identity = 'admin@ai-impress.com';
-- or if the table is named 'user':
UPDATE user SET password = '$2b$10$YOUR_BCRYPT_HASH_HERE' WHERE email = 'admin@ai-impress.com';
# 8. Verify
SELECT identity, secret FROM auth;
# 9. Exit and restart NPM
.quit
docker compose start npm
Table Structure Notes
NPM's SQLite schema varies slightly between versions. In most installations:
- Table
authcontains columns:id,identity(email),secret(bcrypt hash),type - Table
usercontains:id,name,email,password
Run .tables and PRAGMA table_info(auth); inside sqlite3 to confirm the structure for your version before updating.
Why NPM Must Be Stopped
SQLite uses file-level locking. NPM holds a write lock on database.sqlite while running. Editing the file while NPM is active can corrupt the WAL (write-ahead log) or leave the DB in an inconsistent state. Always stop the container, edit, then restart.
Homelab Context
This procedure was used when the NPM admin account at admin@ai-impress.com became inaccessible. Password was reset to admin (minimum viable for internal homelab use). NPM fronts all internal services via reverse proxy and SSL termination at /opt/npm/.
Related Concepts
- wiki/concepts/adguard-dns-rewrites-homelab — AdGuard DNS rewrites pointing *.ai-impress.com to NPM's IP
- wiki/concepts/authentik-homelab-tradeoffs — NPM auth_request integration removed when Authentik was retired
- wiki/concepts/prowlarr-flaresolverr-get-only — similar SQLite direct-edit pattern for Prowlarr cookie injection
- wiki/homelab/_index — homelab infrastructure; NPM as reverse proxy gateway
Sources
- daily/2026-04-29.md — NPM lockout; database.sqlite backup; bcrypt hash injection into auth table; email admin@ai-impress.com; password reset to "admin"; NPM must be stopped during edit