Added user tab and oauth2, streamlined readme
This commit is contained in:
191
README.md
191
README.md
@@ -17,69 +17,39 @@ This project provides a web UI for Caddy Server, eliminating the need to manuall
|
||||
**Key features:**
|
||||
- Reverse proxy configuration with upstream pools and custom headers
|
||||
- HTTP basic auth access lists
|
||||
- OAuth2/OIDC authentication support
|
||||
- Automatic HTTPS via Caddy's ACME (Let's Encrypt) with Cloudflare DNS-01 support
|
||||
- Custom certificate import (internal CA, wildcards, etc.)
|
||||
- Audit logging of all configuration changes
|
||||
- Login rate limiting and session management
|
||||
- Built with Next.js 16, React 19, Drizzle ORM, and TypeScript
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```bash
|
||||
git clone https://github.com/fuomag9/caddy-proxy-manager.git
|
||||
cd caddy-proxy-manager
|
||||
cp .env.example .env
|
||||
# Edit .env with your credentials (see Configuration section below)
|
||||
# Edit .env with your credentials
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
The stack includes:
|
||||
- `web` - Next.js app with SQLite database
|
||||
- `caddy` - Custom Caddy build (includes Cloudflare DNS and Layer4 modules)
|
||||
Access at `http://localhost:3000/login`
|
||||
|
||||
Data is persisted in:
|
||||
- `./data` - Application database and certificates
|
||||
- `./caddy-data` - ACME certificates
|
||||
- `./caddy-config` - Caddy runtime config
|
||||
|
||||
### Local Development
|
||||
|
||||
```bash
|
||||
npm install
|
||||
cp .env.example .env
|
||||
# Edit .env with your credentials
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Access the interface at `http://localhost:3000/login`.
|
||||
|
||||
Login attempts are rate-limited (5 attempts per 5 minutes, 15 minute lockout after repeated failures).
|
||||
Data persists in `./data`, `./caddy-data`, and `./caddy-config`.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
| Module | Description |
|
||||
|--------|-------------|
|
||||
| **Proxy Hosts** | HTTP/HTTPS reverse proxies with upstream pools, custom headers, Authentik forward auth |
|
||||
| **Redirects** | 301/302 redirects with optional query string preservation |
|
||||
| **Dead Hosts** | Maintenance pages with custom status codes |
|
||||
| **Access Lists** | HTTP basic auth user management for proxy hosts |
|
||||
| **Certificates** | Custom SSL/TLS certificate import (Caddy auto-manages Let's Encrypt) |
|
||||
| **Settings** | ACME email and Cloudflare API configuration |
|
||||
| **Audit Log** | Chronological log of all configuration changes |
|
||||
|
||||
**Technical Stack:**
|
||||
- Next.js 16 App Router with React 19
|
||||
- Material UI (dark theme)
|
||||
- Drizzle ORM with SQLite
|
||||
- Direct integration with Caddy Admin API
|
||||
- Cloudflare DNS-01 challenge support
|
||||
- bcrypt for access list password hashing
|
||||
- **Proxy Hosts** - Reverse proxies with custom headers and upstream pools
|
||||
- **Redirects** - 301/302 redirects
|
||||
- **Dead Hosts** - Maintenance pages
|
||||
- **Access Lists** - HTTP basic auth
|
||||
- **Certificates** - Custom SSL/TLS import (automatic Let's Encrypt via Caddy)
|
||||
- **Settings** - ACME email and Cloudflare DNS-01 configuration
|
||||
- **Audit Log** - Configuration change tracking
|
||||
|
||||
---
|
||||
|
||||
@@ -99,153 +69,68 @@ Login attempts are rate-limited (5 attempts per 5 minutes, 15 minute lockout aft
|
||||
| `LOGIN_MAX_ATTEMPTS` | Max login attempts before rate limit | `5` | No |
|
||||
| `LOGIN_WINDOW_MS` | Rate limit window in milliseconds | `300000` (5 min) | No |
|
||||
| `LOGIN_BLOCK_MS` | Rate limit block duration in milliseconds | `900000` (15 min) | No |
|
||||
| `OAUTH_ENABLED` | Enable OAuth2/OIDC authentication | `false` | No |
|
||||
| `OAUTH_PROVIDER_NAME` | Display name for OAuth provider | `OAuth2` | No |
|
||||
| `OAUTH_CLIENT_ID` | OAuth2 client ID | None | No |
|
||||
| `OAUTH_CLIENT_SECRET` | OAuth2 client secret | None | No |
|
||||
| `OAUTH_ISSUER` | OAuth2 OIDC issuer URL | None | No |
|
||||
|
||||
**Production Security Requirements (Strictly Enforced):**
|
||||
**Production Requirements:**
|
||||
- `SESSION_SECRET`: 32+ characters (`openssl rand -base64 32`)
|
||||
- `ADMIN_PASSWORD`: 12+ chars with uppercase, lowercase, numbers, and special characters
|
||||
|
||||
The application will **fail to start** in production if these requirements are not met:
|
||||
|
||||
- **`SESSION_SECRET`**:
|
||||
- Must be at least 32 characters long
|
||||
- Cannot be a known placeholder value
|
||||
- Generate with: `openssl rand -base64 32`
|
||||
|
||||
- **`ADMIN_USERNAME`**:
|
||||
- Must be set (any value is acceptable, including `admin`)
|
||||
|
||||
- **`ADMIN_PASSWORD`**:
|
||||
- Minimum 12 characters
|
||||
- Must include uppercase letters (A-Z)
|
||||
- Must include lowercase letters (a-z)
|
||||
- Must include numbers (0-9)
|
||||
- Must include special characters (!@#$%^&* etc.)
|
||||
- Cannot be `admin` in production
|
||||
|
||||
**Development Mode:**
|
||||
- Default credentials (`admin`/`admin`) are allowed in development
|
||||
- Set `NODE_ENV=development` to use relaxed validation
|
||||
Development mode (`NODE_ENV=development`) allows default `admin`/`admin` credentials.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
caddy-proxy-manager/
|
||||
├── app/ # Next.js App Router
|
||||
│ ├── (auth)/ # Authentication pages
|
||||
│ ├── (dashboard)/ # Dashboard and feature modules
|
||||
│ ├── api/ # API routes
|
||||
│ └── providers.tsx # Theme providers
|
||||
├── src/lib/ # Core business logic
|
||||
│ ├── models/ # Database models
|
||||
│ ├── caddy/ # Caddy config generation
|
||||
│ └── auth/ # Authentication
|
||||
├── drizzle/ # Database migrations
|
||||
├── docker/
|
||||
│ ├── web/ # Next.js Dockerfile
|
||||
│ └── caddy/ # Custom Caddy build
|
||||
├── docker-compose.yml # Deployment stack
|
||||
└── data/ # SQLite + certificates
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
**Authentication:**
|
||||
- Production mode enforces strong credentials (12+ chars, mixed case, numbers, special characters)
|
||||
- Application refuses to start with weak passwords in production
|
||||
- Production enforces strong passwords (12+ chars, mixed case, numbers, special characters)
|
||||
- 32+ character session secrets required
|
||||
- Login rate limiting: 5 attempts per 5 minutes, 15 minute lockout
|
||||
- Single admin user model
|
||||
|
||||
**Data Protection:**
|
||||
- Imported certificates stored with `0600` permissions
|
||||
- Session encryption with validated secrets
|
||||
- API tokens redacted after initial entry
|
||||
- Login rate limiting: 5 attempts per 5 minutes
|
||||
- Audit trail for all configuration changes
|
||||
- HSTS headers applied to managed hosts
|
||||
- Supports OAuth2/OIDC for SSO
|
||||
|
||||
**Production Setup:**
|
||||
```bash
|
||||
export SESSION_SECRET=$(openssl rand -base64 32)
|
||||
export ADMIN_USERNAME="admin"
|
||||
export ADMIN_PASSWORD="YourStr0ng-P@ssw0rd123!"
|
||||
echo "SESSION_SECRET=$SESSION_SECRET" > .env
|
||||
echo "ADMIN_USERNAME=$ADMIN_USERNAME" >> .env
|
||||
echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env
|
||||
chmod 600 .env
|
||||
```
|
||||
|
||||
**Development Mode:**
|
||||
```bash
|
||||
export NODE_ENV=development
|
||||
npm run dev
|
||||
# Login with admin/admin
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**Limitations:**
|
||||
- Certificate private keys stored unencrypted in SQLite
|
||||
- In-memory rate limiting (not suitable for multi-instance deployments)
|
||||
- No 2FA support
|
||||
|
||||
---
|
||||
|
||||
## Certificate Management
|
||||
|
||||
**Automatic HTTPS (Default):**
|
||||
Caddy automatically obtains Let's Encrypt certificates for all proxy hosts.
|
||||
|
||||
Caddy automatically obtains and renews Let's Encrypt certificates for all proxy hosts. Just add a domain and certificates are handled automatically.
|
||||
**Cloudflare DNS-01** (optional): Configure in Settings with a Cloudflare API token (`Zone.DNS:Edit` permissions).
|
||||
|
||||
For automatic certificates, configure Cloudflare DNS-01 in Settings (see below).
|
||||
|
||||
**Custom Certificates (Optional):**
|
||||
|
||||
Import your own certificates for:
|
||||
- Internal CA certificates
|
||||
- Certificates from other providers
|
||||
- Compliance requirements
|
||||
|
||||
To import:
|
||||
1. Go to Certificates page
|
||||
2. Click Import Custom Certificate
|
||||
3. Enter certificate name and domains
|
||||
4. Paste certificate PEM (full chain recommended)
|
||||
5. Paste private key PEM
|
||||
6. Assign to proxy hosts as needed
|
||||
|
||||
Note: Private keys are stored in SQLite without encryption.
|
||||
**Custom Certificates** (optional): Import your own certificates via the Certificates page. Private keys are stored unencrypted in SQLite.
|
||||
|
||||
---
|
||||
|
||||
## Cloudflare DNS-01 Setup
|
||||
## OAuth Authentication
|
||||
|
||||
For automatic certificates via DNS-01 challenge:
|
||||
Supports any OIDC-compliant provider (Authentik, Keycloak, Auth0, etc.).
|
||||
|
||||
1. Go to Settings
|
||||
2. Create a Cloudflare API token with `Zone.DNS:Edit` permissions
|
||||
3. Enter token (not displayed again after saving)
|
||||
4. Optionally add Zone ID / Account ID
|
||||
5. Set ACME email for certificate notifications
|
||||
```bash
|
||||
OAUTH_ENABLED=true
|
||||
OAUTH_PROVIDER_NAME="Authentik" # Display name
|
||||
OAUTH_CLIENT_ID=your-client-id
|
||||
OAUTH_CLIENT_SECRET=your-client-secret
|
||||
OAUTH_ISSUER=https://auth.example.com/application/o/app/
|
||||
```
|
||||
|
||||
To revoke: Select "Remove existing token" in Settings.
|
||||
**Redirect URI**: `{BASE_URL}/api/auth/callback/oauth2`
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `npm run dev` | Development server with hot reload |
|
||||
| `npm run build` | Production build |
|
||||
| `npm start` | Run production server |
|
||||
| `npm run typecheck` | TypeScript type checking |
|
||||
| `npm run db:migrate` | Apply database migrations |
|
||||
|
||||
**Notes:**
|
||||
- Drizzle migrations are in `/drizzle`
|
||||
- Caddy config regenerated on each mutation and pushed via Admin API
|
||||
- Rate limiting is in-memory (not suitable for multi-instance deployments)
|
||||
- Single admin user architecture
|
||||
OAuth login appears on the login page alongside credentials. Users can link OAuth to existing accounts from the Profile page.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user