mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-02 06:56:36 +08:00
文档更新
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
# 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).
|
||||
@@ -1,100 +0,0 @@
|
||||
# Publishing Your First Site
|
||||
|
||||
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.
|
||||
|
||||
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-publish Checks
|
||||
|
||||
Verify that the following conditions are met:
|
||||
|
||||
| Item | Expectation |
|
||||
| --- | --- |
|
||||
| Server | Management console is accessible and log-in succeeds |
|
||||
| Agent | At least one node is online |
|
||||
| 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 Website Configuration
|
||||
|
||||
A new website configuration requires at least:
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
| --- | --- |
|
||||
| Website Name | `app` |
|
||||
| Domain | `app.example.com` |
|
||||
| Origin Address | `http://10.0.0.20:8080` |
|
||||
|
||||
A single domain can belong to only one website configuration. Rate limiting, reverse proxy, and caching parameters are shared site-wide.
|
||||
|
||||
## Bind Certificate
|
||||
|
||||
HTTPS certificates are bound by domain. Domains without a bound certificate will not be placed into `443 ssl` server blocks automatically.
|
||||
|
||||
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 & Activate
|
||||
|
||||
Standard Pipeline:
|
||||
|
||||
```text
|
||||
Modify rules -> Preview / Diff -> Publish -> Generate complete version -> Activate version -> Agent pulls -> Local application -> Report result
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
Verify in the management console after publishing:
|
||||
|
||||
| Position | Expected Result |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
|
||||
Verify Agent logs on the node:
|
||||
|
||||
```bash
|
||||
journalctl -u openflare-agent -n 100 --no-pager
|
||||
```
|
||||
|
||||
Access via domain:
|
||||
|
||||
```bash
|
||||
curl -I http://app.example.com
|
||||
```
|
||||
|
||||
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 Validation:
|
||||
|
||||
```bash
|
||||
curl -I https://app.example.com
|
||||
```
|
||||
|
||||
## Rollback
|
||||
|
||||
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.
|
||||
|
||||
Roll back to an older version:
|
||||
|
||||
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.
|
||||
@@ -1,43 +0,0 @@
|
||||
# Guide Overview
|
||||
|
||||
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 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 Reading Path
|
||||
|
||||
If you are new to OpenFlare, read the documents in the following order:
|
||||
|
||||
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.
|
||||
|
||||
## Role-Based Entrypoints
|
||||
|
||||
| What do you want to do? | Recommended Entrance |
|
||||
| --- | --- |
|
||||
| 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](../../guideline/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 Partitions
|
||||
|
||||
`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 response structures, and repository layout.
|
||||
|
||||
`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.
|
||||
@@ -1,219 +0,0 @@
|
||||
# Quick Start
|
||||
|
||||
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 minimum running unit of OpenFlare consists of:
|
||||
|
||||
| Component | Responsibility |
|
||||
| --- | --- |
|
||||
| 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. |
|
||||
|
||||
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.
|
||||
|
||||
## Environment Requirements
|
||||
|
||||
| Item | Requirement |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
|
||||
* **Docker**: `20.10.0+`
|
||||
* **Docker Compose**: `2.0.0+`
|
||||
|
||||
## 1. Start the Server
|
||||
|
||||
Create a `docker-compose.yml` file in an empty directory:
|
||||
|
||||
```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
|
||||
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 the services:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Verify that the containers are running:
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
docker compose logs -f openflare
|
||||
```
|
||||
|
||||
Once you see `server listening` in the logs and the `openflare` container status is running, access:
|
||||
|
||||
```text
|
||||
http://localhost:3000
|
||||
```
|
||||
|
||||
Default credentials:
|
||||
|
||||
| Username | Password |
|
||||
| --- | --- |
|
||||
| `root` | `123456` |
|
||||
|
||||
Please change the default password immediately after your first login.
|
||||
|
||||
## 2. Prepare Agent Token
|
||||
|
||||
The Agent can be connected using one of two types of credentials:
|
||||
|
||||
| Credential | Applicable Scenario |
|
||||
| --- | --- |
|
||||
| `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 |
|
||||
|
||||
After preparing one of these credentials in the management console, proceed to the next step.
|
||||
|
||||
* **`discovery_token`** path: "System Settings" -> "Auto Registration"
|
||||
* **`agent_token`** path: "Node Management" -> "Add Node"
|
||||
|
||||
## 3. Install/Run the Agent
|
||||
|
||||
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 image directly on the proxy node:
|
||||
|
||||
```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 \
|
||||
-e OPENFLARE_SERVER_URL=http://your-server:3000 \
|
||||
-e OPENFLARE_AGENT_TOKEN=YOUR_AGENT_TOKEN \
|
||||
ghcr.io/rain-kl/openflare-agent:latest
|
||||
```
|
||||
|
||||
### Option B: Execute Installation Script (Local Host Deployment)
|
||||
|
||||
Execute the installation script on the proxy node.
|
||||
|
||||
Using the `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
|
||||
```
|
||||
|
||||
Using the 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
|
||||
```
|
||||
|
||||
The script defaults to:
|
||||
|
||||
| Item | Default Value |
|
||||
| --- | --- |
|
||||
| Install Directory | `/opt/openflare-agent` |
|
||||
| Config File | `/opt/openflare-agent/agent.json` |
|
||||
| systemd Service | `openflare-agent.service` |
|
||||
| OpenResty Path | Automatically detects `openresty` if unspecified |
|
||||
|
||||
Verify the Agent service status:
|
||||
|
||||
```bash
|
||||
systemctl status openflare-agent
|
||||
journalctl -u openflare-agent -f
|
||||
```
|
||||
|
||||
If systemd is not available on the OS, the script outputs manual startup commands instead.
|
||||
|
||||
## 4. Publish Your First Configuration
|
||||
|
||||
Perform the following operations in the management console:
|
||||
|
||||
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.
|
||||
|
||||
The version number format is `YYYYMMDD-NNN`. Historic versions are immutable; rollbacks are accomplished by re-activating an older version.
|
||||
|
||||
## 5. Verify Success
|
||||
|
||||
Confirm in the management console:
|
||||
|
||||
| Position | Expected Result |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
|
||||
Confirm on the Agent node:
|
||||
|
||||
```bash
|
||||
journalctl -u openflare-agent -n 100 --no-pager
|
||||
```
|
||||
|
||||
## Common Failures
|
||||
|
||||
| Symptom | Troubleshooting Direction |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
|
||||
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.
|
||||
@@ -1,106 +0,0 @@
|
||||
# SSO Login Configuration
|
||||
|
||||
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 logins configured via Authentication Sources. Currently, GitHub OAuth and standard OIDC Providers (e.g., Logto, authentik, Keycloak, Casdoor) are supported.
|
||||
|
||||
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.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, prepare the following:
|
||||
|
||||
| Item | Description |
|
||||
| --- | --- |
|
||||
| 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` |
|
||||
|
||||
**Verify that "System Settings -> General Settings -> Server Address" accurately matches your domain name.**
|
||||
|
||||
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
|
||||
|
||||
The Redirect URI / Callback URL in third-party platforms is formatted as:
|
||||
|
||||
```text
|
||||
<OpenFlare URL>/oauth/<Auth Source Name>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
https://openflare.example.com/oauth/github
|
||||
https://openflare.example.com/oauth/company-oidc
|
||||
```
|
||||
|
||||
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. 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.
|
||||
|
||||
Once enabled, the corresponding GitHub login button will display on the login page.
|
||||
|
||||
## Configure OIDC Login
|
||||
|
||||
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. 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.
|
||||
|
||||
Once enabled, the corresponding OIDC login button will display on the login page.
|
||||
|
||||
## Login & Binding Behaviors
|
||||
|
||||
Once a third-party account returns to OpenFlare, it is processed according to the following rules:
|
||||
|
||||
| Scenario | Behavior |
|
||||
| --- | --- |
|
||||
| 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 want only existing users to use SSO, you can disable user registration. Unbound third-party accounts will then trigger the binding flow.
|
||||
|
||||
## Modify Authentication Source
|
||||
|
||||
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 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.
|
||||
|
||||
## Common Problems
|
||||
|
||||
### Returns `invalid_scope`
|
||||
|
||||
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 Address Mismatch
|
||||
|
||||
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.
|
||||
|
||||
### Third-party Login Button Not Showing on Login Page
|
||||
|
||||
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 Saved but Not Displayed in Clear Text
|
||||
|
||||
This is expected behavior. OpenFlare does not echo the Client Secret back via API, displaying only whether the secret is configured.
|
||||
@@ -1,249 +0,0 @@
|
||||
# Troubleshooting
|
||||
|
||||
You will learn: How to troubleshoot OpenFlare Server, database, login, Agent, OpenResty, configuration publishing, and frontend build issues by symptoms.
|
||||
|
||||
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 Diagnostic
|
||||
|
||||
| Symptom | Where to check first |
|
||||
| --- | --- |
|
||||
| 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 Fails to Start
|
||||
|
||||
1. View logs:
|
||||
|
||||
```bash
|
||||
docker compose logs -n 200 openflare
|
||||
```
|
||||
|
||||
For source-code execution, inspect terminal outputs.
|
||||
|
||||
2. Check port conflicts:
|
||||
|
||||
```bash
|
||||
lsof -i :3000
|
||||
```
|
||||
|
||||
3. If using PostgreSQL, verify that the database is healthy:
|
||||
|
||||
```bash
|
||||
docker compose ps postgres
|
||||
docker compose logs -n 100 postgres
|
||||
```
|
||||
|
||||
4. If using SQLite, verify that the database directory is writable:
|
||||
|
||||
```bash
|
||||
ls -ld "$(dirname /path/to/openflare.db)"
|
||||
```
|
||||
|
||||
Common causes:
|
||||
|
||||
| Log or Symptom | Action |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
|
||||
## Admin Console Fails to Load or Shows Blank Page
|
||||
|
||||
1. Verify that the Server is listening:
|
||||
|
||||
```bash
|
||||
curl -I http://127.0.0.1:3000
|
||||
```
|
||||
|
||||
2. If running from source, verify that the frontend static assets have been built:
|
||||
|
||||
```bash
|
||||
cd openflare-server/web
|
||||
pnpm build
|
||||
```
|
||||
|
||||
3. Verify if the browser URL matches your reverse proxy domain.
|
||||
|
||||
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 Credentials Fail to Log In
|
||||
|
||||
The default credentials are `root` / `123456`. If you have modified the password after your first login, use your new password.
|
||||
|
||||
Troubleshooting Steps:
|
||||
|
||||
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.
|
||||
|
||||
### Emergency Reset of Admin Password
|
||||
|
||||
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):
|
||||
|
||||
#### 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
|
||||
```
|
||||
|
||||
Inspect Agent logs:
|
||||
|
||||
```bash
|
||||
journalctl -u openflare-agent -n 200 --no-pager
|
||||
```
|
||||
|
||||
Verify configuration parameters:
|
||||
|
||||
```bash
|
||||
sed -n '1,160p' /opt/openflare-agent/agent.json
|
||||
```
|
||||
|
||||
Key Settings:
|
||||
|
||||
| Configuration | Description |
|
||||
| --- | --- |
|
||||
| `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 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 Fails to Apply New Version after Publishing
|
||||
|
||||
Verify in sequence:
|
||||
|
||||
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.
|
||||
|
||||
Inspect Agent logs:
|
||||
|
||||
```bash
|
||||
journalctl -u openflare-agent -f
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## OpenResty Application Fails
|
||||
|
||||
Common Causes:
|
||||
|
||||
| Cause | Diagnostic |
|
||||
| --- | --- |
|
||||
| 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 Configuration Validation:
|
||||
|
||||
```bash
|
||||
openresty -t -c /path/to/openflare/data/etc/nginx/nginx.conf
|
||||
```
|
||||
|
||||
OpenResty Runtime Status:
|
||||
|
||||
```bash
|
||||
ps aux | grep openresty
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Actual binary paths and main configuration paths are governed by `openresty_path` and `main_config_path` in `agent.json`.
|
||||
|
||||
## HTTPS Fails to Work
|
||||
|
||||
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 will not be added to the HTTPS configuration automatically; this is expected behavior.
|
||||
|
||||
## Traffic Analytics Has No Data
|
||||
|
||||
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
|
||||
pnpm install
|
||||
pnpm lint
|
||||
pnpm typecheck
|
||||
pnpm test
|
||||
pnpm build
|
||||
```
|
||||
|
||||
Common causes:
|
||||
|
||||
| Symptom | Action |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
|
||||
## Documentation Build Fails
|
||||
|
||||
```bash
|
||||
cd docs
|
||||
pnpm install
|
||||
pnpm build
|
||||
```
|
||||
|
||||
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.
|
||||
@@ -1,174 +0,0 @@
|
||||
# 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.
|
||||
@@ -1,156 +0,0 @@
|
||||
# Basic Usage
|
||||
|
||||
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 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 |
|
||||
| --- | --- |
|
||||
| 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 Operation Sequence
|
||||
|
||||
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. 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 Website Configuration
|
||||
|
||||
A website configuration requires at least:
|
||||
|
||||
| Field | Requirement |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
| --- | --- |
|
||||
| Website Name | `docs` |
|
||||
| Domain | `docs.example.com` |
|
||||
| Origin Address | `http://10.0.0.10:8080` |
|
||||
| Back-to-source Host | `docs.internal.example.com` |
|
||||
|
||||
Upstream Address Rules:
|
||||
|
||||
* 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 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:
|
||||
|
||||
* 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 by domain rather than being forced across the entire website.
|
||||
|
||||
Operation Sequence:
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Configure WAF & PoW
|
||||
|
||||
Security protection is centrally accessed via the **WAF** link in the side navigation bar:
|
||||
|
||||
* 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.
|
||||
|
||||
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.
|
||||
|
||||
For detailed information on WAF security configurations and evaluation principles, see [WAF Security Protection](./waf-usage.md).
|
||||
|
||||
## Publish, Activate & Rollback
|
||||
|
||||
Standard Pipeline:
|
||||
|
||||
```text
|
||||
Modify config -> Preview / Diff -> Publish -> Generate complete version -> Activate version -> Agent pulls -> Local application -> Report result
|
||||
```
|
||||
|
||||
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`.
|
||||
|
||||
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.
|
||||
|
||||
## View Nodes & Observability
|
||||
|
||||
The Nodes section is designed to answer three questions:
|
||||
|
||||
| Question | Where to check |
|
||||
| --- | --- |
|
||||
| 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 |
|
||||
|
||||
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.
|
||||
|
||||
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. 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 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 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 Publication
|
||||
|
||||
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
|
||||
|
||||
* 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.
|
||||
@@ -1,161 +0,0 @@
|
||||
# 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.
|
||||
@@ -1,162 +0,0 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user