HTTP Auth Backend
Deploying the auth-worker on Cloudflare Workers for centralized authentication
The HTTP auth backend (auth-worker) is a Cloudflare Worker that provides centralized authentication and user management for multiple trojan-rs server nodes. It includes a web admin dashboard, per-node traffic tracking, and a REST API.
Architecture
┌───────────────┐ ┌───────────────┐
│ trojan-server │────▶│ │
│ (tokyo-1) │ │ │
└───────────────┘ │ auth-worker │──▶ D1 Database
┌───────────────┐ │ (Cloudflare) │──▶ KV Cache
│ trojan-server │────▶│ │
│ (us-west) │ │ │
└───────────────┘ └───────────────┘Each trojan-server node authenticates with the worker using a unique node token. The worker verifies client passwords against a D1 database and caches results in KV for performance.
Prerequisites
- Cloudflare account (Workers free tier is sufficient)
- Wrangler CLI (
npm install -g wrangler) - Rust toolchain (for building the worker)
- Node.js (for building the admin dashboard)
Deployment
1. Create Cloudflare Resources
# Create the D1 database
npx wrangler d1 create auth-db
# Create the KV namespace (verify cache)
npx wrangler kv namespace create CACHENote the database_id and KV id from the output.
2. Configure Wrangler
Copy the example configuration and fill in your IDs:
cd auth-worker
cp wrangler.example.toml wrangler.tomlEdit wrangler.toml and replace the placeholder IDs:
[[d1_databases]]
binding = "DB"
database_name = "auth-db"
database_id = "your-d1-database-id"
[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-namespace-id"3. Set the Admin Token
The admin token protects the /admin/* endpoints and the web dashboard:
npx wrangler secret put ADMIN_TOKEN
# Enter a strong random token when prompted4. Deploy
npx wrangler deployThis builds both the Rust worker and the React admin dashboard, then deploys to Cloudflare.
5. Initialize the Database
After deployment, run the migration to create tables:
curl -X POST https://your-worker.workers.dev/admin/migrate \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"Admin Dashboard
The worker serves a single-page admin dashboard at the root URL. Log in with your admin token to:
- Manage users (add, edit, enable/disable, delete)
- Manage server nodes (add, rotate tokens, enable/disable)
- View per-node traffic logs
Connecting a Server Node
1. Register the Node
In the admin dashboard, add a new node with a descriptive name (e.g., tokyo-1). A unique token is generated automatically — copy it.
2. Configure trojan-rs
Add the HTTP auth backend to your server configuration:
[auth]
http_url = "https://your-worker.workers.dev"
http_node_token = "the-generated-node-token"Or pass it via CLI flags:
trojan server -c config.toml \
--auth-database http://your-worker.workers.dev \
--auth-node-token "the-generated-node-token"The server sends the node token as a Bearer token in the Authorization header on every /verify and /traffic request. The worker identifies the node, records its IP, and updates last_seen.
API Reference
Wire Endpoints
These are called by trojan-rs server nodes. Both require a valid node token.
POST /verify
Verifies a client password hash. Returns user status or an error.
Request:
{ "hash": "56-byte-sha224-hex-string" }Response (success):
{
"Ok": {
"user_id": "1",
"metadata": {
"traffic_limit": 107374182400,
"traffic_used": 5368709120,
"expires_at": 0,
"enabled": true
}
}
}Response (error):
{ "Err": "NotFound" }Possible errors: NotFound, TrafficExceeded, Expired, Disabled.
The worker checks KV cache first, then falls back to D1. Cache entries are invalidated when user data changes.
POST /traffic
Reports traffic consumed by a user.
Request:
{ "user_id": "1", "bytes": 1048576 }Updates the user's traffic_used counter and inserts a row in traffic_logs with the reporting node's ID.
Admin Endpoints
All admin endpoints require the admin token as a Bearer token.
Users
| Method | Path | Description |
|---|---|---|
GET | /admin/users | List all users |
POST | /admin/users | Create user |
GET | /admin/users/:id | Get user by ID |
PATCH | /admin/users/:id | Update user fields |
DELETE | /admin/users/:id | Delete user |
Nodes
| Method | Path | Description |
|---|---|---|
GET | /admin/nodes | List all nodes |
POST | /admin/nodes | Register a new node |
GET | /admin/nodes/:id | Get node by ID |
PATCH | /admin/nodes/:id | Update node (name, enabled) |
DELETE | /admin/nodes/:id | Delete node |
POST | /admin/nodes/:id/rotate | Regenerate node token |
Traffic Logs
| Method | Path | Description |
|---|---|---|
GET | /admin/traffic | List traffic logs |
GET | /admin/traffic?user_id=1 | Filter by user |
GET | /admin/traffic?node_id=2 | Filter by node |
Utility
| Method | Path | Description |
|---|---|---|
GET | /health | Health check |
GET | /admin/version | Worker version |
POST | /admin/migrate | Create/update database tables |
Wire Protocol
The /verify and /traffic endpoints support two serialization formats:
| Format | Content-Type | Description |
|---|---|---|
| Bincode | application/octet-stream | Compact binary (default, used by trojan-rs) |
| JSON | application/json | Human-readable (for debugging with curl) |
The format is auto-detected from the Content-Type header.
Database Schema
The worker uses three tables in D1:
users — Client accounts with traffic tracking:
| Column | Type | Description |
|---|---|---|
hash | TEXT | SHA-224 hex of password (unique) |
username | TEXT | Display name (unique) |
traffic_limit | INTEGER | Byte quota (0 = unlimited) |
traffic_used | INTEGER | Bytes consumed |
expires_at | INTEGER | Unix timestamp (0 = never) |
enabled | INTEGER | 1 = active, 0 = disabled |
nodes — Registered server nodes:
| Column | Type | Description |
|---|---|---|
name | TEXT | Human label (unique) |
token | TEXT | Bearer token (unique) |
enabled | INTEGER | 1 = active, 0 = disabled |
ip | TEXT | Last seen IP address |
last_seen | INTEGER | Last request timestamp |
traffic_logs — Per-user, per-node traffic history:
| Column | Type | Description |
|---|---|---|
user_id | INTEGER | Foreign key to users |
node_id | INTEGER | Foreign key to nodes |
bytes | INTEGER | Bytes reported |
recorded_at | INTEGER | Unix timestamp |