[优化] 更新文档

This commit is contained in:
ryan
2026-06-01 23:19:32 +08:00
parent a850b0a188
commit 2525664013
76 changed files with 6493 additions and 2497 deletions
-73
View File
@@ -1,73 +0,0 @@
# Connect Agent
OpenFlare Agent runs on proxy nodes. It handles registration, heartbeat, configuration sync, OpenResty file writes, validation, reload, rollback, and self-update.
## Authentication
| Method | Use case |
| --- | --- |
| `agent_token` | The node already exists or has a dedicated credential |
| `discovery_token` | First-time auto-registration; Server exchanges it for a node token |
At least one of them is required.
## Install Script
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
Or with discovery:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--discovery-token YOUR_DISCOVERY_TOKEN
```
## Configuration Example
```json
{
"server_url": "http://127.0.0.1:3000",
"agent_token": "replace-with-node-auth-token",
"data_dir": "./data",
"openresty_path": "openresty",
"openresty_observability_port": 18081,
"observability_replay_minutes": 15,
"heartbeat_interval": 10000,
"request_timeout": 10000
}
```
Without `openresty_path`, Agent runs `openresty` by default.
Agent self-update requires the GitHub Release to include both the target binary and a matching `.sha256` file. The downloaded binary is verified before it replaces the local executable.
## Docker
```bash
docker pull ghcr.io/rain-kl/openflare-agent:latest
docker rm -f openflare-agent 2>/dev/null || true
docker run -d --name openflare-agent --restart unless-stopped \
-p 80:80 -p 443:443 \
-e OPENFLARE_SERVER_URL=http://your-server:3000 \
-e OPENFLARE_AGENT_TOKEN=YOUR_AGENT_TOKEN \
ghcr.io/rain-kl/openflare-agent:latest
```
## Run from Source
```bash
cd openflare_agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
## Uninstall
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash
```
+27
View File
@@ -0,0 +1,27 @@
# Credits
OpenFlare is essentially a solution integration project. During its design and implementation phases, it drew inspiration from the exceptional concepts, architectural designs, and technical achievements of numerous open-source projects. Below are the key upstream open-source projects OpenFlare relies on for its core engine, security mechanisms, and backend/frontend system frameworks, along with our sincere thanks to these projects and their active communities.
---
### 1. OpenResty
* **Project Positioning**: A high-performance Web platform based on Nginx and Lua.
* **Role in OpenFlare**: Acts as the edge gateway for the global Data Plane. All public web traffic is received by OpenResty first, where high-concurrency HTTPS handshakes, WAF security rule evaluations, and PoW CC verification are performed before executing reverse proxies.
* **Project Link**: [OpenResty Official Website](https://openresty.org/)
### 2. FRP (Fast Reverse Proxy)
* **Project Positioning**: A high-performance reverse proxy application focused on intranet penetration.
* **Role in OpenFlare**: Serves as the underlying tunnel engine for the intranet penetration subsystem. The relay-side manager `openflare-relay` is responsible for running and scheduling the `frps` engine, while the intranet client `openflared` is responsible for generating TOML configurations locally and running the multiplexed `frpc` subprocesses.
* **Project Link**: [fatedier/frp (GitHub)](https://github.com/fatedier/frp)
---
### 3. Anubis (PoW Solution)
* **Project Positioning**: A lightweight human-machine verification and protection solution based on Proof of Work (PoW).
* **Role in OpenFlare**: Provides the core **seamless PoW CC challenge** capabilities for the gateway WAF.
---
### 4. gin-template
* **Project Positioning**: A modern full-stack development boilerplate based on Go Gin and frontend builds.
* **Role in OpenFlare**: Provided the standard, unified backend/frontend system architecture baseline for the OpenFlare control plane (Server).
-299
View File
@@ -1,299 +0,0 @@
# Deployment
You will learn: The recommended OpenFlare deployment model, Server and Agent requirements, source startup workflow, integration steps, upgrade paths, and uninstall entry points.
For production, use PostgreSQL for the Server database and set `SESSION_SECRET` explicitly. The recommended deployment method for the Agent is Docker deployment (i.e., running the Agent image that already includes OpenResty); it also supports shell-script installation or running manually.
## Topology
```text
Browser
|
v
OpenFlare Server :3000
|
| Agent API / heartbeat / config pull
v
OpenFlare Agent
|
v
OpenResty binary
|
v
Origin service
```
## Requirements
Server:
| Item | Requirement |
| --- | --- |
| Go | `1.25+`, source run only |
| Node.js | `18+`, frontend source build only |
| Database | Writable SQLite directory or reachable PostgreSQL instance |
| Port | `3000` by default |
Agent:
| Item | Requirement |
| --- | --- |
| OS | Install script supports Linux and macOS. systemd service is created only on Linux + systemd. |
| Architecture | `amd64` or `arm64` |
| OpenResty | Required for local Agent installs, or specified via `--openresty-path` |
| Docker | Required only when running the Agent Docker image |
| Network | Agent node must reach the Server URL |
| GeoIP | WAF regional rules use local MaxMind mmdb; Agent initializes a built-in library and updates it periodically |
[Needs confirmation: recommended production CPU, memory, and disk size]
## Docker Compose Server
Create `docker-compose.yml`:
```yaml
services:
postgres:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_DB: openflare
POSTGRES_USER: openflare
POSTGRES_PASSWORD: replace-with-strong-password
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U openflare -d openflare"]
interval: 10s
timeout: 5s
retries: 5
openflare:
image: ghcr.io/rain-kl/openflare:latest
container_name: openflare
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "3000:3000"
environment:
SESSION_SECRET: replace-with-a-long-random-string
DSN: postgres://openflare:replace-with-strong-password@postgres:5432/openflare?sslmode=disable
GIN_MODE: release
LOG_LEVEL: info
volumes:
- openflare-data:/data
volumes:
postgres-data:
openflare-data:
```
Start:
```bash
docker compose up -d
docker compose ps
docker compose logs -f openflare
```
Open `http://localhost:3000`. The default account is `root` / `123456`; change it immediately.
## Run Server from Source
Build the management UI first:
```bash
cd openflare_server/web
corepack enable
pnpm install
pnpm build
```
Then start Server:
```bash
cd openflare_server
export SESSION_SECRET='replace-with-a-long-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
# Optional: PostgreSQL takes precedence when set.
# export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
go run .
```
Default port is `3000`. You can also set it explicitly:
```bash
go run . --port 3000 --log-dir ./logs
```
## Run Agent in Docker (Recommended)
Docker deployment is the recommended deployment method for the Agent. In Docker deployments, directly run the Agent image. This image is built on top of the OpenResty image and includes both the Agent controller and the OpenResty binary. When `node_ip` is not explicitly configured, the Agent prioritizes obtaining the real public egress IP via a third-party API, avoiding registering the Docker bridge address as the node IP.
Mounting the configuration file:
```bash
docker pull ghcr.io/rain-kl/openflare-agent:latest
docker rm -f openflare-agent 2>/dev/null || true
docker run -d --name openflare-agent --restart unless-stopped \
-p 80:80 -p 443:443 \
-v openflare-agent-data:/data \
-v ./agent.json:/etc/openflare/agent.json:ro \
ghcr.io/rain-kl/openflare-agent:latest
```
Using environment variables:
```bash
docker pull ghcr.io/rain-kl/openflare-agent:latest
docker rm -f openflare-agent 2>/dev/null || true
docker run -d --name openflare-agent --restart unless-stopped \
-p 80:80 -p 443:443 \
-e OPENFLARE_SERVER_URL=http://your-server:3000 \
-e OPENFLARE_AGENT_TOKEN=YOUR_AGENT_TOKEN \
ghcr.io/rain-kl/openflare-agent:latest
```
## Connect Agent (Script Installation)
In addition to Docker deployment, you can also deploy the Agent on the local host using our installation script.
With `discovery_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--discovery-token YOUR_DISCOVERY_TOKEN
```
With node-specific `agent_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
Supported options:
| Option | Description |
| --- | --- |
| `--server-url` | Server URL, required |
| `--discovery-token` | First-registration token, mutually exclusive with `--agent-token` |
| `--agent-token` | Node-specific token, mutually exclusive with `--discovery-token` |
| `--install-dir` | Install directory, default `/opt/openflare-agent` |
| `--openresty-path` | OpenResty binary path, auto-detected when omitted |
| `--repo` | GitHub repository for Agent downloads, default `Rain-kl/OpenFlare` |
| `--no-service` | Do not create a systemd service |
Check status:
```bash
systemctl status openflare-agent
journalctl -u openflare-agent -f
```
## Run Agent Manually
From source:
```bash
cd openflare_agent
export LOG_LEVEL='info'
go run ./cmd/agent -config /path/to/agent.json
```
Build and run:
```bash
cd openflare_agent
go build -o openflare-agent ./cmd/agent
export LOG_LEVEL='info'
./openflare-agent -config /path/to/agent.json
```
Minimal `agent.json`:
```json
{
"server_url": "http://127.0.0.1:3000",
"agent_token": "replace-with-node-auth-token",
"data_dir": "./data",
"openresty_path": "openresty",
"heartbeat_interval": 10000,
"request_timeout": 10000
}
```
When `openresty_path` is not configured, Agent runs `openresty`.
By default, the Agent will attempt to upgrade to a WebSocket after a successful HTTP heartbeat. When the upgrade succeeds, the Server immediately notifies the Agent of any configuration publications or activations; if the WebSocket cannot be established or is unexpectedly disconnected, the Agent automatically falls back to HTTP heartbeat synchronization.
WAF regional rules rely on the Agent's local `GeoLite2-Country.mmdb`. Upon startup, the Agent initializes a built-in database at `data_dir/etc/openflare/GeoLite2-Country.mmdb` and attempts to update it periodically based on configuration; update failures only record warnings, and do not affect configuration synchronization or OpenResty reload.
## Minimal Integration Flow
1. Start Server and sign in.
2. Prepare `agent_token` or `discovery_token`.
3. Start Agent and confirm the node is online.
4. Create an enabled site configuration.
5. Publish and activate a new version.
6. Check node detail and apply logs.
7. Visit the domain or verify with `curl`.
## Upgrade and Uninstall
Server:
* Root users can check and upgrade stable Server releases from the top bar.
* Preview releases can be checked manually.
* Binary upload upgrades are also supported.
Agent:
* Agents follow stable releases by default.
* Agent autoupdate requires the GitHub Release to include both the target binary and a matching `.sha256` checksum file; the download must pass SHA-256 validation before the local executable is replaced.
* The install script can be rerun to reinstall or upgrade.
* Preview upgrades require manual action.
Uninstall Agent:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/uninstall-agent.sh | bash
```
The uninstall script stops Agent and removes the systemd service and install directory. It does not remove the local OpenResty installation.
## Validation Commands
Server:
```bash
cd openflare_server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Agent:
```bash
cd openflare_agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Frontend:
```bash
cd openflare_server/web
pnpm build
```
Swagger:
```bash
go install github.com/swaggo/swag/cmd/swag@v1.16.4
cd openflare_server
swag init -g main.go -o docs
```
-188
View File
@@ -1,188 +0,0 @@
# Local Development
You will learn how to set up a local OpenFlare development environment, run the Server, Agent, and frontend, execute tests and builds, and understand the boundaries contributors must follow.
This page is for contributors. Product boundaries, data model constraints, API conventions, and frontend layering are defined in [Development Constraints](../design/development.md). This page focuses on executable local workflows.
## Repository Layout
| Path | Responsibility |
| --- | --- |
| `openflare_server` | Gin + GORM + SQLite/PostgreSQL monolithic control plane |
| `openflare_server/web` | Next.js management UI, statically exported and served by the Go Server |
| `openflare_agent` | Go Agent binary running on nodes |
| `scripts` | Agent install and uninstall scripts |
| `docs` | VitePress documentation site |
## Requirements
| Tool | Requirement |
| --- | --- |
| Go | `1.25+` |
| Node.js | `18+` |
| pnpm | Use `corepack enable` to follow the project-declared version |
| Docker | Needed for Server containers, local integration, and the Agent Docker image |
| OpenResty | Needed when running Agent locally |
| PostgreSQL | Optional. The Server uses SQLite when PostgreSQL is not configured. |
## Install Frontend Dependencies
```bash
cd openflare_server/web
corepack enable
pnpm install
```
Build static assets served by the Go Server:
```bash
pnpm build
```
## Run the Server
SQLite:
```bash
cd openflare_server
export SESSION_SECRET='dev-session-secret'
export SQLITE_PATH='./openflare-dev.db'
export LOG_LEVEL='debug'
go run .
```
PostgreSQL:
```bash
cd openflare_server
export SESSION_SECRET='dev-session-secret'
export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
export LOG_LEVEL='debug'
go run .
```
Default URL:
```text
http://localhost:3000
```
Default account: `root` / `123456`.
## Run the Frontend Dev Server
The frontend dev server listens on `3001` by default and proxies API requests through `NEXT_DEV_BACKEND_URL`:
```bash
cd openflare_server/web
export NEXT_DEV_BACKEND_URL='http://127.0.0.1:3000'
pnpm dev
```
Open:
```text
http://localhost:3001
```
## Run the Agent
Create a local `agent.json`:
```json
{
"server_url": "http://127.0.0.1:3000",
"agent_token": "replace-with-node-auth-token",
"data_dir": "./data",
"heartbeat_interval": 10000,
"request_timeout": 10000
}
```
Run:
```bash
cd openflare_agent
export LOG_LEVEL='debug'
go run ./cmd/agent -config ./agent.json
```
When `openresty_path` is not configured, the Agent runs `openresty`. For debugging, set `openresty_path`, `main_config_path`, `route_config_path`, `access_log_path`, `cert_dir`, `lua_dir`, and `runtime_config_dir` as needed.
## Tests
Server:
```bash
cd openflare_server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Agent:
```bash
cd openflare_agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Frontend:
```bash
cd openflare_server/web
pnpm lint
pnpm typecheck
pnpm test
pnpm test:e2e
```
Docs:
```bash
cd docs
pnpm build
```
## Builds
Frontend static assets:
```bash
cd openflare_server/web
pnpm build
```
Server binary:
```bash
cd openflare_server
go build -o openflare-server .
```
Agent binary:
```bash
cd openflare_agent
go build -o openflare-agent ./cmd/agent
```
## Debugging Entrypoints
| Scenario | Command or Location |
| --- | --- |
| Server logs | `LOG_LEVEL=debug go run .` |
| Agent logs | `LOG_LEVEL=debug go run ./cmd/agent -config ./agent.json` |
| Swagger | `http://localhost:3000/swagger/index.html` |
| Frontend API proxy | `NEXT_DEV_BACKEND_URL=http://127.0.0.1:3000 pnpm dev` |
| OpenResty config test | `openresty -t -c ./data/etc/nginx/nginx.conf` |
## Change Acceptance
Before contributing, confirm that:
1. The change fits [Product Boundary](../design/index.md).
2. The implementation follows [Development Constraints](../design/development.md).
3. It does not break release, sync, rollback, or upgrade flows.
4. Documentation is updated when configuration, deployment, API, or product boundaries change.
5. Risky changes include tests or equivalent integration verification.
Database schema changes must bump the database version and include explicit migration and validation logic from the previous version.
+43 -43
View File
@@ -1,88 +1,88 @@
# Publishing Your First Configuration
# Publishing Your First Site
You will learn: How to create your first site configuration, bind origins and certificates, publish a configuration version, and confirm that the Agent has applied it.
You will learn: How to create your first website configuration, bind origins and certificates, publish the configuration version, and verify that the Agent applied it successfully.
OpenFlare's release link is centered on complete configuration versions. After modifying site configurations on the management console, you need to publish and activate the new version before the Agent pulls and applies it in subsequent heartbeats.
The publishing pipeline of OpenFlare centers on a complete configuration version snapshot. After modifying website configurations in the management console, you need to publish and activate the new version to let the Agent pull and apply it in the next heartbeat.
## Pre-release Check
## Pre-publish Checks
Confirm that the following conditions are met:
Verify that the following conditions are met:
| Project | Expectation |
| Item | Expectation |
| --- | --- |
| Server | Can log into the management console |
| Server | Management console is accessible and log-in succeeds |
| Agent | At least one node is online |
| Origin | The Agent node can access the origin address |
| Domain | The domain has been resolved to the OpenResty node, or you are ready to verify via local hosts / curl Host header |
| HTTPS | If HTTPS is required, the certificate has been uploaded or hosted |
| Origin | The Agent node can reach the origin server address |
| Domain | Domain is resolved to the OpenResty node, or prepared to verify via local `hosts` / `curl` Host header |
| HTTPS | If HTTPS is required, the certificate is uploaded or hosted |
## Create Site Configuration
## Create Website Configuration
When adding a site configuration on the management console, you need at least:
A new website configuration requires at least:
| Field | Description |
| --- | --- |
| Site Name | Unique business identifier; defaults to the primary domain when omitted |
| Domains | At least one domain; the first item is treated as the primary domain |
| Origin URL | Valid `http://` or `https://` upstream address |
| Enabled | Only enabled site configurations participate in release rendering |
| Website Name | Business unique identifier; the primary domain is used if left blank |
| Domain | At least one domain, where the first is treated as the primary domain |
| Origin Address | A valid `http://` or `https://` upstream address |
| Enabled Status | Only enabled website configurations will participate in publishing and rendering |
Example:
| Field | Example |
| --- | --- |
| Site Name | `app` |
| Domains | `app.example.com` |
| Origin URL | `http://10.0.0.20:8080` |
| Website Name | `app` |
| Domain | `app.example.com` |
| Origin Address | `http://10.0.0.20:8080` |
A domain can belong to only one site configuration. Site-level rate limits, reverse proxies, and cache configurations are shared by site.
A single domain can belong to only one website configuration. Rate limiting, reverse proxy, and caching parameters are shared site-wide.
## Bind Certificates
## Bind Certificate
HTTPS certificates are bound per domain. Domains not bound to certificates will not be automatically placed in `443 ssl` server blocks.
HTTPS certificates are bound by domain. Domains without a bound certificate will not be placed into `443 ssl` server blocks automatically.
If a site contains multiple domains, the publishing rendering will generate HTTPS configurations grouped by certificate and ensure all domains still belong to the same site snapshot.
If a website contains multiple domains, the rendering pipeline groups the HTTPS configurations by certificate while ensuring all domains belong to the same site snapshot.
## Publish and Activate
## Publish & Activate
Standard link:
Standard Pipeline:
```text
Modify rules -> Preview / View diff -> Publish -> Generate complete configuration version -> Activate version -> Agent pulls -> Local application -> Report result
Modify rules -> Preview / Diff -> Publish -> Generate complete version -> Activate version -> Agent pulls -> Local application -> Report result
```
When publishing, the Server reads all enabled site configurations, OpenResty main configuration templates, performance parameters, and cache parameters, renders the complete OpenResty configuration, calculates the `checksum`, writes to `config_versions`, and then switches the activated version.
During publication, the Server reads all enabled website configurations, the main OpenResty config templates, performance and cache parameters, rendering the complete OpenResty configuration and calculating its `checksum`, saving to `config_versions`, and switching the active version.
## Verify Results
After publishing, confirm on the management console:
Verify in the management console after publishing:
| Location | Expected Result |
| Position | Expected Result |
| --- | --- |
| Node List | Node is online |
| Node Details | The current version is consistent with the activated version |
| Apply Logs | The most recent application succeeded |
| Version Page | The new version is in the activated state |
| Node List | Node status is online |
| Node Details | Current version matches active version |
| Apply Logs | Most recent application succeeded |
| Version Page | The new version is currently active |
Confirm the Agent logs on the node:
Verify Agent logs on the node:
```bash
journalctl -u openflare-agent -n 100 --no-pager
```
Access using the domain:
Access via domain:
```bash
curl -I http://app.example.com
```
If the domain has not been officially resolved yet, you can temporarily specify the Host header to access the node IP:
If the domain has not been officially resolved, you can verify by specifying the Host header against the node IP:
```bash
curl -I -H 'Host: app.example.com' http://NODE_IP
```
HTTPS verification:
HTTPS Validation:
```bash
curl -I https://app.example.com
@@ -90,11 +90,11 @@ curl -I https://app.example.com
## Rollback
If the target version application fails and rolls back, the Agent will block repeated applications of the same `version + checksum` locally until the activated version or checksum on the control plane changes.
If a target version application fails and triggers a rollback, the Agent blocks repeated synchronization of the same failing `version + checksum` until the active version or checksum changes on the control plane.
To roll back to an older version:
Roll back to an older version:
1. Open the configuration version page.
2. Find the previous confirmed working historical version.
3. Reactivate that version.
4. View the node application records to confirm that the Agent applied it successfully.
1. Open the Configuration Versions page.
2. Locate the last known good historic version.
3. Re-activate that version.
4. Check the node application logs to verify that the Agent successfully applied the rollback.
+31 -24
View File
@@ -1,36 +1,43 @@
# Guide
# Guide Overview
You will learn how the OpenFlare documentation is organized, which pages to read for a first run, and where to find deployment, usage, troubleshooting, and development information.
You will learn: How the OpenFlare documentation is organized, which pages to read when running it for the first time, and where to start for deployment, usage, troubleshooting, and development.
OpenFlare is a self-hosted OpenResty control plane. It brings reverse proxy site configuration, immutable releases, Agent-based node sync, TLS certificates, and basic observability into one management UI for a single team or organization.
OpenFlare is a self-hosted OpenResty control plane. It integrates reverse proxy website configurations, configuration version publishing, Agent node synchronization, TLS certificates, and basic observability into a single management console, making it ideal for a single team or organization managing multiple proxy nodes.
## Recommended Path
## Recommended Reading Path
If you are new to OpenFlare, read these pages in order:
If you are new to OpenFlare, read the documents in the following order:
1. [Quick Start](./quick-start.md): start the Server with Docker Compose, sign in, and connect the first Agent.
2. [Usage](./usage.md): learn common operations for sites, origins, certificates, releases, rollbacks, and observability.
3. [Deployment](./deployment.md): run the Server and Agent in an environment closer to production.
4. [Configuration](../reference/configuration.md): look up Server environment variables, runtime options, and Agent configuration fields.
5. [Troubleshooting](./troubleshooting.md): debug login, database, node sync, OpenResty apply, and frontend build issues.
1. [Quick Start](./quick-start.md): Start the Server using Docker Compose, log into the management console, and connect your first Agent.
2. [Basic Usage](./usage.md): Learn common operations for website configs, origins, certificates, publishing, rollbacks, and observability.
3. [Tunnel & Intranet Penetration](./tunnel-usage.md): Learn to deploy Relay and Client to achieve secure, public IP-free reverse penetration.
4. [WAF Security Protection](./waf-usage.md): Master IP whitelisting/blacklisting, WAF auto IP group aggregation Expr rules, geographical restrictions, and PoW CC protection.
5. [WAF Auto IP Group Expressions](./waf-ip-group-expr.md): Write auto IP group Expr rules and learn keyword definitions and presets.
6. [Deployment Guide](../deployment/deployment.md): Deploy Server and Agent in closer-to-production environments.
7. [Configurations Reference](../reference/configuration.md): Check Server environment variables, runtime Options, and Agent configurations.
8. [Troubleshooting](./troubleshooting.md): Troubleshoot login, database, node sync, OpenResty application, and frontend build issues.
## Find by Role
## Role-Based Entrypoints
| Goal | Start Here |
| What do you want to do? | Recommended Entrance |
| --- | --- |
| Run the management UI in a few minutes | [Quick Start](./quick-start.md) |
| Publish the first reverse proxy site | [Publish First Site](./first-site.md) |
| Connect or reinstall a node Agent | [Connect Agent](./agent.md) |
| Start the Server from source | [Run Server](./server.md) |
| Configure GitHub or OIDC login | [SSO Login](./sso.md) |
| Upgrade the Server or Agent | [Upgrade and Maintenance](./upgrade.md) |
| Contribute code or fix issues | [Local Development](./development.md) and [Development Constraints](../design/development.md) |
| Understand architecture and releases | [Architecture](../design/architecture.md) and [Release Model](../design/release-model.md) |
| Run the console in under 5 minutes | [Quick Start](./quick-start.md) |
| Publish your first reverse proxy configuration | [Publish First Configuration](./first-site.md) |
| Configure intranet penetration mapping | [Tunnel & Intranet Penetration](./tunnel-usage.md) |
| Configure CC protection & IP group blocking | [WAF Security Protection](./waf-usage.md) |
| Write auto IP group aggregation rules | [WAF Auto IP Group Expressions](./waf-ip-group-expr.md) |
| Connect or reinstall a node Agent | [Access Agent](../deployment/agent.md) |
| Start Server from source code | [Launch Server](../deployment/server.md) |
| Configure GitHub or OIDC SSO | [SSO Login Configuration](./sso.md) |
| Upgrade Server or Agent | [Upgrade & Maintenance](../deployment/upgrade.md) |
| Participate in development or bug fixing | [Local Development](../design/development.md) and [Development Constraints](../../guildline/development-constraints.md) |
| Understand architecture and publishing | [System Architecture](../design/architecture.md) and [Agent & Publish Model](../design/agent-design.md) |
| View open-source references and credits | [Credits](./credits.md) |
## Documentation Areas
## Documentation Partitions
`guide/` is for users and operators. It provides executable steps from installation to daily operations.
`guide/` is oriented toward users and deployers, providing actionable steps from installation to daily operations.
`reference/` collects stable facts, such as configuration fields, commands, API conventions, and repository layout.
`reference/` collects stable facts such as configuration fields, commands, API response structures, and repository layout.
`design/` is for maintainers and contributors. It describes product boundaries, architecture, release model, and engineering constraints. Update the related design page before implementing changes that alter those boundaries.
`design/` is oriented toward maintainers and contributors, describing product boundaries, system architecture, Agent & publishing models, and engineering constraints. Before adding capabilities or changing boundaries, update the corresponding design document first.
+80 -62
View File
@@ -1,31 +1,32 @@
# Quick Start
You will learn how to start OpenFlare Server with Docker Compose, sign in for the first time, connect the first Agent, and verify that a configuration was published to a node.
You will learn: How to start OpenFlare Server using Docker Compose, complete your first login, connect your first Agent, and verify if a configuration has been published to the node.
The minimal OpenFlare setup contains:
The minimum running unit of OpenFlare consists of:
| Component | Responsibility |
| --- | --- |
| Server | Management UI, management API, Agent API, configuration rendering, release publishing, and state storage |
| Agent | Runs on proxy nodes, pulls configuration, writes OpenResty files, validates, and reloads |
| OpenResty | Receives traffic and proxies requests to origins |
| Server | Admin UI, Admin API, Agent API, configuration rendering, version publishing, and state storage. |
| Agent | Runs on the proxy node, pulls configurations, writes files for OpenResty, executes validations, and triggers reloads. |
| OpenResty | Receives actual traffic and reverse proxies it to origin servers. |
Agent controls OpenResty through the OpenResty binary. Local installs need an `openresty` executable on the node; Docker installs can run the Agent image that already includes OpenResty.
The Agent manages the runtime through the OpenResty binary. A local deployment requires the `openresty` executable to be already present on the node; a Docker deployment can directly run the Agent image containing built-in OpenResty.
## Requirements
## Environment Requirements
| Item | Requirement |
| --- | --- |
| Docker / Docker Compose | Used to start Server and PostgreSQL; also used if you run the Agent Docker image |
| OpenResty | Required for local Agent installs unless `--openresty-path` points to a custom binary |
| Reachable ports | Server listens on `3000` by default. Agent nodes must reach the Server URL. |
| Browser | Used to open the management UI |
| Docker / Docker Compose | Used to start Server and PostgreSQL; also used to run the Agent if using the Docker Agent image |
| OpenResty | Required to have the `openresty` executable when installing the Agent locally, or specify its path in the installation script |
| Reachable Ports | The Server listens on port `3000` by default; the Agent node needs to be able to reach the Server address |
| Browser | Used to access the management console |
[Needs confirmation: minimum recommended Docker and Docker Compose versions]
* **Docker**: `20.10.0+`
* **Docker Compose**: `2.0.0+`
## 1. Start Server
## 1. Start the Server
Create `docker-compose.yml` in an empty directory:
Create a `docker-compose.yml` file in an empty directory:
```yaml
services:
@@ -57,58 +58,62 @@ services:
DSN: postgres://openflare:replace-with-strong-password@postgres:5432/openflare?sslmode=disable
GIN_MODE: release
LOG_LEVEL: info
volumes:
- openflare-data:/data
volumes:
postgres-data:
openflare-data:
```
Start:
Start the services:
```bash
docker compose up -d
```
Verify:
Verify that the containers are running:
```bash
docker compose ps
docker compose logs -f openflare
```
When the `openflare` container is running and logs show `server listening`, open:
Once you see `server listening` in the logs and the `openflare` container status is running, access:
```text
http://localhost:3000
```
Default account:
Default credentials:
| Username | Password |
| --- | --- |
| `root` | `123456` |
Change the default password immediately after first login.
Please change the default password immediately after your first login.
## 2. Prepare an Agent Token
## 2. Prepare Agent Token
Agents can connect with either:
The Agent can be connected using one of two types of credentials:
| Credential | Use Case |
| Credential | Applicable Scenario |
| --- | --- |
| `discovery_token` | First-time automatic node registration. Server exchanges it for a node-specific token. |
| `agent_token` | A node-specific token created or assigned in the management UI. |
| `discovery_token` | Automatically registers a node for the first time, which the Server exchanges for a node-specific Token |
| `agent_token` | Node has already been created/allocated in the management console, directly uses this node-specific Token |
Prepare one of them in the management UI before continuing.
After preparing one of these credentials in the management console, proceed to the next step.
[Needs confirmation: exact UI menu path for creating or viewing `discovery_token` and node `agent_token`]
* **`discovery_token`** path: "System Settings" -> "Auto Registration"
* **`agent_token`** path: "Node Management" -> "Add Node"
## 3. Install/Run Agent
## 3. Install/Run the Agent
The recommended deployment method for the Agent is Docker deployment (i.e., running the Agent image that already includes OpenResty); it also supports shell-script installation on the local host.
The recommended Agent deployment method is using Docker (which runs the Agent image with built-in OpenResty); deploying the Agent locally on the host using the installation script is also supported.
### Option A: Run Agent in Docker (Recommended)
Run the Agent Docker image on the proxy node:
Run the Agent image directly on the proxy node:
```bash
docker pull ghcr.io/rain-kl/openflare-agent:latest
@@ -121,11 +126,11 @@ docker run -d --name openflare-agent --restart unless-stopped \
ghcr.io/rain-kl/openflare-agent:latest
```
### Option B: Run the Installation Script (Local Host)
### Option B: Execute Installation Script (Local Host Deployment)
Run the install script on the proxy node.
Execute the installation script on the proxy node.
With `discovery_token`:
Using the `discovery_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
@@ -133,7 +138,7 @@ curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/inst
--discovery-token YOUR_DISCOVERY_TOKEN
```
With node-specific `agent_token`:
Using the node-specific `agent_token`:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
@@ -143,46 +148,46 @@ curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/inst
The script defaults to:
| Item | Default |
| Item | Default Value |
| --- | --- |
| Install directory | `/opt/openflare-agent` |
| Config file | `/opt/openflare-agent/agent.json` |
| systemd service | `openflare-agent.service` |
| OpenResty path | Auto-detects `openresty` unless `--openresty-path` is provided |
| Install Directory | `/opt/openflare-agent` |
| Config File | `/opt/openflare-agent/agent.json` |
| systemd Service | `openflare-agent.service` |
| OpenResty Path | Automatically detects `openresty` if unspecified |
Check status:
Verify the Agent service status:
```bash
systemctl status openflare-agent
journalctl -u openflare-agent -f
```
If systemd is unavailable, the script prints a manual start command.
If systemd is not available on the OS, the script outputs manual startup commands instead.
## 4. Publish the First Configuration
## 4. Publish Your First Configuration
In the management UI:
Perform the following operations in the management console:
1. Create a site configuration with a site name, domain, and origin URL.
2. Ensure the site is enabled.
3. Preview the rendered configuration or review the diff.
4. Publish and activate a new version.
5. Wait for the Agent to discover and apply the version through heartbeat.
1. Add a website configuration, filling in the website name, domain, and origin address.
2. Verify that the website configuration is enabled.
3. Check the preview or change summary before publishing.
4. Publish and activate the new version.
5. Wait for the Agent to detect and apply the version in the next heartbeat.
Version numbers use `YYYYMMDD-NNN`. Historical versions are immutable; rollback reactivates an old version.
The version number format is `YYYYMMDD-NNN`. Historic versions are immutable; rollbacks are accomplished by re-activating an older version.
## 5. Verify Success
In the UI:
Confirm in the management console:
| Location | Expected Result |
| Position | Expected Result |
| --- | --- |
| Node list | Agent node is online |
| Node detail | Current version matches the active version |
| Apply logs | Latest apply succeeded |
| Versions page | New version is active |
| Node List | Agent node status is online |
| Node Details | Current version matches active version |
| Apply Logs | Most recent application succeeded |
| Version Page | The new version is currently active |
On the Agent node:
Confirm on the Agent node:
```bash
journalctl -u openflare-agent -n 100 --no-pager
@@ -190,12 +195,25 @@ journalctl -u openflare-agent -n 100 --no-pager
## Common Failures
| Symptom | What to Check |
| Symptom | Troubleshooting Direction |
| --- | --- |
| Cannot open the UI | Confirm `docker compose ps` shows Server running and host port `3000` is free |
| Login works but data cannot be saved | Check PostgreSQL health and the username/password/database in `DSN` |
| Agent cannot register | Confirm the Agent node can reach `--server-url`, and check whether the token is wrong or expired |
| Agent is online but does not apply | Confirm the site is enabled and a version was published and activated |
| OpenResty apply fails | Check apply logs and `journalctl -u openflare-agent`, especially domains, certificates, upstream URLs, and port conflicts |
| Management console fails to load in browser | Verify that the Server is running in `docker compose ps` and port `3000` is not bound by other processes |
| Data fails to save after logging in | Check the health of the PostgreSQL container, and verify the username, password, and database name in `DSN` |
| Agent fails to register | Verify that the Agent node can reach `--server-url`, and verify if the Token is typed correctly or expired |
| Agent is online but configuration is not applied | Verify that the website configuration is enabled and a version has been published and activated |
| OpenResty application fails | Review node application logs and `journalctl -u openflare-agent`, checking domains, certificates, upstreams, and port conflicts |
See [Troubleshooting](./troubleshooting.md) for deeper diagnostics.
For more troubleshooting details, see [Troubleshooting](./troubleshooting.md).
---
## Advanced Deployment Guides
Once you complete the quick start and familiarize yourself with the basic operations of OpenFlare, you can read the following advanced deployment documents to put components into production:
* **Server Production Deployment**: Read [Launch Server](../deployment/server.md) to learn how to build the frontend from source, configure system environment variables, and run with Docker Compose.
* **Agent Production Integration**: Read [Deploy Agent](../deployment/agent.md) to learn about systemd-based service management, detailed local configuration parameters, and troubleshooting.
* **Tunnel Relay Deployment**: Read [Deploy Relay](../deployment/relay.md) to learn how to configure public relay nodes (frps) for penetration tunnels.
* **Tunnel Client Deployment**: Read [Deploy OpenFlared](../deployment/openflared.md) to learn how to run the penetration daemon client (frpc) on the intranet server side.
* **Production Deployment Topology**: Read [Deployment Guide](../deployment/deployment.md) to learn about high-availability production topologies and overall network planning.
* **System Upgrades & Maintenance**: Read [Upgrade & Maintenance](../deployment/upgrade.md) to learn how to upgrade the Server and individual node Agents smoothly.
-106
View File
@@ -1,106 +0,0 @@
# Starting the Server
You will learn: How to build the management console frontend from source, start OpenFlare Server, select SQLite or PostgreSQL, and access Swagger.
OpenFlare Server is a Gin + GORM monolithic control plane, responsible for the management console UI, management APIs, Agent APIs, configuration rendering, version releases, data storage, and aggregated queries.
## Prerequisites
| Project | Requirement |
| --- | --- |
| Go | `1.25+` |
| Node.js | `18+` |
| pnpm | Recommended to use the pnpm declared by the project via `corepack enable` |
| Database | SQLite file directory is writable, or an accessible PostgreSQL instance |
In production environments, it is recommended to explicitly configure `SESSION_SECRET` and prioritize PostgreSQL.
## Build the Management Console Frontend
The Go Server hosts the static artifacts in `openflare_server/web/build`. Before starting from source, build the frontend first:
```bash
cd openflare_server/web
corepack enable
pnpm install
pnpm build
```
Common frontend checks:
```bash
pnpm lint
pnpm typecheck
pnpm test
```
## Start with SQLite
```bash
cd openflare_server
export SESSION_SECRET='replace-with-a-long-random-string'
export SQLITE_PATH='./openflare.db'
export LOG_LEVEL='info'
go run .
```
Listens on port `3000` by default. Access:
```text
http://localhost:3000
```
## Start with PostgreSQL
```bash
cd openflare_server
export SESSION_SECRET='replace-with-a-long-random-string'
export DSN='postgres://openflare:secret@127.0.0.1:5432/openflare?sslmode=disable'
export LOG_LEVEL='info'
go run .
```
`DSN` takes precedence over SQLite once set. When `DSN` and the legacy-named `SQL_DSN` both exist, `DSN` takes precedence.
If the target PostgreSQL database is empty and the local `SQLITE_PATH` file exists, the Server will attempt to migrate SQLite data to PostgreSQL during the startup phase and output the migration progress in the logs.
## Command Line Parameters
```bash
go run . --port 3000 --log-dir ./logs
```
| Parameter | Action | Default Value |
| --- | --- | --- |
| `--port` | Specify the Server listening port | `3000` |
| `--log-dir` | Specify the log directory | Empty (outputs to standard output) |
| `--version` | Output the version and exit | `false` |
| `--help` | Output the help information and exit | `false` |
## First Login
Default account:
| Username | Password |
| --- | --- |
| `root` | `123456` |
Please change the default password immediately after logging in for the first time.
## Swagger
Access after logging into the management console:
```text
http://localhost:3000/swagger/index.html
```
Regenerate Swagger locally:
```bash
go install github.com/swaggo/swag/cmd/swag@v1.16.4
cd openflare_server
swag init -g main.go -o docs
```
The generated Swagger files are located in `openflare_server/docs`.
+56 -54
View File
@@ -1,104 +1,106 @@
# SSO Login
# SSO Login Configuration
You will learn how to configure GitHub OAuth or a standard OIDC login source for OpenFlare, how to set callback URLs, and how third-party accounts bind to local users.
You will learn: How to configure GitHub OAuth or standard OIDC login portals for OpenFlare, how to fill in callback URLs, and how third-party accounts bind to existing local users.
OpenFlare supports third-party login through authentication sources. The current supported source types are GitHub OAuth and standard OIDC providers, such as Logto, authentik, Keycloak, and Casdoor.
OpenFlare supports third-party logins configured via Authentication Sources. Currently, GitHub OAuth and standard OIDC Providers (e.g., Logto, authentik, Keycloak, Casdoor) are supported.
After an authentication source is configured and enabled, it appears on the login page. Users can sign in with the third-party account or bind it to the current local account while already signed in.
Once an Authentication Source is configured and enabled, it displays in the third-party login section of the login page. Users can log in using their third-party accounts or bind their third-party accounts to their current local account while logged in.
## Before You Start
## Prerequisites
Prepare:
Before starting, prepare the following:
| Item | Description |
| --- | --- |
| OpenFlare public URL | The URL users open in their browser, such as `https://openflare.example.com` |
| Source name | Internal unique name, such as `github` or `company-oidc` |
| Client ID | Provided by the third-party application |
| Client Secret | Provided by the third-party application |
| OIDC Discovery URL | Required only for OIDC, such as `https://idp.example.com/.well-known/openid-configuration` |
| OpenFlare URL | The actual URL accessed by user browsers, e.g., `https://openflare.example.com` |
| Auth Source Name | Unique internal identifier in OpenFlare, e.g., `github`, `company-oidc` |
| Client ID | Provided after creating an application in the third-party platform |
| Client Secret | Provided after creating an application in the third-party platform |
| OIDC Discovery URL | Required for OIDC only, e.g., `https://idp.example.com/.well-known/openid-configuration` |
Confirm that the server address in system settings matches the domain users access.
**Verify that "System Settings -> General Settings -> Server Address" accurately matches your domain name.**
The source name can contain letters, numbers, hyphens, and underscores, and must start with a letter or number. The source name is part of the callback URL. If you rename it later, update the callback URL in the third-party platform too.
The Auth Source name can only contain letters, numbers, hyphens, or underscores, and must start with a letter or number. The Auth Source name will appear in the callback URL; if you modify the name after saving, you must simultaneously modify the callback URL on the third-party platform.
## Callback URL
Set the Redirect URI / Callback URL in the third-party platform to:
The Redirect URI / Callback URL in third-party platforms is formatted as:
```text
<OpenFlare public URL>/oauth/<source name>
<OpenFlare URL>/oauth/<Auth Source Name>
```
Examples:
Example:
```text
https://openflare.example.com/oauth/github
https://openflare.example.com/oauth/company-oidc
```
When creating or editing an authentication source, the UI shows the callback URL based on the current browser URL and source name.
When creating or editing an authentication source in the management console, the form automatically generates the callback URL based on your current browser URL and the Auth Source name you entered.
## Configure GitHub Login
1. Create an OAuth App in GitHub.
2. Set `Homepage URL` to the OpenFlare public URL.
3. Set `Authorization callback URL` to the callback shown by OpenFlare, such as `https://openflare.example.com/oauth/github`.
4. Copy the Client ID and Client Secret.
5. Sign in to OpenFlare and open Settings -> System Settings -> Authentication Sources.
6. Add a source and select `GitHub`.
7. Fill in source name, display name, Client ID, and Client Secret.
8. Keep the default scope `user:email` unless your GitHub app requires a different value.
9. Save and enable the source.
2. Fill `Homepage URL` with your OpenFlare URL.
3. Fill `Authorization callback URL` with the callback URL generated in OpenFlare, e.g., `https://openflare.example.com/oauth/github`.
4. Copy the Client ID and Client Secret provided by GitHub.
5. Log into the OpenFlare management console, go to "Settings -> System Settings -> Configure Authentication Sources".
6. Add an authentication source, choosing `GitHub` as the type.
7. Fill in the Auth Source name, display name, Client ID, and Client Secret.
8. The Scope defaults to `user:email`, which usually requires no modification.
9. Save and enable the authentication source.
The login page will show the GitHub button after the source is enabled.
Once enabled, the corresponding GitHub login button will display on the login page.
## Configure OIDC Login
1. Create an application or client in the OIDC provider.
2. Choose a Web / Confidential Client type.
3. Set Redirect URI / Callback URL to the value shown by OpenFlare, such as `https://openflare.example.com/oauth/company-oidc`.
1. Create an application or client in your OIDC Provider.
2. Select Web / Confidential Client as the application type.
3. Fill `Redirect URI / Callback URL` with the callback URL generated in OpenFlare, e.g., `https://openflare.example.com/oauth/company-oidc`.
4. Copy the Client ID and Client Secret.
5. Get the provider Discovery URL, usually ending in `/.well-known/openid-configuration`.
6. Sign in to OpenFlare and open Settings -> System Settings -> Authentication Sources.
7. Add a source and select `OIDC`.
8. Fill in source name, display name, Client ID, Client Secret, and OIDC Discovery URL.
9. Keep the default scope `openid profile email` unless the provider restricts scopes.
10. Save and enable the source.
5. Retrieve the Provider's Discovery URL, which usually ends with `/.well-known/openid-configuration`.
6. Log into the OpenFlare management console, go to "Settings -> System Settings -> Configure Authentication Sources".
7. Add an authentication source, choosing `OIDC` as the type.
8. Fill in the Auth Source name, display name, Client ID, Client Secret, and OIDC Discovery URL.
9. Scope defaults to `openid profile email`. If the Provider restricts scopes, adjust to values permitted by the Provider.
10. Save and enable the authentication source.
The login page will show the OIDC button after the source is enabled.
Once enabled, the corresponding OIDC login button will display on the login page.
## Login and Binding Behavior
## Login & Binding Behaviors
Once a third-party account returns to OpenFlare, it is processed according to the following rules:
| Scenario | Behavior |
| --- | --- |
| Third-party account already bound to a local user | Sign in directly |
| User is already signed in and starts third-party authorization | Bind the third-party account to the current local user |
| Third-party account is unbound and registration is allowed | Create a normal local user and bind it |
| Third-party account is unbound and registration is disabled | Ask the user to enter existing local credentials to bind |
| Third-party account is already bound to a local user | Logs in directly |
| User is already logged in and initiates third-party authorization | Binds to the current local user |
| Third-party account is unbound, and registration is enabled | Automatically creates a standard user and binds |
| Third-party account is unbound, and registration is disabled | Prompts to enter an existing local username and password to complete the binding |
If you only want existing users to use SSO, disable registration. Unbound third-party accounts will enter the existing-account binding flow.
If you want only existing users to use SSO, you can disable user registration. Unbound third-party accounts will then trigger the binding flow.
## Update a Source
## Modify Authentication Source
When editing an authentication source, leave Client Secret empty to keep the existing secret. Entering a new value overwrites it.
When editing an authentication source, leaving the Client Secret field blank retains the existing secret; entering a new value will overwrite the saved secret.
If you change the source name, the callback URL changes too. Update Redirect URI / Callback URL in the third-party platform, or the provider will reject the callback.
If you modify the Auth Source name, the callback URL changes accordingly. You must modify the Redirect URI / Callback URL on the third-party platform; otherwise, the third-party platform will deny the callback or return an error.
## FAQ
## Common Problems
### `invalid_scope`
### Returns `invalid_scope`
The provider does not allow the configured scope. The OIDC default is `openid profile email`; the GitHub default is `user:email`. Adjust the scope in OpenFlare or allow it in the provider.
This indicates that the third-party platform does not permit the configured Scope. OIDC defaults to `openid profile email`, and GitHub defaults to `user:email`. Adjust the Scope in the authentication source edit page or configure the third-party platform to permit the scope.
### Callback URL Mismatch
### Callback Address Mismatch
Check that the Redirect URI / Callback URL in the provider exactly matches the URL shown by OpenFlare. Protocol, domain, port, and path must all match.
Verify if the Redirect URI / Callback URL configured in the third-party platform matches the prompt in the OpenFlare form exactly. The protocol, domain, port, and path must match.
### No Third-Party Login Button
### Third-party Login Button Not Showing on Login Page
Check that the source is enabled and that Client ID and Client Secret are saved. OpenFlare validates these fields before enabling a source.
Verify if the authentication source is enabled and confirm that the Client ID and Client Secret are saved. OpenFlare validates these fields before enabling the source.
### Client Secret Is Not Shown in the List
### Client Secret Saved but Not Displayed in Clear Text
This is expected. OpenFlare does not return Client Secret through the API; it only shows whether the secret is configured.
This is expected behavior. OpenFlare does not echo the Client Secret back via API, displaying only whether the secret is configured.
+110 -86
View File
@@ -1,45 +1,45 @@
# Troubleshooting
You will learn how to debug OpenFlare Server, database, login, Agent, OpenResty, release, and frontend build issues by symptom.
You will learn: How to troubleshoot OpenFlare Server, database, login, Agent, OpenResty, configuration publishing, and frontend build issues by symptoms.
Start by locating the failing layer: browser, Server, database, Agent, OpenResty, origin, or DNS. OpenFlare applies configuration only after a version is activated and the Agent discovers it through heartbeat.
During troubleshooting, first identify which layer the issue occurs in: browser, Server, database, Agent, OpenResty, origin server, or DNS. OpenFlare configurations are not written directly to nodes online; only after the active version changes will the Agent detect and apply it in heartbeats.
## Quick Triage
## Quick Diagnostic
| Symptom | Check First |
| Symptom | Where to check first |
| --- | --- |
| Management UI does not open | Server process/container logs and port binding |
| Login fails | Default account, `SESSION_SECRET`, browser request, Server logs |
| Data cannot be saved | Database connection, SQLite permissions, PostgreSQL health |
| Agent is offline | Agent logs, token, Server URL, network reachability |
| Node does not update after release | Active version, node heartbeat, apply logs |
| OpenResty apply fails | Apply logs, Agent logs, certificates, upstream URL, port conflicts |
| No access analytics | OpenResty status, observability port, Agent replay logs |
| Admin panel fails to open | Server container or process logs, port listening |
| Login anomalies | Default credentials, Session Secret, browser request payloads, Server logs |
| Data fails to save | Database connection, SQLite file permissions, PostgreSQL health |
| Agent offline | Agent logs, Token, Server URL, network connectivity |
| Node not updated after publishing | Active version, node heartbeat, application logs |
| OpenResty application failed | Application logs, Agent logs, certificates, upstream addresses, port conflicts |
| Observability analytics has no data | OpenResty container status, observability port, Agent retry logs |
## Server Does Not Start
## Server Fails to Start
1. Check logs:
1. View logs:
```bash
docker compose logs -n 200 openflare
```
For source runs, check terminal output.
For source-code execution, inspect terminal outputs.
2. Check port usage:
2. Check port conflicts:
```bash
lsof -i :3000
```
3. If PostgreSQL is used, check database health:
3. If using PostgreSQL, verify that the database is healthy:
```bash
docker compose ps postgres
docker compose logs -n 100 postgres
```
4. If SQLite is used, check that the database directory is writable:
4. If using SQLite, verify that the database directory is writable:
```bash
ls -ld "$(dirname /path/to/openflare.db)"
@@ -47,154 +47,178 @@ ls -ld "$(dirname /path/to/openflare.db)"
Common causes:
| Log or Symptom | Fix |
| Log or Symptom | Action |
| --- | --- |
| Database connection failed | Check username, password, host, port, database, and `sslmode` in `DSN` |
| SQLite cannot create file | Check that the `SQLITE_PATH` directory exists and is writable |
| Port is already in use | Change `PORT` or `--port`, or stop the process using the port |
| Database connection failed | Check `DSN` username, password, host, port, dbname, and `sslmode` |
| SQLite fails to create files | Check if the parent directory of `SQLITE_PATH` exists and is writable |
| Port is already in use | Change `PORT` or `--port`, or stop the process binding to the port |
## UI Does Not Open or Is Blank
## Admin Console Fails to Load or Shows Blank Page
1. Confirm that the Server responds:
1. Verify that the Server is listening:
```bash
curl -I http://127.0.0.1:3000
```
2. For source runs, confirm frontend static assets were built:
2. If running from source, verify that the frontend static assets have been built:
```bash
cd openflare_server/web
pnpm build
```
3. Check whether the browser URL matches your reverse proxy setup.
3. Verify if the browser URL matches your reverse proxy domain.
4. If using the frontend dev server, confirm backend proxy configuration:
4. If accessing via the frontend dev server, verify the backend proxy configuration:
```bash
cd openflare_server/web
NEXT_DEV_BACKEND_URL=http://127.0.0.1:3000 pnpm dev
```
## Default Account Cannot Sign In
## Default Credentials Fail to Log In
The default account is `root` / `123456`. If the password was changed after first login, use the updated password.
The default credentials are `root` / `123456`. If you have modified the password after your first login, use your new password.
Steps:
Troubleshooting Steps:
1. Confirm the Server is connected to the expected database, not another `SQLITE_PATH` or `DSN`.
2. Check Server logs to see whether it uses `sqlite` or `postgres`.
3. If deployed behind replicas or a reverse proxy, ensure `SESSION_SECRET` is fixed and consistent across instances.
4. Clear browser cookies and try again.
1. Confirm that you are connecting to the expected database, avoiding `SQLITE_PATH` or `DSN` pointing to a different environment.
2. Check the Server log to see if it is running on `sqlite` or `postgres`.
3. If deployed in multi-replicas or behind a reverse proxy, verify that `SESSION_SECRET` is static and uniform across all instances.
4. Clear browser Cookies and try logging in again.
[Needs confirmation: whether the project provides a safe root password reset command or procedure]
### Emergency Reset of Admin Password
## Agent Cannot Register or Stays Offline
If you forget the password for the `root` account, you can reset it back to `123456` by directly updating the password hash in the database (please change it immediately after logging in):
On the Agent node:
#### 1. If using SQLite Database
Stop the Server and open the database file using the `sqlite3` client:
```bash
sqlite3 /path/to/openflare.db
```
Execute the following SQL statement:
```sql
UPDATE users SET password_hash = '$2a$10$wN9aE3zTz83rO7R1uKlhuehJtA3c604pX4Z12B/9.5c0X337t1L4m' WHERE username = 'root';
```
Type `.exit` to exit and restart the Server.
#### 2. If using PostgreSQL Database
Connect to your PostgreSQL instance using a database tool (e.g., `psql`, `pgAdmin`, or `DBeaver`), select the corresponding `openflare` database, and execute the following SQL:
```sql
UPDATE users SET password_hash = '$2a$10$wN9aE3zTz83rO7R1uKlhuehJtA3c604pX4Z12B/9.5c0X337t1L4m' WHERE username = 'root';
```
Once executed successfully, you can log in using the default password `123456`.
## Agent Fails to Register or Stays Offline
Execute on the Agent node:
```bash
curl -I http://your-server:3000
```
Check Agent logs:
Inspect Agent logs:
```bash
journalctl -u openflare-agent -n 200 --no-pager
```
Check config:
Verify configuration parameters:
```bash
sed -n '1,160p' /opt/openflare-agent/agent.json
```
Confirm:
Key Settings:
| Config | Notes |
| Configuration | Description |
| --- | --- |
| `server_url` | Must be reachable from the Agent node |
| `agent_token` / `discovery_token` | At least one is required |
| `heartbeat_interval` | Supports millisecond integers or Go duration strings |
| `request_timeout` | Increase it for slow networks |
| `server_url` | Must be the Server address reachable by the Agent node |
| `agent_token` / `discovery_token` | At least one must be provided |
| `heartbeat_interval` | Supports integer milliseconds or Go duration strings |
| `request_timeout` | Can be increased for slower network links |
If the log says the token is invalid, prepare a new token in the UI, update `agent.json`, and restart:
If the log warns that the Token is invalid, retrieve a new Token in the management console, update `agent.json`, and restart the Agent:
```bash
systemctl restart openflare-agent
```
## Node Does Not Apply a New Version
## Node Fails to Apply New Version after Publishing
Check in order:
Verify in sequence:
1. The target version is active on the versions page.
2. The node is online and heartbeat time is updating.
3. Apply logs contain a success, warning, or failure for the target version.
4. The site configuration is enabled.
5. Agent logs show pull, validation, reload, or rollback messages.
1. Confirm that the target version is activated on the Versions page.
2. Verify if the node is online and if its last heartbeat time has updated.
3. Check the Application Logs for successful, warned, or failed logs for the target version.
4. Verify if the website configuration is enabled; disabled websites do not participate in rendering.
5. Inspect Agent logs for pulls, validations, reloads, or rollback events.
Follow Agent logs:
Inspect Agent logs:
```bash
journalctl -u openflare-agent -f
```
After a target `version + checksum` fails and rolls back, the Agent blocks repeated attempts for that same target locally. Fix the configuration and publish a new checksum, or activate an old version to roll back.
Note: If a target `version + checksum` fails to apply and triggers a rollback, the Agent blocks repeated synchronization of that failing target in its local state. You must fix the configuration issues and republish to generate a new checksum, or activate an older version to trigger a rollback.
## OpenResty Apply Fails
If this is the Agent's first time applying configurations and no historic `nginx.conf` exists locally to roll back to, the failed version remains blocked but the Agent will attempt to enter the safe fallback runtime. At this point, the application logs and Agent logs will contain `fallback runtime started`. OpenResty will only listen to port `80`, returning a `503` with the body `OpenFlare: No Valid Configuration`, while retaining the local `/openflare/stub_status` health probe. After correcting the configurations and republishing, the Agent overrides the fallback config and restores normal reverse proxies.
Common causes:
## OpenResty Application Fails
| Cause | Check |
Common Causes:
| Cause | Diagnostic |
| --- | --- |
| Domain or server block conflict | Ensure the same domain is not used by multiple sites |
| Invalid upstream URL | Every upstream must be `http://` or `https://` |
| Invalid multi-upstream format | Multiple upstreams must be plain `scheme://host[:port]` |
| Missing certificate or wrong path | Check domain certificate binding and Agent certificate directory permissions |
| Port conflict | Check local `80` and `443` usage |
| Domain or server block conflict | Verify if the same domain is used by multiple website configurations |
| Invalid upstream address | Confirm that all upstreams are valid `http://` or `https://` URLs |
| Mismatched multi-upstream format | Multi-upstreams must be pure `scheme://host[:port]` |
| Missing cert or invalid paths | Verify if domains are bound to certs and check if the Agent cert directory is writable |
| Port already in use | Verify ports `80` and `443` on the host |
OpenResty config test:
OpenResty Configuration Validation:
```bash
openresty -t -c /path/to/openflare/data/etc/nginx/nginx.conf
```
OpenResty runtime:
OpenResty Runtime Status:
```bash
ps aux | grep openresty
```
Agent periodic health checks use local `http://127.0.0.1:<openresty_observability_port>/openflare/stub_status` instead of repeatedly running `openresty -t`. If a node is unhealthy, first confirm that the local observability port is listening. If `host not found in upstream` only appears during apply, the failure comes from config validation or reload, not the periodic health probe.
The Agent determines OpenResty survival periodically using the local endpoint `http://127.0.0.1:<openresty_observability_port>/openflare/stub_status`, completely bypassing repeated `openresty -t` calls. If a node is marked as unhealthy, confirm if this local observability port is listening. If failures only occur when applying configurations (e.g., `host not found in upstream`), the failure lies in config validation or reload, not the periodic health checks.
Use the actual `openresty_path` and `main_config_path` from `agent.json`.
Actual binary paths and main configuration paths are governed by `openresty_path` and `main_config_path` in `agent.json`.
## HTTPS Does Not Work
## HTTPS Fails to Work
1. Confirm the certificate exists.
2. Confirm the domain is bound to that certificate in the site configuration.
3. Confirm a new version was published and activated.
4. Check apply logs for success.
5. Inspect with `curl`:
1. Verify that the certificate has been uploaded or hosted.
2. Verify that the website configuration binds the certificate to the domain.
3. Confirm that the configuration version has been published and activated.
4. Check if the Application Logs indicate a success.
5. Check the certificate chain and status code using `curl`:
```bash
curl -Iv https://your-domain
```
Domains without a bound certificate are not automatically added to HTTPS configuration.
Domains without a bound certificate will not be added to the HTTPS configuration automatically; this is expected behavior.
## No Access Analytics
## Traffic Analytics Has No Data
1. Confirm the node applied a configuration that includes observability Lua assets.
2. Confirm OpenResty is running.
3. Check Agent logs for collection or replay failures.
4. Check whether `openresty_observability_port` is occupied. The default is `18081`.
5. Confirm Server cleanup policy did not remove data for that time window.
1. Confirm that the node has successfully applied configurations carrying observability Lua scripts.
2. Verify that OpenResty is running.
3. Check Agent logs for observability extraction or upload errors.
4. Check if `openresty_observability_port` (default is `18081`) is bound by other processes.
5. Verify if the Server database has purged data inside the time window.
## Frontend Build Fails
Execute:
```bash
cd openflare_server/web
corepack enable
@@ -207,14 +231,14 @@ pnpm build
Common causes:
| Symptom | Fix |
| Symptom | Action |
| --- | --- |
| pnpm version mismatch | Run `corepack enable` and reinstall |
| Type errors | Run `pnpm typecheck` to locate files |
| API type mismatch | Check `lib/api/` and `types/` response structures |
| E2E fails | Ensure both the Server and frontend dev server are running |
| pnpm version mismatch | Reinstall packages after executing `corepack enable` |
| TypeScript errors | Locate detailed file bugs by running `pnpm typecheck` |
| API type mismatch | Check responses structures in `lib/api/` and `types/` |
| E2E test failures | Confirm that both the Server and frontend dev server are running |
## Docs Build Fails
## Documentation Build Fails
```bash
cd docs
@@ -222,4 +246,4 @@ pnpm install
pnpm build
```
If the failure is a link error, check that new pages are added to `docs/en/config.ts` and that relative links point to existing Markdown files.
If it fails on broken links, check if new pages are added to the `docs/config.ts` sidebar, or if relative markdown links point to existing markdown files.
+174
View File
@@ -0,0 +1,174 @@
# Tunnel & Intranet Penetration
You will learn: The design principles of OpenFlare intranet penetration tunnels, core concepts (Relay nodes and Tunnel clients), and how to safely and stably publish your intranet development environment or private cloud services to a public domain name from scratch.
In many practical development and operations scenarios, our origin servers are deployed in local LANs, local development machines, or heavily guarded private VPCs, having no public IP address and no port mapping (NAT) configured on border firewalls or routers.
OpenFlare provides an end-to-end solution **based on reverse relay penetration tunnels**. You only need to initiate a secure outbound connection from your intranet environment to the public relay node, without configuring any inbound ports, to smoothly route public web traffic into your intranet origin. At the same time, you benefit from automatic TLS certificate hosting and WAF security protection provided by the gateway.
---
## Core Concepts
Before using the intranet penetration features, you need to familiarize yourself with the following components and core concepts:
| Concept | Description | Component / Operation |
| --- | --- | --- |
| **Relay Node (Relay)** | Traffic relay services deployed at the public edge, responsible for listening to intranet client persistent connections, acting as the transit bridge between the gateway Agent (OpenResty) and internal traffic. | Node of type `tunnel_relay` running the `openflare-relay` daemon |
| **Penetration Tunnel (Tunnel)** | Logical penetration client instances having a globally unique ID and secure authentication token, used to identify a specific intranet environment. | Globally unique ID generated by Server `tunnel_id` (format: `tun-<32hex>`) |
| **Tunnel Client (Client)** | A lightweight controller running in the intranet environment, automatically managing the underlying frpc tunnel subprocesses according to the configuration dispatched by the Server. | The `openflared` container or independent binary process deployed in the intranet |
| **Tunnel Upstream (Tunnel Upstream)** | A special upstream type in the website configuration. When this type is selected, the gateway forwards public traffic to the Vhost port of the local relay node, eventually reaching the intranet origin. | Upstream of type `tunnel` configured in the website details |
---
## Recommended Operation Sequence
To publish an intranet service to the public internet, we recommend doing so in the following order:
1. Register and deploy at least one public **Relay Node (Relay)** and keep it online.
2. Create a **Penetration Tunnel (Tunnel)** in the management console and copy its dedicated Token.
3. Deploy and start the **Tunnel Client (OpenFlared)** on your intranet server.
4. Confirm that the status of the tunnel in the management console shows as "Online".
5. Add a website configuration, selecting **Intranet Penetration** as the upstream type, binding it to the corresponding tunnel, and entering the intranet port (e.g., `127.0.0.1:8080`).
6. Publish and activate the new version.
7. Access via the public domain to verify that the intranet penetration link is established.
---
## Detailed Configuration Steps
### Step 1: Prepare the Relay Node (Relay)
Intranet traffic is routed through public relay nodes. Before starting, ensure you have a public relay server available.
1. Log into the management console and go to **"Node Management"**.
2. Add a new node, selecting **Relay Node (tunnel_relay)** as the **Node Type**.
3. Save and copy the node-specific `agent_token`.
4. Start the `openflare-relay` process on your public server. You can run it quickly using Docker:
```bash
docker run -d --name openflare-relay --restart unless-stopped \
-p 7000:7000 \
-e OPENFLARE_SERVER_URL=http://<YOUR_SERVER_PUBLIC_IP>:3000 \
-e OPENFLARE_AGENT_TOKEN=<YOUR_COPIED_AGENT_TOKEN> \
-v openflare-relay-data:/var/lib/openflare-relay \
ghcr.io/rain-kl/openflare-relay:latest
```
> [!IMPORTANT]
> Make sure to allow port `7000` (the control port for frpc client connections) in your cloud provider's security group. If your Server and Relay are deployed on the same machine, `OPENFLARE_SERVER_URL` should point to the Server's public or internal IP.
### Step 2: Create a Penetration Tunnel in the Management Console
1. Navigate to the **"Intranet Penetration"** section in the side navigation bar.
2. Click the **"Create Tunnel"** button and enter:
* **Tunnel Name**: Describes the intranet environment, e.g., `home-lab` or `office-dev`.
* **Description**: Optional, describes the purpose of this tunnel.
3. Click save, and the system will automatically generate a globally unique ID and a dedicated `tunnel_token` (e.g., `tun-xxxx...`).
4. Copy the **Client Deployment Command** generated in the popup window, which will be used in the next step.
### Step 3: Deploy the Intranet Client (OpenFlared)
Return to your intranet server and execute the copied deployment command to run the client.
#### Option A: Deploy with Docker (Highly Recommended)
The official `openflared` image embeds the master daemon and `frpc` runtime, working out-of-the-box with no extra dependencies:
```bash
docker run -d --name openflared --restart unless-stopped \
-e OPENFLARE_SERVER_URL=http://<YOUR_SERVER_PUBLIC_IP>:3000 \
-e OPENFLARE_TUNNEL_TOKEN=<YOUR_COPIED_TUNNEL_TOKEN> \
-v openflared-data:/app/data \
ghcr.io/rain-kl/openflared:latest
```
#### Option B: Host Binary Manual Execution
If you cannot use Docker, you can download or compile the `flared` binary:
1. Create a `flared.json` configuration file in the same directory as the executable on your intranet machine:
```json
{
"server_url": "http://<YOUR_SERVER_PUBLIC_IP>:3000",
"tunnel_token": "<YOUR_COPIED_TUNNEL_TOKEN>",
"frpc_path": "/usr/local/bin/frpc",
"data_dir": "./data"
}
```
2. Execute the startup command:
```bash
./flared -config ./flared.json
```
#### Verify Online Status
Once started successfully, the intranet client will send heartbeats through outbound networks to synchronize configurations. At this point:
1. Refresh the **"Intranet Penetration"** list in the management console; the tunnel status indicator should turn green and show **"Online"**.
2. Click tunnel details to view which public Relays the intranet client is currently connected to.
### Step 4: Create a Website and Bind the Tunnel Upstream
Now you can configure public reverse proxy and domain routing for your intranet service.
1. Go to the **"Website Configuration"** page and click **"Create Website"**.
2. Enter the **Domain Name** required to access the service publicly, e.g., `nas.example.com`.
3. Critical Configuration: In the **"Upstream Configuration"** section, switch the **Upstream Type** from "Direct" to **"Intranet Penetration"**.
4. In the dropdown list, select your newly deployed **Intranet Tunnel** (e.g., `home-lab`).
5. Enter the **Intranet Target Address** (the local address and port reachable by the intranet client, e.g., `127.0.0.1:8080`) and select the **Intranet Protocol** (usually `http`).
6. Configure other standard website settings (such as TLS certificates) and click save.
### Step 5: Publish & Activate
To allow the gateway's OpenResty instance to match and route domain traffic correctly, we need to publish a new configuration version.
1. Click **"Preview Config"** in the top right corner of the navigation bar to verify the generated configurations.
2. In the popup window, click **"Publish & Activate"**.
3. Now, the public edge Agent pulls the latest routing, forwarding requests for `nas.example.com` to the loopback virtual host port of `openflare-relay (frps)`.
4. The intranet client `openflared (frpc)` receives the relayed packets, securely hands them over to the local `127.0.0.1:8080` service, and returns responses back through the tunnel.
5. Access `nas.example.com` in your browser to confirm that the intranet service displays successfully!
---
## Advanced Application Scenarios
### 1. Single-Tunnel Multi-Service Multiplexing (Multi-Port Mapping)
You do not need to deploy an `openflared` container for every single internal service.
If you want to map multiple different services in the same intranet environment (e.g., `127.0.0.1:80` for a blog, `127.0.0.1:8080` for an API, and `192.168.1.120:9000` for a local network drive):
1. Keep this single `openflared` client online.
2. Create three independent website configurations in the management console (binding their respective public domains).
3. Set the **Upstream Type** to **the same intranet tunnel** for all three website configurations.
4. Fill in their respective "Intranet Target Addresses" (e.g., `127.0.0.1:80`, `127.0.0.1:8080`, and `192.168.1.120:9000`).
5. Publish and activate the new version to achieve single-tunnel multi-service multiplexing.
### 2. Seamless Integration with Gateway Security Features
Since all public traffic enters the public Agent node first, completing the HTTPS/TLS handshake and WAF filtering before traveling through the secure tunnel:
Your intranet services **naturally benefit from the following advanced features without any code changes**:
* **One-Click HTTPS**: Select or issue SSL certificates directly in the management console, encrypting transmission end-to-end.
* **Global/Custom WAF Protections**: Enables SQL injection blocking, XSS prevention, and regional IP filtering.
* **Human-Machine Challenge (PoW CC)**: Instantly blocks brute-force CC API attacks targeting your intranet services.
---
## Common Troubleshooting
### 1. Tunnel Shows as "Offline" in the Management Console
* **Check the Token**: Check if the `tunnel_token` configured in `flared` logs or environment variables matches the one generated in the management console.
* **Check Outbound Connectivity**: The intranet server must be able to make outbound requests to the Server address. Ensure the control plane firewall is not blocking HTTP requests from the client.
* **Relay Firewall Port Closed**: Check if port `7000` (or your custom bindPort) on the public Relay node has been allowed in the public security groups.
### 2. Accessing the Public Domain Returns 502 Bad Gateway / 504 Gateway Timeout
* **Intranet Service Not Running**: Verify that the service corresponding to the intranet target address is running and listening on the intranet server.
* **Target Address Unreachable**: If the intranet address is set to `127.0.0.1:8080`, ensure the service is running on the exact same host as `openflared`; if set to a LAN IP `192.168.x.x`, test connectivity to that IP inside the `openflared` container.
* **Check Client Application Logs**: View the "Apply Logs" in the management console or inspect local `flared` logs for any `LastError`. When frpc fails to connect to the intranet port, it reports the failure details to the Server.
### 3. Multiple Relays Network Instability or Retry Failures
* When the control plane associates multiple Relay nodes, `openflared` spawns independent frpc daemon processes for each Relay and pulls topology states periodically at `sync_interval` (default 30s) configured in `flared.json`.
* If a Relay drops frequently due to network jitter, the system triggers the backoff retry mechanism automatically. You can see `frpc process missing, starting` logs on the host, which is a normal process self-healing action and will recover within 5-10 seconds after network recovery.
-85
View File
@@ -1,85 +0,0 @@
# Upgrade and Maintenance
You will learn: How to upgrade the Server and Agent, how to clean up observability data, and which verification commands to execute before and after maintenance.
Before upgrading, it is recommended to confirm the current activated version, the latest Agent application result, and the database backup policy. Do not upgrade in production environments while configuration publishing, large-scale Agent reconnection, or database migrations are in progress.
## Server Upgrade
Root users can check and upgrade the Server stable version from the top bar of the management console. Upgrades can also be confirmed and executed by uploading the Server binary.
To try a preview version, you can manually check the corresponding release. It is recommended to prioritize the stable version in production environments.
After upgrading, confirm:
```bash
docker compose ps
docker compose logs -n 100 openflare
```
If it is a source deployment, confirm that there are no database migration or startup errors in the logs after restarting the Server.
## Agent Upgrade
Node Agents follow stable versions by default for automatic updates. Preview upgrades must be triggered manually.
The installation script can be executed repeatedly to reinstall or upgrade the Agent:
```bash
curl -fsSL https://raw.githubusercontent.com/Rain-kl/OpenFlare/main/scripts/install-agent.sh | bash -s -- \
--server-url http://your-server:3000 \
--agent-token YOUR_AGENT_TOKEN
```
Note: Currently, the installation script will delete the entire installation directory during reinstallation, including the old `agent.json`, local state, cache data, and downloaded binaries. Please confirm that you still have a usable Token on hand before executing.
After upgrading, confirm:
```bash
systemctl status openflare-agent
journalctl -u openflare-agent -n 100 --no-pager
```
## Data Maintenance
The settings page of the management console can maintain the observability data automatic cleanup policy:
| Configuration Item | Description |
| --- | --- |
| `DatabaseAutoCleanupEnabled` | Whether to enable daily automatic cleanup |
| `DatabaseAutoCleanupRetentionDays` | Automatic cleanup retention days, at least 1 day |
Once enabled, the Server will clean up access logs, metric snapshots, and request reports at 3 AM every day.
## Common Verification Commands
Server:
```bash
cd openflare_server
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Agent:
```bash
cd openflare_agent
GOCACHE=/tmp/openflare-go-cache go test ./...
```
Frontend:
```bash
cd openflare_server/web
pnpm lint
pnpm typecheck
pnpm test
pnpm build
```
Docs:
```bash
cd docs
pnpm build
```
+91 -81
View File
@@ -1,146 +1,156 @@
# Usage
# Basic Usage
You will learn what sites, origins, certificates, versions, nodes, and observability mean in OpenFlare, and which order to follow for daily operations.
You will learn: What website configurations, origins, certificates, versions, nodes, and observability are in OpenFlare, and the recommended sequence of operations during daily usage.
OpenFlare does not patch OpenResty configuration files online. You edit control-plane data in the UI; Agents pull and apply a full configuration only after you publish and activate a new version.
OpenFlare does not directly modify Nginx/OpenResty configurations on nodes online. What you modify in the management console is control plane data; only after publishing and activating a new version will the Agent pull the complete configuration and apply it to the nodes.
## Core Concepts
| Concept | Description |
| --- | --- |
| Site configuration | The reverse proxy aggregation object. One site can bind one or more domains. |
| Primary domain | The first item in the `domains` list. |
| Origin | The upstream service address, such as `http://10.0.0.10:8080`. |
| Configuration version | A full OpenResty configuration snapshot generated by a release. Historical versions are immutable. |
| Active version | The globally effective version. By default, all nodes consume the same active version. |
| Agent | The node-side process that registers, heartbeats, syncs, validates, reloads, and rolls back on failure. |
| Website Config | The aggregate object for reverse proxy rules. One website configuration can bind one or more domains. |
| Primary Domain | The first domain in the `domains` list, used as the main display domain for the website. |
| Origin | The upstream address accessed by the reverse proxy, e.g., `http://10.0.0.10:8080`. |
| Config Version | An immutable snapshot of the complete OpenResty configuration generated upon publishing. |
| Active Version | The globally effective configuration version. All nodes consume the same active version by default. |
| Agent | The node-side process responsible for registration, heartbeats, sync, validation, reloads, and rollbacks on failure. |
## Recommended Workflow
## Recommended Operation Sequence
For a normal reverse proxy change:
When publishing a reverse proxy configuration in daily operations, the following sequence is recommended:
1. Confirm that at least one Agent node is online.
2. Create or select an origin.
3. Create a site configuration with domains, upstreams, and site-level settings.
4. If HTTPS is needed, upload or select certificates and bind them per domain.
5. Preview the rendered configuration or review the diff.
6. Publish and activate a new version.
7. Check node details and apply logs.
2. Add or select an origin address.
3. Create a website configuration, entering the domain, origin, and site-level configurations.
4. If HTTPS is required, upload or select a certificate and bind it by domain.
5. Preview the configuration or review the change summary.
6. Publish and activate the new version.
7. Verify the application result in the node details and application logs.
## Create a Site
## Create Website Configuration
A site requires at least:
A website configuration requires at least:
| Field | Requirement |
| --- | --- |
| Site name | Business-unique identifier. The primary domain is a common default. |
| Domains | At least one domain. The first domain is the primary domain. Each domain must be globally unique. |
| Origin URL | A valid `http://` or `https://` upstream address. |
| Enabled state | Only enabled sites are included in release rendering. |
| Website Name | Business unique identifier; the primary domain is usually used if left blank |
| Domain | At least one domain, where the first is the primary domain; any domain can belong to only one website globally |
| Origin Address | A valid `http://` or `https://` address |
| Enabled Status | Only enabled website configurations will participate in publishing and rendering |
Example:
| Field | Example |
| --- | --- |
| Site name | `docs` |
| Website Name | `docs` |
| Domain | `docs.example.com` |
| Origin URL | `http://10.0.0.10:8080` |
| Origin Host | `docs.internal.example.com` |
| Origin Address | `http://10.0.0.10:8080` |
| Back-to-source Host | `docs.internal.example.com` |
Upstream rules:
Upstream Address Rules:
* A single upstream may include a base path or query string, such as `https://app.example.com/base?from=openflare`.
* Multiple upstreams are used for load balancing and must be plain `scheme://host[:port]`.
* Multiple upstreams in the same site should use the same protocol.
* A single upstream can carry a base path or query, e.g., `https://app.example.com/base?from=openflare`.
* When multiple upstreams are used for load balancing, each upstream must be a pure `scheme://host[:port]`.
* Multiple upstreams in the same rule must use the same protocol.
## Manage Origins
Origins are a lightweight reusable address directory. When a site references an origin, the site still stores a renderable `origin_url` snapshot so historical versions can be replayed independently.
Origins act as a lightweight directory to reuse common upstream addresses. After a website configuration links with an origin, it still stores a renderable snapshot of the `origin_url`, ensuring that historic configuration versions can be re-rendered and rolled back independently.
Recommended practices:
Recommended Practices:
* Store frequently reused internal service addresses as origins.
* After changing an origin entry, check whether site snapshots need to be updated.
* Use preview or diff before publishing.
* Maintain internal service addresses that are frequently reused as Origins.
* After modifying an origin directory, check if published website configurations need their origin snapshots updated.
* Use preview or diff to verify rendering results before publishing.
## Enable HTTPS
HTTPS is bound per domain, not forced for the whole site.
HTTPS is bound by domain rather than being forced across the entire website.
1. Upload or create a certificate record.
2. Open the site configuration and select a certificate for each domain that needs HTTPS.
3. Domains without a certificate stay HTTP-only and are not automatically added to `443 ssl` server blocks.
4. Publish and activate a new version.
Operation Sequence:
If a site contains multiple domains, the Server groups HTTPS output by certificate while keeping all domains in the same site snapshot.
1. Upload or host certificates in the Certificate Management section.
2. Edit the website configuration and select certificates for domains requiring HTTPS.
3. Domains without a bound certificate will remain HTTP and will not be automatically placed in a `443 ssl` server block.
4. Publish and activate the new version.
## Configure WAF and PoW
If a website contains multiple domains, the Server groups and renders the HTTPS configuration by certificate during publishing while keeping these domains within the same website snapshot.
Security controls are managed from the **WAF** sidebar entry:
## Configure WAF & PoW
* The WAF page manages the global rule group and custom rule groups. The global rule group always applies to every site. Custom rule groups can be applied to selected sites from the rule group drawer or bound from the site detail `WAF` section.
* `PoW` is a tab inside the selected rule group, between `Allow / Block Lists` and `Block Response`. It reuses the existing per-site PoW execution logic and can apply the current PoW policy to every site or the sites bound to the current rule group.
* Site details no longer edit PoW directly. They show the always-on global WAF group and let you bind custom WAF rule groups. PoW rule content and scope should be maintained from the WAF page.
Security protection is centrally accessed via the **WAF** link in the side navigation bar:
After changing WAF or PoW settings, publish and activate a new configuration version so Agents can apply the updated OpenResty runtime.
* The WAF page maintains global and custom rule groups. Global rule groups always apply to all websites; custom rule groups can bind websites directly in the group settings or inside the `WAF` section of the website details.
* Clicking **Manage IP Groups** on the WAF page opens the independent IP Groups section. Manual IP groups store IPs/CIDR blocks directly; automatic IP groups evaluate Expr rules against request logs periodically to update members; subscription IP groups periodically sync from remote text or JSON feeds.
* The Auto IP Group page provides two presets: requests count > 100 and 404 ratio >= 80% from a single IP; or IP-host direct access count > 50 and direct access ratio > 50% from a single IP. You can click **Test Rule** to preview IPs matching the log window before saving, and click **Execute Now** to update the group members instantly after saving. The syntax is detailed in [WAF Auto IP Group Expressions](./waf-ip-group-expr.md).
* In the blacklist/whitelist settings of a WAF rule group, you can add IPs/CIDR blocks directly or reference existing IP groups. The published version snapshot only contains referenced IP group IDs; the Agent synchronizes IP group members via checksum differentials and WebSocket real-time broadcasts.
* `PoW` is a configuration Tab in the rule group, located between `Blacklist/Whitelist` and `Block Interception`. It reuses the site's existing PoW execution logic, allowing current PoW parameters to apply to all websites or only those bound to the current rule group.
* The website details page no longer edits individual PoW rules; it only displays the global WAF rule group and binds custom WAF rule groups. The PoW enablement scopes and rule parameters must be maintained centrally on the WAF pages.
## Release, Activate, and Roll Back
After WAF rule groups, site bindings, or PoW configurations are modified, you must republish and activate the configuration version to let the Agent pull and apply them to OpenResty. IP group member changes do not require a new version publication; online Agents update incrementally via WebSockets, while offline or non-WebSocket Agents synchronize via checksum differentials in the next heartbeat.
Standard flow:
For detailed information on WAF security configurations and evaluation principles, see [WAF Security Protection](./waf-usage.md).
## Publish, Activate & Rollback
Standard Pipeline:
```text
Edit configuration -> Preview / diff -> Release -> Generate full version -> Activate version -> Agent pulls -> Agent applies locally -> Agent reports result
Modify config -> Preview / Diff -> Publish -> Generate complete version -> Activate version -> Agent pulls -> Local application -> Report result
```
During release, the Server reads all enabled site configurations, OpenResty main template, performance options, cache options, and certificate assets. It renders a full configuration and calculates a `checksum`.
During publication, the Server reads all enabled website configurations, the main OpenResty config templates, performance and cache parameters, and certificate assets, rendering the complete configuration and calculating its `checksum`.
Rollback means reactivating an old version. The Agent then applies that version through the normal sync flow.
Rolling back does not modify historic versions; it simply re-activates an older version. Once the Agent detects a change in the active version, it pulls and applies it following the standard sync flow.
## Nodes and Observability
## View Nodes & Observability
Node pages answer three questions:
The Nodes section is designed to answer three questions:
| Question | Where to Check |
| Question | Where to check |
| --- | --- |
| Is the node online? | Node list or node detail |
| Which version is running? | Current version on the node detail page |
| Did the last apply succeed? | Apply logs |
| Is the node online? | Node List or Node Details |
| Which version is currently running? | Current Version in Node Details |
| Did the most recent application succeed? | Application Logs |
Node IPs are filled automatically by Agent registration and subsequent heartbeats by default. When you enter or change an IP in the admin UI, the node editor enables "Lock node IP" by default; Agent reports will not overwrite the IP while the lock is enabled. After unlocking, the next Agent heartbeat or WebSocket status report can update it again.
The node IP is automatically filled by Agent registration and heartbeats by default. If you manually enter or modify the IP in the management console, the node edit page defaults to "Lock Node IP"; when enabled, Agent reports will not override this IP. Disabling the lock restores auto-update logic in the next heartbeat or WebSocket state report.
Access analytics and resource snapshots provide basic observability. OpenFlare only keeps access details for a controlled time window; it is not a general-purpose log platform. Use a dedicated logging system for long-term log search.
Traffic Analytics and Resource Snapshots provide basic observability. OpenFlare only retains access details within a controlled time window, and is not positioned as a general logging platform. If you require long-term log indexing, integrate an independent logging system.
## Common Scenarios
### Add a Reverse Proxy for an Internal Service
1. Confirm the Agent node can reach the origin service.
2. Create a site configuration.
3. Add a domain, such as `app.example.com`.
4. Add an origin, such as `http://10.0.0.20:8080`.
1. Verify that the origin service is reachable from the Agent node.
2. Add a website configuration in the management console.
3. Enter the domain, e.g., `app.example.com`.
4. Enter the origin, e.g., `http://10.0.0.20:8080`.
5. Publish and activate the version.
6. Verify the domain from a browser or with `curl`.
6. Verify the domain on the Agent node or from a browser.
> [!TIP]
> If your origin server is deployed internally without a public IP and is unreachable by the Agent, use the intranet penetration tunnel feature to map your service. For detailed instructions, see [Tunnel & Intranet Penetration](./tunnel-usage.md).
### Enable HTTPS for an Existing Domain
1. Prepare a certificate that covers the domain.
2. Upload or create the certificate record.
3. Bind the certificate to the domain in the site configuration.
4. Publish and activate a new version.
5. Verify with `curl -I https://your-domain`.
1. Prepare a certificate covering the domain.
2. Upload or create a certificate record in Certificate Management.
3. Edit the website configuration and select the certificate for the domain.
4. Publish and activate the version.
5. Verify the certificate chain and status code in a browser or via `curl -I https://your-domain`.
### Roll Back a Failed Release
### Roll Back a Failed Publication
1. Open the configuration versions page.
2. Find the last known good version.
3. Activate that version again.
4. Check apply logs until the Agent reports success.
5. Fix the configuration and publish a new version.
1. Open the Configuration Versions page.
2. Locate the last known good version.
3. Re-activate that version.
4. Check the node application logs to verify that the Agent applied the old version.
5. Fix the configuration issues before publishing a new version.
## Recommended Practices
* Set `SESSION_SECRET` explicitly in production and prefer PostgreSQL.
* Preview or diff changes before release.
* Check node details and apply logs after each release.
* Keep the network path from Agents to the Server stable.
* Do not manually edit OpenFlare-managed OpenResty files on nodes; the next release will overwrite them.
* Explicitly configure `SESSION_SECRET` and prefer PostgreSQL in production.
* Review the preview or diff after modifying a website configuration before publishing.
* Check the node details and application logs after every publication.
* Maintain a stable network path from Agent to Server in multi-node deployments.
* Never manually modify OpenResty configurations managed by OpenFlare on the node; these files will be overwritten in the next publication.
+161
View File
@@ -0,0 +1,161 @@
# WAF Auto IP Group Expressions
Automatic IP groups are used to aggregate metrics from request logs on a per-client-IP basis, using Expr expressions to determine if an IP should be added to the group. Automatic IP groups can be referenced by IP blacklists or whitelists in WAF rule groups; during publication, the Server only writes the referenced IP group ID to `waf_config.json`, while IP group members are synchronized independently by the Agent into the local runtime files.
## Configuration Structure
The configuration of an automatic IP group is a JSON object:
```json
{
"lookback_minutes": 60,
"rules": [
{
"name": "Single IP High-Frequency 404 Scanning",
"expr": "request_count > 100 && status_404_ratio >= 0.8"
}
]
}
```
Field Descriptions:
| Field | Type | Role |
| --- | --- | --- |
| `lookback_minutes` | number | How many minutes of request logs to look back during execution. Defaults to 60 minutes if blank, minimum 5 minutes, maximum 43200 minutes. |
| `rules` | array | List of automatic rules. If any rule matches, the IP is added to the automatic IP group list. |
| `rules[].name` | string | Rule name, used only for UI display and error messages. |
| `rules[].expr` | string | Expr expression, must return a boolean value. |
## Evaluation Mechanics
Automatic rules do not evaluate logs request-by-request, but instead aggregate them by client IP first:
1. The Server reads request logs from the past `lookback_minutes` minutes.
2. Groups them by normalized IP (`remote_addr`).
3. Computes metrics like request count, 404 count, and direct IP host count for each IP.
4. Evaluates `rules[].expr` for each IP.
5. If an IP matches any rule, it is written to the automatic IP group's IP member list.
Whether a request is "accessing via IP directly" is determined by the `Host` field in the request logs. If the Host header is an IPv4 or IPv6 literal (e.g., `203.0.113.10`, `[2001:db8::10]`, `203.0.113.10:443`), it is counted in `ip_host_count`.
## Available Metrics
The following metrics are directly available in Expr expressions:
| Keyword | Type | Role |
| --- | --- | --- |
| `ip` | string | The client IP currently being evaluated. |
| `request_count` | number | Total request count of the IP in the lookback window. |
| `status_404_count` | number | Number of 404 responses returned to the IP in the lookback window. |
| `status_404_ratio` | number | 404 request ratio, calculated as `status_404_count / request_count`. |
| `ip_host_count` | number | Number of requests from the IP using an IP address directly as the Host header. |
| `ip_host_ratio` | number | Ratio of direct IP address accesses, calculated as `ip_host_count / request_count`. |
| `client_error_count` | number | Number of requests returning 4xx status codes. |
| `server_error_count` | number | Number of requests returning 5xx status codes. |
| `last_seen_unix` | number | Unix timestamp (in seconds) of the last request from the IP in the lookback window. |
All ratio fields are decimals between `0` and `1`. An 80% ratio should be written as `0.8`, and 50% as `0.5`.
## Common Expr Syntax
Automatic IP groups use the Expr syntax. The expression must return a boolean value.
Common Operators:
| Operator | Role | Example |
| --- | --- | --- |
| `>`, `>=`, `<`, `<=` | Numeric comparison | `request_count > 100` |
| `==`, `!=` | Equality / Inequality | `ip != "127.0.0.1"` |
| `&&` | Logical AND | `request_count > 100 && status_404_ratio >= 0.8` |
| `||` | Logical OR | `status_404_ratio >= 0.8 || server_error_count > 20` |
| `!` | Logical NOT | `!(ip == "127.0.0.1")` |
| `in` | Value is in list | `ip in ["203.0.113.10", "198.51.100.20"]` |
| `not in` | Value is not in list | `ip not in ["127.0.0.1"]` |
| `()` | Grouping controls operator priority | `(request_count > 100 && status_404_ratio >= 0.8) || server_error_count > 50` |
## Built-in Presets
The management console provides two built-in preset rules that can be added directly and adjusted as needed:
```json
{
"name": "Single IP High-Frequency 404 Scanning",
"expr": "request_count > 100 && status_404_ratio >= 0.8"
}
```
Meaning: A single IP requests more than 100 times in the lookback window, and the 404 status code ratio is at least 80%.
```json
{
"name": "Single IP Direct IP Access Mismatch",
"expr": "ip_host_count > 50 && ip_host_ratio > 0.5"
}
```
Meaning: A single IP accesses the server directly using an IP address as the Host header more than 50 times, and this type of access represents more than 50% of its total requests.
## Examples
High-frequency 404 scanning:
```json
{
"lookback_minutes": 60,
"rules": [
{
"name": "High-Frequency 404 Scanning",
"expr": "request_count > 100 && status_404_ratio >= 0.8"
}
]
}
```
Direct IP access mismatch:
```json
{
"lookback_minutes": 30,
"rules": [
{
"name": "Direct IP Access Mismatch",
"expr": "ip_host_count > 50 && ip_host_ratio > 0.5"
}
]
}
```
Capture both high 4xx and 5xx errors:
```json
{
"lookback_minutes": 120,
"rules": [
{
"name": "Abnormal Error Rates",
"expr": "(client_error_count > 80 && request_count > 100) || server_error_count > 30"
}
]
}
```
Exclude trusted IPs:
```json
{
"lookback_minutes": 60,
"rules": [
{
"name": "404 Scanning Excluding Trusted IPs",
"expr": "ip not in [\"203.0.113.10\", \"198.51.100.20\"] && request_count > 100 && status_404_ratio >= 0.8"
}
]
}
```
## Usage Recommendations
Start with a shorter lookback window and higher thresholds to monitor matches, then adjust thresholds gradually. The IP Groups page in the management console allows you to click **"Test Rule"** before saving to view matching IPs in the current window immediately. Once an automatic IP group runs, it overwrites the list of IPs. If you want to permanently whitelist or blacklist certain IPs, add them to a manual IP group instead, and reference both manual and automatic groups in your WAF rule groups.
Updating automatic IP groups does not require publishing configuration versions. Online Agents receive changes via WebSocket and update the local `waf_ip_groups.json` instantly. If WebSocket is unavailable, the Agent reports its local checksum in heartbeats, and the Server syncs only the mismatched IP groups.
+162
View File
@@ -0,0 +1,162 @@
# WAF Security Protection
You will learn: How the OpenFlare edge Web Application Firewall (WAF) works, its protection dimensions, how to manage and reference the three types of IP groups (Manual, Subscription, and Expr-based Automatic IP groups), configure CC protection challenges (PoW human-machine verification) and regional filtering, and achieve sub-second hot updates of IP group members without Nginx reloads.
---
## Core Concepts
Before configuring security policies, you need to understand the core components of the WAF:
| Concept | Description | Scope & Activation Method |
| --- | --- | --- |
| **WAF Rule Group (Rule Group)** | A logical collection of security rules, including: IP whitelists/blacklists (direct input or IP group references), country/region limits, CC protection (PoW), and custom block responses. | Supports global enablement or binding to single/multiple websites. **Modifying rule group definitions requires publishing and activating a configuration version**. |
| **IP Group (IP Group)** | A list container storing individual IPs or CIDR blocks. Divided into **Manual**, **Subscription**, and **Automatic** types. WAF rule groups reference IP groups by ID. | Belongs to dynamic resources. **IP group member updates support sub-second WebSocket hot-syncing, completely bypassing Nginx process reloads**. |
| **PoW Challenge (CC PoW)** | A human-machine verification challenge based on Proof of Work. By prompting browsers to solve hash collisions of a specified difficulty, it silently blocks malicious brute-force scripts and bots while keeping legitimate user experience smooth. | A configuration Tab in the rule group. **Modifying PoW parameters requires publishing and activating a configuration version**. |
---
## Recommended Configuration Sequence
When configuring security protections for your websites, we recommend doing so in the following order:
1. Navigate to IP Groups, creating the required **Manual IP Groups** (e.g., developer whitelist) or **Automatic IP Groups** (e.g., auto-blocked IPs based on 404 scans).
2. Create or edit a **WAF Rule Group**:
* Bind the IP groups you want to reference or block.
* Configure regional whitelists/blacklists for countries or provinces.
* (Optional) Configure human-machine challenge parameters in the `PoW` Tab.
* Set custom status codes (e.g., 403, 418) and HTML block pages in the `Block Response` Tab.
3. Associate the rule group with the corresponding **Website Configuration**.
4. Publish and activate the configuration version to let the edge node (Agent) apply the WAF rules to filter traffic.
---
## Detailed Step Guide
### Step 1: Manage and Configure IP Groups
IP groups are the foundations of large-scale IP filtering. OpenFlare provides three highly resilient types of IP groups:
#### 1. Manual IP Groups (Manual)
* **Purpose**: Statically maintain a list of verified trusted IPs or long-term blocked IPs/CIDR blocks.
* **Configuration**: Click "Create IP Group" -> select type "Manual" -> enter IPs or CIDRs line-by-line (e.g., `192.168.1.100` or `10.0.0.0/24`).
#### 2. Subscription IP Groups (Subscription)
* **Purpose**: Integrate third-party threat intelligence databases or IP ranges published by cloud providers.
* **Configuration**: Select type "Subscription" -> enter fetch URL (supports line-separated plain text or standard JSON formats). A background cron job on the Server periodically pulls the subscription source and updates the group members automatically.
#### 3. Automatic IP Groups (Automatic)
* **Purpose**: **The most aggressive automated defense channel against scans and brute-force attacks**.
* **Configuration**: Select type "Automatic" -> write Expr log aggregation logic. You can directly select built-in presets:
* **Single IP High-Frequency 404 Scanning**: `request_count > 100 && status_404_ratio >= 0.8` (A single IP requesting over 100 times in the past hour with a 404 response ratio of at least 80%).
* **Single IP Direct IP Access Mismatch**: `ip_host_count > 50 && ip_host_ratio > 0.5` (Bypassing domains to hit the server directly using IP address host headers).
* **Test & Run**: Click **"Test Rule"** before saving to preview IPs matching the current log window. Click **"Execute Now"** after saving to aggregate logs immediately and generate the block list.
> [!TIP]
> For the detailed syntax and available metrics of automatic IP groups, see [WAF Auto IP Group Expressions](./waf-ip-group-expr.md).
---
### Step 2: Create and Configure a WAF Rule Group
1. Navigate to the **"WAF"** section in the side menu, and click **"Create Rule Group"**.
2. Enter the rule group name (e.g., `production-api-shield`), and select if it is a "Global Rule Group".
3. Enter rule group details, and configure the tabs sequentially below:
#### 1. Whitelist / Blacklist Configuration (Allow / Block Lists)
* **Direct IPs**: Enter individual IPs or CIDR blocks line-by-line that need temporary whitelisting or blacklisting directly in the text area.
* **IP Group Reference**: Click "Bind IP Groups", selecting the manual, automatic, or subscription IP groups you configured in Step 1. Whitelists permit traffic instantly, whereas blacklists block it.
#### 2. Regional Restriction (GeoIP)
* **Description**: OpenFlare integrates GeoIP geolocation resolution.
* **Configuration**: Toggle the regional restriction switch, selecting "Allow Only" or "Block".
* * For example, if your service is only intended for domestic users, set the mode to "Allow Only" and check `China` in the country list.
* * Supports refining to specific provinces/regions, enabling you to block malicious traffic originating from targeted geographic zones with one click.
#### 3. Human-Machine Challenge Configuration (PoW CC Protection)
* **Description**: Enable CC protection human-machine challenges. When a request triggers the CC protection threshold, the browser renders a silent challenge page, solving a mathematical challenge (hash collision) within several hundred milliseconds. Upon passing, it sets a Cookie and allows subsequent visits. This is seamless to actual users but blocks brute-force scripts and CC tools that do not support JS execution or mathematical computations.
* **Core Parameters**:
* **Status**: Enable / Disable.
* **Hash Difficulty**: Controls the computation difficulty (recommending `4` or `5`).
* **Cookie Expiration**: How long the verification remains valid after passing (e.g., `3600` seconds).
* **Custom Challenge HTML**: Customize the Loading page style of the challenge to match your business design.
#### 4. Block Response (Block Response)
* **Description**: Define the behavior of the WAF when blocking malicious requests.
* **Configuration**:
* **Block Status Code**: Customize the HTTP status code returned, e.g., the standard `403` or a fun `418 (I'm a teapot)`.
* **Block Response Body**: Input custom HTML content shown to blocked attackers (e.g., "WAF Interception: Your request has been logged").
---
### Step 3: Associate the Rule Group with Websites
Once configured, the rule group does not automatically take effect; you need to bind it to specific website configurations.
* **Option A (Recommended)**: In the **"Bind Websites"** Tab of the rule group details, select the websites you wish to apply this rule group to and save.
* **Option B**: Return to **"Website Configuration"**, edit a specific website, and check and bind the rule group in the "Security Protection" section.
> [!NOTE]
> If a rule group is marked as **"Global Rule Group (is_global)"**, it applies to **all websites** hosted on the gateway automatically, requiring no manual binding.
---
### Step 4: Publish & Activate Configurations
1. If you modify **rule group definitions**, **GeoIP scopes**, **PoW CC difficulties**, or **website-to-rule-group bindings**:
* Click **"Preview Config"** -> **"Publish & Activate"** in the top right corner.
* Once the Agent pulls and validates the new version, it rewrites local core OpenResty config files (`waf_config.json`, etc.) and gracefully reloads the processes to apply the policies.
2. If you only update **IP group members** (e.g., adding/deleting an IP in a manual IP group, or an automatic IP group aggregates a new set of blocked IPs periodically):
* **No publication or activation is required!**
* The Server calculates the new MD5 Checksum of the IP group immediately after updating the database.
* The control plane **broadcasts the modified IP group members in real-time to all online Agents via WebSocket**. The Agent overwrites the runtime local disk file `waf_ip_groups.json` incrementally.
* The OpenResty Lua engine calculates the file hash in microseconds when processing new requests. If it detects a Checksum change, it reloads it into the memory dictionary (`ngx.shared`) in real-time. **This entire process requires absolutely no Nginx service reloads, having zero impact on online high-concurrency operations**.
* Even if the WebSocket connection drops, the Agent reports its local Checksum in every heartbeat cycle, and the Server syncs the differential updates to guarantee synchronization.
---
## WAF Evaluation Flow (Filtering Funnel)
When an external request reaches the OpenResty data plane, the WAF runtime evaluates it in the `access` phase according to the funnel decision chain below. Once a match is made, evaluation terminates:
```text
Request enters access phase
│
v
Get all active rule groups bound to this site (Global + Bound Custom groups)
│
v
1. Matches IP whitelist / Whitelist IP group? ──────(Yes)─────► [ Allow (ALLOW) ]
│ (No)
v
2. Matches country / province whitelist? ────────(Yes)─────► [ Allow (ALLOW) ]
│ (No)
v
3. Matches IP blacklist / Blacklist IP group? ──────(Yes)─────► [ Block (BLOCK) ] ──► Return status & HTML block page
│ (No)
v
4. Matches country / province blacklist? ────────(Yes)─────► [ Block (BLOCK) ] ──► Return status & HTML block page
│ (No)
v
5. Is PoW CC protection enabled for this site?
├───(Yes)───► [ Validate PoW Cookie ] ──(Passed)──► [ Allow (ALLOW) ]
│ │
│ (Not Passed)
│ v
│ [ Render PoW Challenge ] ──(Solved)──► Set Cookie & Allow
v
6. No rules triggered, legitimate traffic ─────────────────────► [ Allow (ALLOW) ]
```
---
## Best Practices & Tuning Recommendations
* **Whitelist Precedence & Protection**: Before deploying strict blacklists or regional blocks, we strongly recommend creating a "Trusted IP Group" containing your team's office egress IPs, local development IPs, and third-party callback server IPs (e.g., WeChat or Alipay payment callback addresses), and prioritizing it in the rule group's **whitelist**. This effectively prevents accidental blockages.
* **Reasonably Fine-tune PoW Difficulty**: Human-machine CC challenge hash difficulty (`challenge_difficulty`) is a double-edged sword:
* Difficulty `3`: Computes almost instantly, providing low protection.
* Difficulty `4`: Normal phones/low-end browsers solve it in 100-300ms, providing good protection.
* Difficulty `5`: Requires 500ms-2s, providing strong protection but low-end client browsers might perceive slight loading delays.
* Difficulty `6` and above: Computes exponentially slower, easily freezing client browser CPUs. **We strongly recommend choosing `4` or `5` in production**.
* **Utilize "Test Rule"**: For automatic IP groups, always click **"Test Rule"** before saving. By inspecting the list of matching IPs in the current window, verify if your Expr expressions thresholds (such as request counts, 404 ratios, etc.) are too broad or too strict, preventing accidental blockages of legitimate users.
* **Isolate Static & Dynamic Blacklists**: Never enter static malicious IPs that require permanent blocks directly into automatic IP groups (since the aggregated list will be overwritten in the next cron cycle). You should add permanent malicious IPs into a dedicated "Manual Blacklist IP Group" and reference both the manual and automatic groups in your rule groups.