93 lines
3.8 KiB
Markdown
93 lines
3.8 KiB
Markdown
---
|
|
title: "Nginx Proxy Manager — Admin Password Reset via SQLite bcrypt Injection"
|
|
aliases: [npm-admin-reset, npm-password-reset, npm-sqlite-reset]
|
|
tags: [nginx-proxy-manager, npm, sqlite, homelab, docker, admin]
|
|
sources:
|
|
- "daily/2026-04-29.md"
|
|
created: 2026-04-29
|
|
updated: 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 `auth` table
|
|
- **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 is `admin@ai-impress.com`
|
|
|
|
## Details
|
|
|
|
### Step-by-Step Reset Process
|
|
|
|
```bash
|
|
# 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 `auth` contains columns: `id`, `identity` (email), `secret` (bcrypt hash), `type`
|
|
- Table `user` contains: `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
|