# Zenith(齐天)代码使用教程
> **L2→L7 全栈网络安全数据面框架** — 从内核旁路到应用层的完整 Rust 网络框架。
>
> 本教程覆盖从快速上手到高级特性的全量用法,所有代码均可在 Linux/Windows 上编译运行。
***
## 目录
1. [🚀 快速上手](#1-快速上手)
2. [🧭 路由与参数提取](#2-路由与参数提取)
3. [🔗 中间件](#3-中间件)
4. [🔒 TLS 1.3 与 HTTPS](#4-tls-1-3-与-https)
5. [⚡ HTTP/2 与 HTTP/3](#5-http-2-与-http-3)
6. [🛡️ WAF Web 应用防火墙](#6-waf-web-应用防火墙)
7. [🚦 IP 准入与端口过滤](#7-ip-准入与端口过滤)
8. [🔀 L4 端口转发与协议转换](#8-l4-端口转发与协议转换)
9. [⚖️ 反向代理与负载均衡](#9-反向代理与负载均衡)
10. [📦 CDN 缓存](#10-cdn-缓存)
11. [🧬 TLS 指纹识别与阻断](#11-tls-指纹识别与阻断)
12. [🎛️ 运行时治理](#12-运行时治理)
13. [🔄 自动降级与跨平台](#13-自动降级与跨平台)
14. [🧩 Feature 组合与部署](#14-feature-组合与部署)
15. [🕸️ 全链路指纹识别与阻断系统](#15-全链路指纹识别与阻断系统)
16. [🧰 独立 Crate 使用模式](#16-独立-crate-使用模式)
17. [🏗️ 链路组合模式](#17-链路组合模式)
18. [🤝 第三方库搭配指南](#18-第三方库搭配指南)
19. [🗺️ 应用场景与搭配速查](#19-应用场景与搭配速查)
20. [🚢 部署最佳实践](#20-部署最佳实践)
- [📎 附录 A. Cargo.toml 完整示例](#a-cargo-toml-完整示例)
- [📎 附录 B. 常用 API 速查](#b-常用-api-速查)
- [📎 附录 C. 平台兼容性矩阵](#c-平台兼容性矩阵)
***
## 1. 🚀 快速上手
### 1.1 依赖配置
```toml
# Cargo.toml
[dependencies]
zenith = { path = "zenith", features = ["web", "runtime"] }
[dev-dependencies]
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
tokio = { workspace = true, features = ["time"] }
```
`web` feature 包含 HTTP/1.1 + HTTP/2 + HTTP/3 + TLS + WAF + 缓存。`runtime` 启用全局运行时和 Supervisor 治理。
### 1.2 最小 HTTP 服务器
```rust
use zenith::api::CanonicalResponse;
use zenith::web::app::{success_response, App};
use zenith::web::server::ProtocolServer;
fn build_app() -> App {
let mut app = App::new();
// 注册路由:GET /
app.get("/", |_req, _rm| {
Ok(success_response("Hello, Zenith!\n", "text/plain; charset=utf-8"))
});
// 路径参数:GET /hello/:name
app.get("/hello/:name", |_req, rm| {
let name = rm.get("name").unwrap_or("stranger");
Ok(success_response(
format!("Hello, {}!\n", name),
"text/plain; charset=utf-8",
))
});
// POST /echo — 回显请求体
app.post("/echo", |req, _rm| {
let mut resp = CanonicalResponse::new(200);
let _ = resp.add_header(b"content-type", b"application/octet-stream");
resp.set_body(req.body().to_vec());
Ok(resp)
});
// GET /status — JSON 状态
app.get("/status", |_req, _rm| {
Ok(success_response(
r#"{"ok":true,"server":"zenith"}"#,
"application/json",
))
});
let _ = app.validate();
app
}
fn main() {
let _ = tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.try_init();
// 初始化全局运行时(自动探测 CPU/NUMA)
let _rt = zenith::rt::init_global(zenith::rt::RuntimeConfig::auto());
let app = build_app();
// 服务器跨连接 Arc 共享('static,供后台线程持有)
let server = std::sync::Arc::new(ProtocolServer::new(app));
zenith::rt::block_on(async move {
let listener = tokio::net::TcpListener::bind("127.0.0.1:18080").await.unwrap();
println!("listening on {}", listener.local_addr().unwrap());
loop {
let (stream, peer) = listener.accept().await.unwrap();
let s = std::sync::Arc::clone(&server);
zenith::rt::spawn(async move {
let std_stream = stream.into_std().unwrap();
let _ = std_stream.set_nonblocking(false);
let _ = tokio::task::spawn_blocking(move || {
s.serve_std_tcp_conn(std_stream, peer, None)
}).await;
});
}
});
}
```
### 1.3 运行
```bash
# Linux
cargo run --release --features web,runtime --example hello_server
# Windows(自动降级到 std::net,全功能可用)
cargo build --release --features web,runtime --example hello_server
target\release\examples\hello_server.exe
```
```bash
curl http://127.0.0.1:18080/ # → 200 "Hello, Zenith!"
curl http://127.0.0.1:18080/hello/world # → 200 "Hello, world!"
curl -X POST -d "ping" http://127.0.0.1:18080/echo # → 200 "ping"
curl http://127.0.0.1:18080/status # → 200 {"ok":true,...}
```
***
## 2. 🧭 路由与参数提取
### 2.1 路由注册
```rust
use zenith::web::app::App;
use zenith::api::CanonicalResponse;
use zenith::web::app::success_response;
let mut app = App::new();
// 静态路由
app.get("/users/:id", |_req, rm| {
let id = rm.get("id").unwrap_or("0");
Ok(success_response(format!("user {}", id), "text/plain"))
});
// 多段路径参数
use zenith::web::extract::path_param_parse;
app.get("/users/:id", |req, rm| {
let id: u64 = path_param_parse(rm, "id")
.map_err(|e| zenith::web::WebError::BadRequest(e.to_string()))?;
Ok(success_response(format!("user #{}", id), "text/plain"))
});
// 内置类型化提取器(不同用法:直接由 FromRequest 推导)
use zenith::web::extract::{Pagination, UserId}; // 需在 handler 内手动调用其 from_request
app.post("/api/users", |req, _rm| { /* ... */ Ok(CanonicalResponse::new(201)) });
app.put("/api/users/:id", |req, _rm| { /* ... */ Ok(CanonicalResponse::new(200)) });
app.delete("/api/users/:id", |_req, _rm| { Ok(CanonicalResponse::new(204)) });
app.patch("/api/users/:id", |req, _rm| { /* ... */ Ok(CanonicalResponse::new(200)) });
// 不区分方法(任何 HTTP 方法都匹配):app.any(path, handler)
app.any("/union", |_req, _rm| Ok(success_response("any method", "text/plain")));
```
### 2.2 查询参数提取
```rust
use zenith::web::extract::{query_param, query_param_or, query_param_parse, parse_query};
use zenith::web::WebError; // handler 返回 Result<_, WebError>
// 注意:handler 闭包参数 req 已是 &CanonicalRequest,直接传 req(勿再取 &)
// query_param 返回 Result<String, ExtractError>,需显式映射为 WebError 才能用 ?
// 必需查询参数(缺失返回 400)
app.get("/search", |req, _rm| {
let q = query_param(req, "q")
.map_err(|e| WebError::BadRequest(e.to_string()))?;
Ok(success_response(format!("搜索: {}", q), "text/plain"))
});
// 带默认值
app.get("/list", |req, _rm| {
let page = query_param_or(req, "page", "1");
Ok(success_response(format!("页码: {}", page), "text/plain"))
});
// 类型解析
app.get("/users", |req, _rm| {
let limit: u32 = query_param_parse(req, "limit").unwrap_or(20);
Ok(success_response(format!("limit={}", limit), "text/plain"))
});
```
### 2.3 请求头提取
```rust
use zenith::web::extract::{header_value, header_required};
use zenith::web::WebError;
## 3. 🔗 中间件
### 3.1 内置中间件
```rust
use zenith::web::middleware::{
CorsMiddleware, AuthMiddleware, IdentityMiddleware,
LoggingMiddleware, RequestIdMiddleware,
};
let mut app = App::new();
// CORS(默认不发送 CORS 头,需显式配置 with_origin)
app.middleware(CorsMiddleware::new()); // 默认安全:不发送任何 CORS 头
// CORS 精细配置
app.middleware(
CorsMiddleware::new()
.with_origin("*") // 显式配置后才发送 CORS 头
.with_methods(vec!["GET".into(), "POST".into()])
.with_headers(vec!["Authorization".into(), "Content-Type".into()])
.with_max_age(3600),
);
// 请求 ID 注入
app.middleware(RequestIdMiddleware::new());
// 日志中间件
app.middleware(LoggingMiddleware::new(true));
// 认证中间件(校验凭据值非空 + 可选恒定时间比较预期值)
app.middleware(AuthMiddleware::new("x-api-key"));
// 启用预期值校验(恒定时间比较,防时序侧信道)
app.middleware(AuthMiddleware::new("Authorization").with_expected_value("Bearer secret-token"));
// 虚拟主机白名单(非白名单 Host → 421)
app.middleware(IdentityMiddleware::new(vec!["localhost".into(), "example.com".into()]));
```
### 3.2 自定义中间件
```rust
use zenith::web::middleware::{Middleware, MiddlewareContext};
use zenith::api::{CanonicalRequest, CanonicalResponse};
#[derive(Debug)]
struct RateLimitMiddleware {
max_requests: u32,
}
impl Middleware for RateLimitMiddleware {
fn name(&self) -> &'static str { "rate-limit" }
fn before(&self, ctx: &mut MiddlewareContext) -> Result<(), Box<CanonicalResponse>> {
// 检查速率限制...
if self.max_requests == 0 {
let resp = CanonicalResponse::new(429);
return Err(Box::new(resp));
}
Ok(())
}
fn after(&self, _req: &CanonicalRequest, response: CanonicalResponse) -> CanonicalResponse {
// 可修改响应
response
}
}
app.middleware(RateLimitMiddleware { max_requests: 100 });
```
***
## 4. 🔒 TLS 1.3 与 HTTPS
### 4.1 自签证书生成
Zenith 内置自签证书生成器,无需外部工具:
```rust
use zenith::tls::cert_manager::{CertGeneration, CertManager};
use zenith::tls::acceptor::TlsAcceptor;
// 从 PEM 创建证书代际
let cert_gen = CertGeneration::from_pem(
include_bytes!("cert.pem"),
include_bytes!("key.pem"),
)?;
```
### 4.2 HTTPS 服务器
```rust
use zenith::tls::acceptor::TlsAcceptor;
use zenith::tls::TlsConfig;
// TLS 配置 → Acceptor(TlsAcceptor 由 TlsConfig 构建,内部封装 TlsEngine)
let tls_config = TlsConfig::new()
.with_certs("cert.pem".to_string(), "key.pem".to_string())
.with_alpn(vec![b"h2".to_vec(), b"http/1.1".to_vec()])
.with_sni(true);
let mut acceptor = TlsAcceptor::new(tls_config);
// 在连接处理中传入 TLS(serve_std_tcp_conn 内部完成 TLS 握手 + ALPN 协商)
server.serve_std_tcp_conn(stream, peer, Some(&mut acceptor))?;
```
> 若手头证书是 PEM 字节而非文件,先用 `CertGeneration::from_pem(bytes)` 加载,再经
> `TlsEngine` 组装为 Acceptor(`TlsAcceptor::from_engine`);TlsConfig 的 `with_certs`
> 负责从文件路径读取证书/私钥。
### 4.3 多域名 SNI 路由
```rust
use zenith::tls::cert_manager::{CertManager, CertGeneration};
let mut cert_manager = CertManager::new();
// 默认证书
cert_manager.set_default(CertGeneration::from_pem(default_cert, default_key)?);
// 按域名设置证书
cert_manager.set_for_domain("api.example.com",
CertGeneration::from_pem(api_cert, api_key)?
);
// 按域名热切换证书
cert_manager.swap_domain("api.example.com");
```
### 4.4 证书代际热切换
```rust
use zenith::tls::cert_manager::CertBank;
let mut bank = CertBank::new();
bank.set_active(CertGeneration::from_pem(cert_v1, key_v1)?);
// 准备新证书
bank.set_standby(CertGeneration::from_pem(cert_v2, key_v2)?);
// 原子切换(旧代际 Arc 引用计数归零后释放)
bank.swap(); // → true
```
***
## 5. ⚡ HTTP/2 与 HTTP/3
### 5.1 HTTP/2(TLS ALPN 自动协商)
HTTP/2 无需额外配置——当 TLS ALPN 协商结果为 `h2` 时,`ProtocolServer` 自动切换到 HTTP/2 帧处理:
```rust
use zenith::tls::TlsConfig;
use zenith::tls::acceptor::TlsAcceptor;
// TLS ALPN 包含 h2,连接后自动检测协议
// 注意:TlsAcceptor::new 接收 TlsConfig(from_pem 的 to_server_config 返回
// Arc<ServerConfig>,不能直接传给 TlsAcceptor::new;用 TlsConfig 配置即可)
let tls_config = TlsConfig::new()
.with_certs("cert.pem".to_string(), "key.pem".to_string())
.with_alpn(vec![b"h2".to_vec(), b"http/1.1".to_vec()]);
let mut acceptor = TlsAcceptor::new(tls_config);
// serve_std_tcp_conn 内部自动:
// TLS 握手 → ALPN 协商 → h2 则走 HTTP/2,否则 HTTP/1.1
server.serve_std_tcp_conn(stream, peer, Some(&mut acceptor))?;
```
### 5.2 HTTP/3 over QUIC
```rust
use zenith::web::quic_server::QuicServerConfig;
use zenith::tls::cert_manager::CertGeneration;
use zenith::tls::quic::QuicVersion;
let cert_gen = CertGeneration::from_pem(cert_pem, key_pem)?;
let quic_config = QuicServerConfig {
bind_addr: "127.0.0.1:18443".parse()?,
version: QuicVersion::V1, // RFC 9000(或 V2 = RFC 9369)
max_connections: 1024, // 最大并发 QUIC 连接
idle_timeout_ms: 30_000, // 空闲超时(毫秒)
};
// 绑定 QUIC 监听
server.bind_quic(quic_config, &cert_gen)?;
// 启动 UDP 数据面循环
// Linux + afxdp feature:io_uring 批量收发
// 其他平台:std::net::UdpSocket
server.serve_udp_loop(65536)?;
```
#### 真实链路验证(外部 curl)
按上述启动 H3 服务器(自签证书)后,用系统 `curl` 走真实 QUIC 链路:
```bash
# --http3-only 强制 HTTP/3;-k 跳过自签证书校验
curl --http3-only -k -i https://127.0.0.1:18443/hello/zenith
# → HTTP/3 200
# content-type: text/plain; charset=utf-8
# Hello, zenith! 🚀
# 同一 QUIC 连接复用(单进程两个请求)
curl --http3-only -k -o NUL -w "%{http_code} " https://127.0.0.1:18443/hello/a https://127.0.0.1:18443/hello/b
# → 200 200
```
> 说明:QPACK Literal Field Line 编码(name_len 3-bit 前缀)与 Section Acknowledgment(仅 RIC>0 时发送)修复后,`curl --http3-only` GET/POST 均以 **exit 0** 正常完成(无 `ERR_CLOSING`)。
### 5.3 协议检测
```rust
use zenith::web::server::ProtocolServer;
use zenith::api::Protocol;
// 从 peek 数据检测协议
let proto = ProtocolServer::detect_protocol_from_peek(peeked_bytes, alpn);
match proto {
Protocol::Http2 => { /* 处理 HTTP/2 */ }
Protocol::Http1 => { /* 处理 HTTP/1.1 */ }
_ => { /* 其他 */ }
}
// TLS 后检测(ALPN 优先 → preface → 默认 H1)
let proto = ProtocolServer::detect_protocol_from_post_tls(post_handshake_data, alpn);
```
***
## 6. 🛡️ WAF Web 应用防火墙
WAF **严格按需:默认关闭**。作为依赖库,Zenith 不写死任何默认开启的安全中间件;需要时在 `ServerConfig` 显式开启(全局 + 按 host 黑白名单)。
> **审计加固**:WAF 在解码后就地删除(压缩)NULL 字节(`\x00`),保留 NULL 后载荷,防止 NULL 字节注入绕过(杜绝"截断到首个 NULL"导致的 fail-open 漏检)。检测模式已扩展:
>
> - **SQLi**:新增 `if(`/`case when`/`into outfile`/`into dumpfile`/`load_file(`/`information_schema`/`regexp`/`between`/`ifnull(`/`coalesce(`
> - **XSS**:新增 `window.location`/`window.open`/`location.href`/`string.fromcharcode`/`unescape(`/`atob(`/`innerhtml`/`outerhtml`/`document.location`
> - **路径穿越**:新增 `..;/`(Tomcat/Jetty 绕过)
### 6.1 按需启用(全局 + 按 host)
```rust
use zenith::web::server::{ProtocolServer, ServerConfig};
// 方式一:全局开启——所有请求都走内置 6 检测器(SQLi/XSS/SSRF/命令注入/路径穿越/BotThreat)
let cfg = ServerConfig::new().with_waf(true);
let server = ProtocolServer::with_config(app, cfg);
// 方式二:仅特定 host 开 WAF,其余关闭(waf_enabled_hosts 白名单)
let cfg = ServerConfig::new()
.with_waf_enabled_hosts(["api.example.com", "admin.example.com"]);
let server = ProtocolServer::with_config(app, cfg);
// 方式三:全局开、个别 host 放行(waf_disabled_hosts 黑名单)
let cfg = ServerConfig::new()
.with_waf(true)
.with_waf_disabled_hosts(["open.example.com"]);
let server = ProtocolServer::with_config(app, cfg);
// 方式四:完全关闭(默认行为)——不调用任何 with_waf*
let server = ProtocolServer::new(app);
// 内置 6 检测器拦截示例(需先 with_waf(true)):
// curl "http://127.0.0.1:18080/?id=1' OR '1'='1" → 403 (SQLi)
// curl "http://127.0.0.1:18080/?q=<script>alert(1)" → 403 (XSS)
// curl "http://127.0.0.1:18080/?url=http://169.254..." → 403 (SSRF)
// curl "http://127.0.0.1:18080/?cmd=;cat /etc/passwd" → 403 (命令注入)
// curl "http://127.0.0.1:18080/../../../etc/passwd" → 403 (路径穿越)
```
判定规则:某 host 是否启用 WAF = `(waf_enabled || host ∈ waf_enabled_hosts) && host ∉ waf_disabled_hosts`。
### 6.1.1 完全自定义规则 / 自定义检测器(独立 WafEngine)
内置管线固定使用默认 6 检测器,不支持运行时替换默认规则。若需**只用自定义规则**(不用默认检测器)或**自定义检测器**,用独立 `WafEngine` 在自定义中间件/路由层实现:
```rust
use zenith::waf::{WafEngine, RuleBuilder, PatternField, FxHashMap};
// 引擎 A:完全自定义规则,不用默认 6 检测器(new() 默认零检测器零规则)
let mut waf_a = WafEngine::new(); // 不调用 with_default_detectors()
waf_a.add_rule(
RuleBuilder::new("only-my-rule")
.pattern(PatternField::Query, "MY_MARKER")
.build(),
);
// 引擎 B:默认 6 检测器 + 追加自定义规则(new() + with_default_detectors())
let mut waf_b = WafEngine::new().with_default_detectors();
waf_b.add_rule(RuleBuilder::new("extra").pattern(PatternField::UserAgent, "bot").build());
// 引擎 C:完全关闭 WAF(空引擎,任何请求都放行 has_threat=false)
let waf_off = WafEngine::new();
// 在自定义 handler / 中间件里按 host 或路径选择引擎
fn route_waf(host: &str, req: &zenith::api::CanonicalRequest) -> bool {
let engine = match host {
"api.example.com" => &waf_b, // 强防护:默认 + 自定义
"open.example.com" => &waf_a, // 仅自定义规则
_ => &waf_off, // 其余 host 完全关闭
};
let headers: FxHashMap<&str, &str> = req.headers_iter()
.iter().map(|h| (h.name_str(), h.value_str())).collect();
!engine.check_request(req.method.as_str(), req.path_str(), &headers, req.body(), req.query_str()).has_threat
}
```
### 6.2 自定义 WAF 规则
```rust
use zenith::waf::{WafEngine, RuleBuilder, DetectionSeverity, PatternField, FxHashMap};
// ProtocolServer 内置的 6 检测器是自带的,运行期不可注入自定义规则;
// 自定义规则请使用独立 WafEngine(真实公开 API)。
let mut waf = WafEngine::new();
// 自定义规则:User-Agent 含 "bot" 的请求直接阻断(RuleBuilder 默认 action = Block)
let rule = RuleBuilder::new("block-user-agent-bot")
.description("拦截自动化爬虫")
.severity(DetectionSeverity::Medium)
.pattern(PatternField::UserAgent, "bot")
.monitor() // 可选:改为仅监控不阻断;不调用则默认 Block
.build();
waf.add_rule(rule);
// 检查请求(headers 为 &str 映射,专用 FxHashMap 类型)
let mut headers = FxHashMap::default();
headers.insert("user-agent", "Googlebot/2.1");
let result = waf.check_request("GET", "/api/users", &headers, b"", "");
if result.has_threat {
println!("被阻断: {:?} 规则={:?}", result.severity, result.triggered_rules);
// 触发 { Monitor } 时 has_threat 仍为 true,但动作由规则 action 决定
}
// ── 规则组合(不同用法)──────────────────────────────────────
// 单条件:path / path_prefix / methods / header_contains / query_value /
// body_pattern / pattern(PatternField, ...) 各取其一
// 多条件组合:.and(vec![...]) 全部满足才命中;.or(vec![...]) 任一满足即命中
use zenith::waf::RuleCondition;
// 场景 A:仅监控不阻断(配合 instrumentation 观察误报)
waf.add_rule(
RuleBuilder::new("monitor-union-select")
.severity(DetectionSeverity::High)
.pattern(PatternField::Query, "UNION SELECT")
.monitor() // 仅记录,不返回 403
.build(),
);
// 场景 B:AND 组合——路径必须以 /admin 开头 且 方法为 POST 才命中
// RuleCondition 为结构体变体,需带字段名构造
waf.add_rule(
RuleBuilder::new("admin-post")
.path_prefix("/admin")
.and(vec![RuleCondition::Method {
methods: vec!["POST".into()],
}])
.build(), // 默认 action = Block
);
// 场景 C:OR 组合——任一触发即命中(多个独立条件的并集)
waf.add_rule(
RuleBuilder::new("or-conditions")
.or(vec![
// 头部值包含匹配:HeaderValue { name, expected, contains }
RuleCondition::HeaderValue {
name: "x-api-key".into(),
expected: "secret".into(),
contains: true,
},
// 请求体子串匹配:Pattern { field, pattern }
RuleCondition::Pattern {
field: PatternField::Body,
pattern: "password=".into(),
},
])
.build(),
);
// 场景 C2:基于内置检测器触发(DetectorTriggered)
// 检测器 ID:SQL_INJECTION / XSS / SSRF / COMMAND_INJECTION / PATH_TRAVERSAL / BOT_THREAT
waf.add_rule(
RuleBuilder::new("strict-xss")
.and(vec![RuleCondition::DetectorTriggered {
detector: "XSS".into(),
}])
.build(),
);
// 场景 D:query 精确值匹配(query_value(name, expected))
let _r2 = RuleBuilder::new("block-debug")
.query_value("debug", "1")
.build();
```
### 6.3 大 body 卸载
```rust
// 当 body > 64KB 时,WAF 检查自动卸载到专用消费线程
// 卸载超时/失败 → 回退内联执行(检查绝不丢弃,fail-closed)
// 无需手动配置——SecurityPipeline 自动处理
```
### 6.4 安全加固特性
v2 综合审计后,Zenith 在以下方面进行了安全加固(均为内部自动生效,无需用户配置):
**密钥与凭据安全:**
- `CertGeneration` 使用 `Zeroizing<PrivateKeyDer>`,作用域结束自动擦除私钥材料
- `AuthMiddleware` 校验凭据值(默认 `require_non_empty`,可选 `with_expected_value` 恒定时间比较)
- `ct_compare` 使用 `core::hint::black_box` 增强恒定时间保证
- CORS `allow_origin` 默认为空——不发送任何 CORS 头,需显式 `with_origin` 配置
**协议层加固:**
- `drive_h3` 强制 `max_response_bytes`,与 H1 路径对齐
- QUIC STOP\_SENDING(0x05)独立解析(原与 RST\_STREAM 合并)
- QUIC CRYPTO 缓冲区限制 65536 字节
- HTTP/3 stream ID 取模在 u64 空间执行(32 位安全)
- `ChunkedDecoder` trailer\_buf 限制 8192 字节
- `TimerWheel` 长延迟钳位防溢出
**连接与资源管理:**
- `ForwardLease` 实现 `Drop` + `pool_idx` 精确跟踪,panic 时防止连接池泄漏
- `ConnectionTable` 使用 `free_stack` 实现 O(1) 槽位分配
- 反向代理自动追加客户端 IP 到 X-Forwarded-For 头
**v3 22 维度审计加固:**
- BPF `bpf_redirect_map` 使用 `XDP_PASS` flags,XSKMAP 竞态删除安全回退
- `detect_locked_memory_kb` 使用 `getrlimit(RLIMIT_MEMLOCK)` 读取真实上限
- `ct_compare` 4 个衍生函数补全 `core::hint::black_box`
- 指纹评分模型引入白名单/黑名单机制
- 指纹向量槽位冲突修复(独立变体)
- `DecisionAction→EnforcementAction` 映射闭合流水线
- `ForwardEngine` 无白名单 fail-closed
- LRU/FIFO 淘汰 BTreeMap O(log n)
- Histogram Prometheus histogram 格式导出
- `PermissionSet` u16 扩展
- 新 Worker QoS 继承
- TCP SynReceived ACK 校验一致
- 审计 `log()` 默认 IP 脱敏
***
## 7. 🚦 IP 准入与端口过滤
### 7.1 SourceAdmissionEngine(L3/L4 包过滤)
```rust
use zenith::net::source_admission::{
SourceAdmissionEngine, AdmissionRule, AdmissionAction, IpAddr, ProtoMatch,
};
// 创建引擎:默认拒绝所有
let mut engine = SourceAdmissionEngine::deny_all();
// 规则 1: 允许 127.0.0.1 所有流量
engine.add_rule(AdmissionRule {
id: 1,
src_ip: IpAddr::V4([127, 0, 0, 1]),
prefix_len: 0, // 0 = 精确匹配
src_port: 0, // 0 = 通配
dst_port: 0, // 0 = 通配
proto: ProtoMatch::Any,
action: AdmissionAction::Allow,
enabled: true,
})?;
// 规则 2: 拒绝 10.0.0.1 的所有流量(IP 黑名单)
engine.add_rule(AdmissionRule {
id: 2,
src_ip: IpAddr::V4([10, 0, 0, 1]),
prefix_len: 0,
src_port: 0,
dst_port: 0,
proto: ProtoMatch::Any,
action: AdmissionAction::Deny,
enabled: true,
})?;
// 规则 3: 只允许 TCP 8080 端口
engine.add_rule(AdmissionRule {
id: 3,
src_ip: IpAddr::V4_WILDCARD,
prefix_len: 0,
src_port: 0,
dst_port: 8080,
proto: ProtoMatch::Tcp,
action: AdmissionAction::Allow,
enabled: true,
})?;
// 评估数据包
let action = engine.evaluate(
IpAddr::V4([192, 168, 1, 100]), // 源 IP
54321, // 源端口
8080, // 目标端口
6, // 协议号 (6=TCP, 17=UDP, 1=ICMP)
);
// → AdmissionAction::Allow(匹配规则 3)
```
### 7.2 CIDR 子网白名单(L4 转发层)
```rust
use zenith::forward::AddressWhitelist;
use std::net::IpAddr;
// 白名单:允许 127.0.0.0/8 + 192.168.0.0/16
let whitelist = AddressWhitelist::new()
.with_allowed_cidr_ip(IpAddr::from([127u8, 0, 0, 0]), 8)
.with_allowed_cidr_ip(IpAddr::from([192u8, 168, 0, 0]), 16);
// 检查地址
assert!(whitelist.is_ip_allowed(&IpAddr::from([127u8, 0, 0, 1]))); // true
assert!(!whitelist.is_ip_allowed(&IpAddr::from([10u8, 0, 0, 1]))); // false
```
***
## 8. 🔀 L4 端口转发与协议转换
### 8.1 TCP 端口转发(跨平台统一 API)
```rust
use zenith::forward::TcpRelay;
use std::net::{TcpListener, TcpStream};
// 监听客户端连接
let listener = TcpListener::bind("127.0.0.1:8080")?;
let (client_conn, peer) = listener.accept()?;
// 连接上游
let upstream = TcpStream::connect("127.0.0.1:9090")?;
// TcpRelay 自动选择最优策略:
// Linux + linux feature → splice(2) 零拷贝
// 其他平台 → 用户态带背压拷贝回退
let relay = TcpRelay::default();
let (c2u, u2c) = relay.relay(&client_conn, &upstream)?;
println!("转发完成: client→upstream={}B, upstream→client={}B", c2u, u2c);
```
### 8.2 ForwardEngine + IP 白名单
```rust
use zenith::forward::{ForwardEngine, ForwardProtocol, AddressWhitelist};
use std::net::{SocketAddr, IpAddr};
// 白名单只允许 127.0.0.1(防 L4 级 SSRF)
let whitelist = AddressWhitelist::new()
.with_allowed_ip(IpAddr::from([127u8, 0, 0, 1]));
let mut engine = ForwardEngine::new().with_whitelist(whitelist);
// 非白名单 IP 会被拒绝
let client = "10.0.0.1:12345".parse::<SocketAddr>().unwrap();
let upstream = "127.0.0.1:9090".parse::<SocketAddr>().unwrap();
// create_session 会校验客户端和上游地址
let session_id = engine.create_session(ForwardProtocol::Tcp, client, upstream);
// → None(10.0.0.1 不在白名单,拒绝)
// 白名单内 IP 通过
let client_ok = "127.0.0.1:12345".parse::<SocketAddr>().unwrap();
let session_id = engine.create_session(ForwardProtocol::Tcp, client_ok, upstream);
// → Some(id)
```
### 8.3 UDP→UDP 转发
```rust
use std::net::UdpSocket;
let relay_sock = UdpSocket::bind("127.0.0.1:8080")?;
let backend_addr = "127.0.0.1:9090";
let mut buf = [0u8; 4096];
// 接收客户端数据
let (n, client_addr) = relay_sock.recv_from(&mut buf)?;
// 转发到后端
relay_sock.send_to(&buf[..n], backend_addr)?;
// 接收后端回显
let (n2, _) = relay_sock.recv_from(&mut buf)?;
// 转发回客户端
relay_sock.send_to(&buf[..n2], client_addr)?;
```
### 8.4 TCP→UDP 协议转换
```rust
// TCP 接收 → UDP 发送 → UDP 接收 → TCP 回写
let mut tcp_conn: TcpStream = /* 客户端 TCP 连接 */;
let udp_sock = UdpSocket::bind("127.0.0.1:0")?;
let mut buf = [0u8; 4096];
// TCP 接收
let n = tcp_conn.read(&mut buf)?;
// 协议转换:TCP → UDP
udp_sock.send_to(&buf[..n], "127.0.0.1:9090")?;
// UDP 接收回显
let (n2, _) = udp_sock.recv_from(&mut buf)?;
// 协议转换:UDP → TCP 回写
tcp_conn.write_all(&buf[..n2])?;
```
### 8.5 ForwardConfig:容量/带宽配置与热更新
`ForwardEngine` 的并发会话上限与单会话带宽可配置,并可**运行时热更新**(无需重建引擎):
```rust
use zenith::forward::{ForwardConfig, ForwardEngine, ForwardProtocol};
// 构建期注入自定义容量/带宽(with_config)
let mut engine = ForwardEngine::with_config(
ForwardConfig::default()
.with_max_concurrent_sessions(8192) // 并发会话上限
.with_max_bandwidth_per_session(2 * 1024 * 1024 * 1024), // 单会话带宽(字节/秒)
);
// 运行时热更新:容量/带宽即时生效(set_config)
engine.set_config(
ForwardConfig::default().with_max_concurrent_sessions(4096),
);
let fc = engine.config(); // 观测当前值
println!("max_sessions={} max_bw={}", fc.max_concurrent_sessions, fc.max_bandwidth_per_session);
```
在 web facade 下,经 `ProtocolServer` 统一热更新同名配置:
```rust
// 构建期:ServerConfig.with_forward_config(...)
let cfg = zenith::web::ServerConfig::new().with_forward_config(
zenith::forward::ForwardConfig::default().with_max_concurrent_sessions(2048),
);
let server = zenith::web::server::ProtocolServer::with_config(app, cfg);
// 运行时热更新(clone 共享引擎,立即生效)
server.set_forward_config(
zenith::forward::ForwardConfig::default().with_max_concurrent_sessions(4096),
);
```
***
## 9. ⚖️ 反向代理与负载均衡
### 9.1 注册代理路由
```rust
use zenith::proxy::LoadBalanceStrategy;
// /api/* → 后端 127.0.0.1:9090(RoundRobin)
server.add_proxy_route(
"/api",
vec![("127.0.0.1:9090".to_string(), 1)], // (地址, 权重)
LoadBalanceStrategy::RoundRobin,
);
// /proxy/* → 多后端加权负载均衡
server.add_proxy_route(
"/proxy",
vec![
("127.0.0.1:9091".to_string(), 3), // 权重 3
("127.0.0.1:9092".to_string(), 1), // 权重 1
],
LoadBalanceStrategy::WeightedRoundRobin,
);
// 代理路径上的 WAF 也自动生效
// curl "http://127.0.0.1:18080/api/?id=1' OR '1'='1" → 403
// ── 上游协议:scheme 前缀自动识别 ──────────────────────────────
// 裸地址 / http:// → HTTP/1.1 明文 https:// → TLS 1.3
// h2:// → HTTP/2 over TLS h3:// → HTTP/3 over QUIC(真实 QUIC 客户端)
// tcp:// / udp:// → L4 透明转发(不经 HTTP 代理路径)
// auto:// → 自动计算最优路径(ALPN 协商 h2 > http/1.1 + 健康感知降级/恢复)
server.add_proxy_route(
"/h3api",
vec![("h3://127.0.0.1:18443".to_string(), 1)],
LoadBalanceStrategy::RoundRobin,
);
server.add_proxy_route(
"/autopath",
vec![("auto://127.0.0.1:19090".to_string(), 1)],
LoadBalanceStrategy::RoundRobin,
);
```
### 9.2 负载均衡策略
```rust
use zenith::proxy::LoadBalanceStrategy;
// 6 种策略
LoadBalanceStrategy::RoundRobin, // 轮询
LoadBalanceStrategy::P2C, // Power of Two Choices(默认,最优)
LoadBalanceStrategy::Rendezvous, // 一致性哈希
LoadBalanceStrategy::Ewma, // 指数加权移动平均(延迟感知)
LoadBalanceStrategy::WeightedRoundRobin, // 加权轮询
LoadBalanceStrategy::IpHash, // 按 IP 哈希(会话保持)
```
### 9.3 Auto 最优路径(自动协商)
`auto://` 上游自动计算最优路径,无需手动指定协议:
- **ALPN 协商**:TLS 1.3 握手时 offer `["h2", "http/1.1"]`,服务器优先选 h2,否则回退 http/1.1(单次握手直接决定,无需先 h2 再降级)。
- **健康感知降级**:H2 连接连续失败计入黑名单,期间自动降级为 http/1.1(fail-closed,不静默丢弃请求)。
- **自动恢复**:降级期每 100 次成功请求探测一次上游,探测成功即恢复 h2(黑名单不会永久卡死)。
```rust
// 对同一上游,auto:// 会根据服务器实际能力自动选择 h2 或 http/1.1
server.add_proxy_route(
"/api",
vec![("auto://api.example.com:443".to_string(), 1)],
LoadBalanceStrategy::RoundRobin,
);
```
> **fail-closed 语义**:`h3://` / `https://` / `auto://` 上游不可达时返回连接/超时错误(502),**绝不静默降级**到更弱协议。`tcp://`/`udp://` 属 L4 转发,经 HTTP 代理路径返回 `UnsupportedScheme`。
### 9.4 ProxyConfig:连接池/超时/健康阈值配置与热更新
反向代理运行参数(连接池、超时、健康阈值共 20+ 旋钮)全部可配置,并支持**运行时热更新**:
```rust
use zenith::proxy::ProxyConfig;
// 构建期:ServerConfig.with_proxy(...)
let proxy_cfg = ProxyConfig::default()
.with_pool_max_total(1024) // 连接池总上限
.with_pool_max_per_upstream(256) // 每上游池上限
.with_forward_connect_timeout_ms(5_000) // 连接超时
.with_forward_read_timeout_ms(30_000) // 读取超时
.with_health_failure_threshold(3) // 连续失败熔断阈值
.with_forward_max_response_bytes(16 * 1024 * 1024);
// 运行时热更新(ProtocolServer,无需重建引擎)
server.set_proxy_config(proxy_cfg); // 整体替换
p.health_recovery_timeout_ms = 10_000;
});
let pc: ProxyConfig = server.proxy_config(); // 观测当前值
```
> **热更新语义**:`set_proxy_config`/`update_proxy_config` 后——**转发超时**(connect/read/H3/auto-TLS)每请求读取当前值,对既有路由**立即生效**;**连接池/健康阈值**在引擎内固化为活实例,对 `add_proxy_route` 后续注册的新路由生效(`add_proxy_route` 读取当前配置)。
***
## 10. 📦 CDN 缓存
### 10.1 缓存策略配置
```rust
use zenith::cache::policy::{CachePolicy, Cacheability, CachePolicyBuilder};
// 公开缓存,max-age=3600
let policy = CachePolicy::public(3600)
.with_stale_while_revalidate(600) // 600s stale-while-revalidate
.with_s_maxage(1800) // 共享缓存 1800s
.with_must_revalidate(); // 过期后必须重新验证
// 私有缓存
let private = CachePolicy::private(600);
// 不缓存
let no_store = CachePolicy::no_store();
// 从 Cache-Control 头解析
let parsed = CachePolicy::parse_directive("public, max-age=3600, stale-while-revalidate=600");
```
### 10.2 缓存引擎
```rust
use zenith::cache::{CacheEngine, CacheEntry, CacheKey, CacheKeyBuilder, CachePolicy, CacheHit, ConditionalHit, EvictionPolicy};
// 创建缓存引擎(16 分片,65536 条目上限)
let cache = CacheEngine::new(65536, 64 * 1024 * 1024)
.with_policy(EvictionPolicy::Lru)
.with_shared_cache(true); // 启用 s-maxage
// 缓存键:由 (method, path){+query}{+vary} 构建
let key = CacheKeyBuilder::new("GET", "/api/users").build();
// 等价写法:let key: CacheKey = ("GET", "/api/users").into();
let entry = CacheEntry::new(
key.clone(),
b"response body".to_vec(),
200,
"text/html".to_string(),
CachePolicy::public(3600),
1, // tenant_id: u32(非字符串)
zenith::core::current_time_ms(),
);
cache.put(entry);
// 查询缓存(key 传 &CacheKey,tenant 为 u32)
let hit = cache.get(&key, 1, zenith::core::current_time_ms());
match hit {
CacheHit::Fresh(entry) => {
// 命中新鲜缓存
println!("body: {}", String::from_utf8_lossy(entry.value.as_ref()));
}
CacheHit::Stale(entry) => {
// 命中过期缓存(可后台刷新)
}
CacheHit::Miss => {
// 未命中
}
}
// 条件请求(key 传 &CacheKey,tenant 为 u32,Range 传 Option<ByteRange>)
let now_ms = zenith::core::current_time_ms();
let conditional = cache.get_conditional(
&key, 1, now_ms,
Some("etag-123"), // If-None-Match
None, // Range
);
match conditional {
ConditionalHit::Full(entry) => { /* 200 完整响应 */ }
ConditionalHit::NotModified { etag } => { /* 304 */ }
ConditionalHit::Partial { entry, range, total } => { /* 206 */ }
ConditionalHit::RangeNotSatisfiable { total } => { /* 416 */ }
ConditionalHit::Miss => { /* 404 */ }
}
// ── 不同用法:淘汰策略与自定义 CachePolicy ────────────────────
// 三种淘汰策略(默认 Lru):
let _lru = CacheEngine::new(65536, 64 * 1024 * 1024).with_policy(EvictionPolicy::Lru);
let _fifo = CacheEngine::new(65536, 64 * 1024 * 1024).with_policy(EvictionPolicy::Fifo);
let _random = CacheEngine::new(65536, 64 * 1024 * 1024).with_policy(EvictionPolicy::Random);
// 用 CachePolicyBuilder 精细构造(默认 CachePolicy::public(3600) 之外的场景)
// cacheability 经 new() 指定:Public / Private / NoCache / NoStore
use zenith::cache::policy::{CachePolicyBuilder, Cacheability};
let custom = CachePolicyBuilder::new(Cacheability::Public)
.max_age(120) // 120 秒新鲜期
.stale_while_revalidate(30) // 过期后 30 秒内可 stale-while-revalidate
.s_maxage(3600) // 共享缓存的 s-maxage
.must_revalidate() // 过期后必须回源
.build();
// 等价简写:CachePolicy::no_cache() / private(600) / no_store()
```
***
## 11. 🧬 TLS 指纹识别与阻断
### 11.1 记录 TLS 指纹
```rust
use zenith::tls::fingerprint::Ja3Fingerprint;
// TLS 握手完成后自动记录指纹(SecurityPipeline 内置)
let fingerprints = server.security().fingerprint_snapshot();
for fp in &fingerprints {
println!("JA3: {} JA4: {}", fp.ja3_hash, fp.ja4_hash);
}
// Ja3Fingerprint 字段:ja3_string / ja3_hash / ja4_hash
```
### 11.2 指纹黑名单
> **严格按需**:内置管线默认**不**自动执行指纹黑名单/限流(避免写死访问控制误伤正常请求)。
> 需在 `ServerConfig` 显式开启 `with_fingerprint_security(true)`,管线才会自动拦截黑名单指纹 / 限流。
> 下述方法为**手动调用**入口(任意场景可用),与自动管线解耦。
```rust
use zenith::web::server::ServerConfig;
// 方式一:管线自动执行(黑名单 + 限流)
// 限流窗口/次数均可配置(默认 100 次 / 60s),同样走 ServerConfig:
let server = ProtocolServer::with_config(
app,
ServerConfig::new()
.with_fingerprint_security(true)
.with_fingerprint_rate_limit_requests(200) // 每窗口最大请求数
.with_fingerprint_rate_limit_window_ms(30_000), // 窗口 30s
);
// 方式二:手动调用(不依赖管线开关)
// 添加 JA3 前缀到黑名单
server.security().add_fingerprint_to_blocklist("abc123".to_string());
// 检查指纹是否在黑名单中
let blocked = server.security().check_fingerprint_blocklist(Some(&fingerprint));
if let Some(reason) = blocked {
println!("被阻断: {}", reason);
}
// 速率限制(60 秒内最多 100 次请求)
let allowed = server.security().check_fingerprint_rate_limit(
Some(&fingerprint),
100, // max_requests_per_window
60_000, // window_ms
);
if !allowed {
// 429 Too Many Requests
}
```
### 11.3 HTTP/3(QUIC)TLS 指纹
HTTP/3 连接同样采集并阻断 JA3/JA4 指纹。QUIC 的 CRYPTO 流中 ClientHello 为**裸 handshake 消息(无 TLS record 层)**,需用 `from_quic_client_hello` 解析(与 TCP/TLS 路径的 `from_client_hello` 口径一致):
```rust
use zenith::tls::fingerprint::Ja3Fingerprint;
// QUIC CRYPTO 流中的裸 ClientHello(自 0x01 起始,非 record 头 0x16)
let fp = Ja3Fingerprint::from_quic_client_hello(&quic_crypto_client_hello);
if let Some(fp) = fp {
println!("QUIC JA3: {} JA4: {}", fp.ja3_hash, fp.ja4_hash);
}
```
桥接层(`zenith-web::quic_server`)在三条 `handle_initial_packet` 路径(新连接 / existing-conn 主包 / coalesced 分片)统一经 `bind_pending_fingerprint` 绑定,并回填 `last_fingerprint` → `security.record_fingerprint`,与 TCP/TLS 共用同一黑名单/限流判定。真实 `curl.exe --http3` 经黑名单 JA4 后连接被 **403** 阻断(`zenith/examples/fingerprint_h3_block_test.rs` 实测)。
***
## 12. 🎛️ 运行时治理
### 12.1 全局运行时
```rust
use zenith::rt::{RuntimeConfig, init_global, block_on, spawn};
// 自动探测最优配置(CPU 核数、NUMA 拓扑、栈大小)
let _rt = init_global(RuntimeConfig::auto());
// 便捷 spawn
let task = spawn(async { 42 });
let result = block_on(async { task.await.unwrap() });
assert_eq!(result, Ok(42));
// 手动配置
let _rt = init_global(RuntimeConfig::new().with_worker_threads(8).with_stack_size(2 * 1024 * 1024));
```
### 12.2 Supervisor 治理
```rust
// 启动 Supervisor
server.start_supervisor();
// 查看状态
let state = server.supervisor_state();
println!("Supervisor: {:?}", state);
// 停止 Supervisor
server.stop_supervisor();
```
### 12.3 ChangeSet 热切换
```rust
// 触发热切换(八态机:prepare → validate → ... → commit)
let generation = server.trigger_changeset()?;
println!("新代际: {}", generation);
// 查看代际状态
let state = server.changeset_state();
```
### 12.4 Prometheus 指标
```rust
// 导出 Prometheus 0.0.4 文本格式
let metrics = server.export_metrics();
println!("{}", metrics);
// 指标包含:
// - requests_total / cache_hits / cache_misses
// - waf_blocked
// - changeset_active_generation
// - request_duration_us (histogram)
// - proxy_upstream_success / proxy_upstream_error
```
### 12.5 审计日志
```rust
// 获取审计日志快照
let logs = server.audit_log();
for entry in &logs {
println!("{}", entry);
}
// 审计事件包含:WAF 拦截、IP 拒绝、身份不一致、故障、限流等
// 敏感字段自动脱敏(password/token/secret/api_key/authorization)
```
***
## 13. 🔄 自动降级与跨平台
### 13.1 环境探测与 Profile 选择
```rust
use zenith::capability::detection::EnvironmentDetector;
use zenith::capability::profile::{ProfileSelector, Profile, ProfileFeatures};
// 探测系统能力
let snapshot = EnvironmentDetector::new().detect();
println!("CPU: {}", snapshot.cpu_cores);
println!("XDP Native: {}", snapshot.xdp_native_supported);
println!("AF_XDP: {}", snapshot.af_xdp_supported);
println!("io_uring: {}", snapshot.io_uring_supported);
// 自动选择最优 Profile
let selector = ProfileSelector::new();
let profile = selector.select(&snapshot);
println!("Profile: {} (tier={})", profile.as_str(), profile.tier());
// 查看特性映射
let features = ProfileFeatures::from_profile(profile, &snapshot);
println!("basic_socket: {}", features.basic_socket);
println!("zero_copy: {}", features.zero_copy);
```
### 13.2 降级链
```rust
// Performance → Balanced → Minimal → Minimal
let p1 = Profile::Performance;
let p2 = p1.degrade(); // Balanced
let p3 = p2.degrade(); // Minimal
let p4 = p3.degrade(); // Minimal (终止)
```
### 13.3 跨平台行为
| AF\_XDP/eBPF | splice(2) + io\_uring 零拷贝 | 自动降级,std::net |
| TCP 转发 | splice(2) 内核零拷贝 | std::io::copy 用户态 |
| CPU 亲和 | sched\_setaffinity | 桩(返回 Unsupported) |
| HTTP/1.1 | 完整 | 完整 |
| HTTPS/TLS 1.3 | 完整 | 完整 |
| HTTP/2 | 完整 | 完整 |
| WAF | 完整 | 完整 |
| 代理/缓存 | 完整 | 完整 |
| 自动降级 | Performance/Balanced | Minimal |
```rust
// TcpRelay 跨平台——用户无需关心
let relay = TcpRelay::default();
let (c2u, u2c) = relay.relay(&client, &upstream)?;
// Linux: splice(2) 零拷贝
// Windows: 用户态带背压拷贝回退
// 行为一致,API 相同
```
***
## 14. 🧩 Feature 组合与部署
### 14.1 Feature 组合
```toml
[features]
default = ["api", "core"] # 最小核心(零依赖)
http = ["http1", "http2", "http3"] # HTTP 协议栈组合
tls = ["dep:zenith-tls", "core"] # TLS 1.3
cache = ["dep:zenith-cache", "core"] # CDN 缓存
waf = ["dep:zenith-waf", "core"] # WAF
web = ["dep:zenith-web", "core"] # Web 服务器(zenith-web 内部包含 HTTP + TLS + WAF + 缓存)
proxy = ["dep:zenith-proxy", "core"] # 反向代理
forward = ["dep:zenith-forward", "core", "zenith-forward?/linux"] # L4 转发
runtime = ["dep:zenith-runtime", "net", "linux", "ebpf", "zenith-web?/full"] # 全链路数据面运行时
full-stack = ["api", "web", "http", "tls", "proxy", "cache", "waf", "forward",
"runtime", "capability", "observability"]
full = ["full-stack", "testkit"] # 全量(含测试工具)
```
### 14.2 常用组合
| 最小 HTTP API | `web, runtime` | HTTP/1.1+2+3 + WAF + TLS |
| CDN 边缘节点 | `web, proxy, cache, runtime` | + 反向代理 + 缓存 |
| API 网关 | `web, proxy, forward, runtime` | + L4 转发 |
| 防火墙数据面 | `net, forward, linux` | L3/L4 包过滤 + 转发 |
| 完整平台 | `full-stack` | 全特性 |
### 14.3 Release 优化
```toml
[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1
panic = "abort"
strip = "symbols"
incremental = false
```
### 14.4 部署模式
```rust
// 模式 1: Plain HTTP
server.serve_std_tcp_conn(stream, peer, None)?;
// 模式 2: TLS (HTTPS)
server.serve_std_tcp_conn(stream, peer, Some(&mut tls_acceptor))?;
// 模式 3: HTTP/3 over QUIC
server.bind_quic(quic_config, &cert_gen)?;
server.serve_udp_loop(65536)?;
```
***
## 15. 🕸️ 全链路指纹识别与阻断系统
`zenith-fingerprint` crate 提供覆盖 L3-L7 全协议栈的客户端指纹采集、决策与阻断能力。
### 15.1 FingerprintVector 特征向量
```rust
use zenith::fingerprint::FingerprintVector;
// 构造默认向量(256 字节,0xFF 表示"未知")
let mut fp = FingerprintVector::default();
assert_eq!(FingerprintVector::size(), 256);
assert_eq!(fp.ip_id_pattern, 0xFF); // 未知
// 从采集器输出合并字段
use zenith::fingerprint::FingerprintField;
fp.merge(FingerprintField::IpInitialTtl(64)); // Linux
fp.merge(FingerprintField::TcpSynWindow(64240));
assert_eq!(fp.ip_initial_ttl, 64);
assert_eq!(fp.tcp_syn_window, 64240);
```
### 15.2 L3/L4 指纹采集
```rust
use zenith::fingerprint::{
L3Context, IpInitialTtlCollector,
TcpContext, TcpSynWindowCollector, TcpOptionsOrderCollector, FpTcpOptionsInfo,
FingerprintField,
};
// L3: IP ID 模式 + 初始 TTL
let mut l3ctx = L3Context::new(6); // protocol = TCP
l3ctx.ip_id = Some(0x1234);
l3ctx.ip_ttl = Some(64);
l3ctx.ip_df = Some(true);
l3ctx.ip_mf = Some(false);
l3ctx.ip_frag_offset = Some(0);
l3ctx.ip_tos = Some(0);
let ttl_collector = IpInitialTtlCollector;
let field = ttl_collector.collect_l3l4(&l3ctx);
// → Some(FingerprintField::IpInitialTtl(64)) (Linux)
// L4: TCP SYN 窗口 + 选项序列
let mut tcp_ctx = TcpContext::new();
tcp_ctx.syn_window = Some(64240);
tcp_ctx.options_info = Some(FpTcpOptionsInfo {
option_types: vec![2, 3, 4, 8], // MSS, WScale, SACK, TS
mss: Some(1460),
window_scale: Some(7),
sack_permitted: true,
tsval: Some(123456),
tsecr: Some(0),
});
let win_collector = TcpSynWindowCollector;
let field = win_collector.collect_l3l4(&tcp_ctx);
// → Some(FingerprintField::TcpSynWindow(64240))
let opts_collector = TcpOptionsOrderCollector;
let field = opts_collector.collect_l3l4(&tcp_ctx);
// → Some(FingerprintField::TcpOptionsSig([u8; 16]))
```
### 15.3 L6 TLS 指纹(JA3/JA4/JA4S/JA4O/JA4H/JA4L)
```rust
use zenith::tls::fingerprint::{Ja3Fingerprint, ClientHelloFeatures};
use zenith::fingerprint::{
TlsFingerprintContext, Ja3Collector, Ja4Collector,
Ja4sCollector, Ja4oCollector, Ja4hCollector, Ja4lCollector,
ServerHelloContext, FingerprintField,
};
// JA3/JA4 从 ClientHello 解析(TLS 握手时自动采集)
let features = ClientHelloFeatures::from_client_hello(&client_hello_bytes);
// features.extension_order: Vec<u16> — 原始扩展顺序(不排序)
let ja3 = Ja3Fingerprint::from_client_hello(&client_hello_bytes);
// ja3.ja3_hash: String — MD5 hex 字符串
// ja3.ja4_hash: String — 三段式 a_b_c
// 构造 TLS 指纹上下文(调用方预计算后传递给采集器)
let tls_ctx = TlsFingerprintContext {
ja3_hash: [0xe6, 0x4d, 0x2b, 0x3c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
ja4_a: [0u8; 12],
ja4_b: [0u8; 12],
ja4_c: [0u8; 12],
extension_types: vec![0x0000, 0x0010, 0x000A, 0x002B].into(),
};
// JA4O: 扩展顺序指纹(不排序)
let ja4o_field = Ja4oCollector.collect(&tls_ctx);
// → FingerprintField::TlsExtOrder([u8; 16]) 原始顺序低字节映射
// JA4S: ServerHello 指纹
// 注意:zenith-tls::compute_ja4s 使用 SHA-256,zenith-fingerprint::Ja4sCollector 使用 FNV-1a
// zenith-tls 版本为规范实现,指纹采集器版本为轻量内部哈希
let server_ctx = ServerHelloContext {
cipher_suite: 0x1301,
extensions: vec![0x0010, 0x000A].into(),
};
let ja4s_field = Ja4sCollector.collect(&server_ctx);
// → FingerprintField::Ja4sHash([u8; 12]) FNV-1a 128-bit 截断
// JA4H: HTTP 头序指纹(接受预计算的 16 字节哈希)
let ja4h_field = Ja4hCollector.collect([0u8; 16]);
// → FingerprintField::HttpHeaderOrder([u8; 16])
// JA4L: 链路延迟指纹(RTT + 请求间隔)
let ja4l_field = Ja4lCollector.collect(30_000, 5_000); // srtt_us=30ms, jitter_us=5ms
// → FingerprintField::TimingRttMs(30) + 抖动特征
```
### 15.4 L7 HTTP 指纹
```rust
use zenith::fingerprint::{HttpUaCollector, HttpContext};
let ctx = HttpContext {
header_names: vec!["host", "user-agent", "accept"].into(),
user_agent: Some(b"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0"),
cookie: Some(b"session=abc; theme=dark"),
sec_ch_width: Some(1920),
sec_ch_viewport_width: Some(1920),
sec_ch_viewport_height: Some(1080),
};
let ua_collector = HttpUaCollector;
let field = ua_collector.collect(&ctx);
// → FingerprintField::UaInfo { hash: [u8; 8], os: 1 (Windows), browser: 0 (Chrome), engine: 0 (Blink) }
```
### 15.5 决策引擎
```rust
use zenith::fingerprint::{
DecisionEngine, FingerprintRule, FingerprintMatcher, DecisionAction, DecisionReason,
FingerprintVector,
};
let mut engine = DecisionEngine::new();
// 添加规则:已知恶意 JA3 前缀 → 阻断
engine.add_rule(FingerprintRule {
id: 1,
name: "block-known-bot".to_string(),
matcher: FingerprintMatcher::Ja3Prefix {
prefix: [0xe6, 0x4d, 0x2b, 0x3c],
len: 4,
},
action: DecisionAction::Block {
reason: DecisionReason::FingerprintBlocklist,
},
priority: 100,
enabled: true,
});
// 评估指纹向量
let fp = FingerprintVector::default();
let action = engine.evaluate(&fp, 0);
// 评分模型:黑名单匹配 → 阻断阈值,白名单匹配 → 0 分(放行),未知指纹 → 基线评分
// 可通过 engine.scoring_mut() 运行时调整白名单/黑名单
// → DecisionAction::Allow (默认向量不匹配规则)
```
### 15.6 非预期数据包丢弃
```rust
use zenith::net::ProtocolExpectation;
let mut expectation = ProtocolExpectation::default();
// 只允许 TCP 80/443 和 UDP 443
expectation.tcp_allowed_ports.push(80);
expectation.tcp_allowed_ports.push(443);
expectation.udp_allowed_ports.push(443);
// 检查数据包是否预期
assert!(expectation.is_packet_expected(6, 80, 64, false)); // TCP:80 ✓
assert!(!expectation.is_packet_expected(6, 22, 64, false)); // TCP:22 ✗
assert!(expectation.is_packet_expected(17, 443, 64, false)); // UDP:443 ✓
assert!(!expectation.is_packet_expected(17, 9999, 64, false)); // UDP:9999 ✗
// 设置到 Worker
// worker.set_protocol_expectation(Some(expectation));
// 非预期包在 Worker 层静默丢弃,不提交 TX Ring
```
### 15.7 Feature 配置
```toml
[dependencies]
zenith = { path = "...", features = ["fingerprint"] }
# fingerprint = zenith-fingerprint(独立运行,无外部 zenith crate 依赖)
# 提供全链路指纹采集 + 决策引擎 + 非预期包丢弃
```
### 15.8 性能指标
| wrk Plain 性能(keep-alive) | **60,359 req/s**(`wrk -t4 -c200 -d8s`,p50 5.14ms,0 socket errors,WSL Ubuntu 26.04,`0.0.0.0`) |
| wrk Plain 低并发 | **90,706 req/s**(`wrk -t2 -c20 -d5s`,p50 249µs) |
| wrk Plain POST | **32,881 req/s**(`wrk -t4 -c200 -d8s -s bench/post.lua`) |
| wrk Plain 非保活 | **26,327 req/s**(`wrk -t4 -c200 -d8s -s bench/close.lua`) |
| TLS 性能 | wrk 4.1.0 不支持 TLS;TLS 1.3 + ALPN h2 经 curl.exe 实测 200 |
| h2spec | 146/146 通过 |
| h3spec | 49/49 通过(IPv4 + IPv6) |
| hping3 TCP | RTT 3.3-7.6ms, 0% packet loss |
| WAF 拦截 | SQLi/XSS/SSRF/路径穿越/命令注入/NULL 字节注入 全部 403(Plain/TLS/H3 三模式) |
| IPv6 | \[::1] HTTP 200(Plain + TLS + H3 模式;WSL curl 与 Windows curl.exe 双端验证) |
| 指纹阻断 | TCP/TLS 与 HTTP/3(QUIC) 黑名单 403 均真实生效(`fingerprint_h3_block_test`) |
| 指纹开销 | < 20μs/请求 |
| cargo test | 3235+ 项通过(53 套件)/ 0 失败;本轮加固新增多组边界单测(http2 175、web 208+11+3、net 364、http3 269+17、core 234)——`cargo test --workspace --all-features` |
***
## 16. 🧰 独立 Crate 使用模式
Zenith 的每个子 crate 可独立引用,无需拉入整个 facade。以下是各 crate 的独立使用场景与示例。
### 16.1 仅使用 zenith-api(类型定义,零依赖)
适用于:只需 HTTP 请求/响应类型定义,不需要协议解析或服务器。
```toml
[dependencies]
zenith-api = { path = "..." }
```
```rust
use zenith_api::{CanonicalRequest, CanonicalResponse, Method};
// 构造请求对象(用于测试或自定义协议适配层)
let mut req = CanonicalRequest::empty();
req.method = Method::Get;
req.set_path("/api/users");
let _ = req.add_header(b"host", b"example.com");
// 构造响应
let mut resp = CanonicalResponse::new(200);
let _ = resp.add_header(b"content-type", b"application/json");
resp.set_body(br#"{"ok":true}"#.to_vec());
```
**搭配场景**:自定义 RPC 框架的类型层、Mock 服务器、协议适配器。
### 16.2 仅使用 zenith-waf(Web 应用防火墙)
适用于:将 WAF 检测能力嵌入到任意 HTTP 框架(如 axum、actix-web、hyper)。
```toml
[dependencies]
zenith-waf = { path = "..." }
```
```rust
use zenith_waf::{WafEngine, RuleBuilder, DetectionSeverity, PatternField, FxHashMap};
// 创建独立 WAF 引擎
let mut waf = WafEngine::new();
// 自定义规则
waf.add_rule(
RuleBuilder::new("block-sql-injection")
.severity(DetectionSeverity::High)
.pattern(PatternField::Query, "UNION SELECT")
.build()
);
// 在任意框架的中间件中调用
fn check_request(method: &str, path: &str, query: &str, body: &[u8]) -> bool {
let mut headers = FxHashMap::default();
headers.insert("user-agent", "Mozilla/5.0");
let result = waf.check_request(method, path, &headers, body, query);
!result.has_threat // true = 放行, false = 拦截
}
// 搭配 axum 使用(伪代码)
// async fn waf_middleware(req: axum::extract::Request, next: axum::middleware::Next) -> Response {
// if !check_request(req.method().as_str(), req.uri().path(), req.uri().query().unwrap_or(""), &[]) {
// return Response::builder().status(403).body(Body::empty()).unwrap();
// }
// next.run(req).await
// }
```
**搭配场景**:axum/actix-web/hyper 的中间件、API 网关安全层、微服务侧车代理。
### 16.3 仅使用 zenith-tls(TLS 1.3 引擎 + 指纹)
适用于:自定义 TLS 终止网关、指纹采集服务。
```toml
[dependencies]
zenith-tls = { path = "..." }
```
```rust
use zenith_tls::fingerprint::{Ja3Fingerprint, compute_ja4s, compute_ja4o, compute_ja4h_header_order};
use zenith_tls::cert_manager::{CertGeneration, CertManager};
// 从 ClientHello 提取 JA3/JA4 指纹
let fp = Ja3Fingerprint::from_client_hello(&client_hello_bytes);
println!("JA3: {}", fp.ja3_hash);
println!("JA4: {}", fp.ja4_hash);
// ServerHello 指纹
let ja4s = compute_ja4s(0x1301, &[0x0010, 0x000A]);
// 扩展顺序指纹
let ja4o = compute_ja4o(&[0x0000, 0x0010, 0x000A, 0x002B]);
// HTTP 头序指纹
let ja4h = compute_ja4h_header_order(&["host", "user-agent", "accept"]);
// 证书代际管理
let cert_gen = CertGeneration::from_pem(cert_pem, key_pem)?;
let mut cert_manager = CertManager::new();
cert_manager.set_default(cert_gen);
```
**搭配场景**:自定义 TLS 代理、指纹分析平台、CDN 边缘 TLS 终止、安全审计工具。
### 16.4 仅使用 zenith-net(L2-L4 协议解析 + 包过滤)
适用于:网络监控工具、自定义数据面、包分析器。
```toml
[dependencies]
zenith-net = { path = "..." }
```
```rust
use zenith_net::packet::parse_packet;
use zenith_net::source_admission::{SourceAdmissionEngine, AdmissionRule, AdmissionAction, IpAddr, ProtoMatch};
use zenith_net::protocol_expectation::ProtocolExpectation;
// 解析网络数据包(零拷贝)
let parsed = parse_packet(&raw_bytes)?;
if let Some(ipv4) = parsed.ipv4 {
println!("src: {:?} dst: {:?} proto: {} ttl: {}",
ipv4.src_ip(), ipv4.dst_ip(), ipv4.protocol(), ipv4.ttl());
}
if let Some(tcp) = parsed.tcp {
println!("src_port: {} dst_port: {} flags: {:?}",
tcp.src_port(), tcp.dst_port(), tcp.flags());
}
// IP 准入过滤
let mut engine = SourceAdmissionEngine::deny_all();
engine.add_rule(AdmissionRule {
id: 1, src_ip: IpAddr::V4([127, 0, 0, 1]), prefix_len: 0, src_port: 0, dst_port: 0,
proto: ProtoMatch::Any, action: AdmissionAction::Allow, enabled: true,
})?;
// 非预期包丢弃
let mut expectation = ProtocolExpectation::default();
expectation.tcp_allowed_ports.push(80);
expectation.tcp_allowed_ports.push(443);
assert!(expectation.is_packet_expected(6, 80, 64, false)); // TCP:80
assert!(!expectation.is_packet_expected(6, 22, 64, false)); // TCP:22 丢弃
```
**搭配场景**:网络抓包分析工具、入侵检测系统(IDS)、自定义防火墙、流量审计。
### 16.5 仅使用 zenith-cache(CDN 缓存层)
适用于:为任意 HTTP 服务器添加缓存能力。
```toml
[dependencies]
zenith-cache = { path = "..." }
```
```rust
use zenith_cache::{CacheEngine, CacheEntry, CacheKey, CacheKeyBuilder, CachePolicy, CacheHit, EvictionPolicy};
// 创建缓存引擎
let cache = CacheEngine::new(65536, 64 * 1024 * 1024)
.with_policy(EvictionPolicy::Lru)
.with_shared_cache(true);
// 缓存键
let key = CacheKeyBuilder::new("GET", "/api/users").build();
// 写入缓存
let entry = CacheEntry::new(
key.clone(), b"response body".to_vec(), 200,
"application/json".to_string(),
CachePolicy::public(3600),
1, // tenant_id
0, // now_ms
);
cache.put(entry);
// 查询缓存
match cache.get(&key, 1, 0) {
CacheHit::Fresh(entry) => println!("命中: {}", String::from_utf8_lossy(entry.value.as_ref())),
CacheHit::Stale(entry) => println!("过期但可用: {}", String::from_utf8_lossy(entry.value.as_ref())),
CacheHit::Miss => println!("未命中"),
}
```
**搭配场景**:为 axum/actix-web 添加缓存中间件、CDN 边缘缓存、API 响应缓存。
### 16.6 仅使用 zenith-forward(L4 转发)
适用于:端口转发工具、协议转换网关。
```toml
[dependencies]
zenith-forward = { path = "..." }
```
```rust
use zenith_forward::{TcpRelay, AddressWhitelist};
use std::net::{TcpListener, IpAddr};
// 端口转发(Linux 自动 splice(2),其他平台用户态带背压拷贝回退)
let listener = TcpListener::bind("0.0.0.0:8080")?;
let (client, peer) = listener.accept()?;
let upstream = std::net::TcpStream::connect("127.0.0.1:9090")?;
let relay = TcpRelay::default();
let (c2u, u2c) = relay.relay(&client, &upstream)?;
// CIDR 白名单(防 SSRF)
let whitelist = AddressWhitelist::new()
.with_allowed_cidr_ip(IpAddr::from([127u8, 0, 0, 0]), 8)
.with_allowed_cidr_ip(IpAddr::from([192u8, 168, 0, 0]), 16);
assert!(whitelist.is_ip_allowed(&IpAddr::from([127u8, 0, 0, 1])));
assert!(!whitelist.is_ip_allowed(&IpAddr::from([10u8, 0, 0, 1])));
```
**搭配场景**:零拷贝端口转发工具、内网穿透、负载均衡 L4 层。
### 16.7 仅使用 zenith-observability(指标 + 审计 + 故障快照)
适用于:为任意服务添加可观测性。
```toml
[dependencies]
zenith-observability = { path = "..." }
```
```rust
use zenith_observability::{MetricsCollector, AuditLogger, AuditEvent, FaultRecorder, FaultType, Severity};
// ══ Prometheus 指标(固定容量、预分配、运行时零堆分配)══════════
// 默认容量 64 个指标槽位;`MetricsCollector::<2048>::new()` 可指定更大容量。
// 三种指标类型与对应记录方法(均返回 Result<(), &'static str>,槽位满时 Err):
let mut metrics = MetricsCollector::new();
// 计数器(单调递增):counter_inc = +1;counter_add(name, delta, labels)
metrics.counter_inc("requests_total", &[("method", "GET"), ("status", "200")]).unwrap();
metrics.counter_add("bytes_rx_total", 1_500, &[]).unwrap();
// 仪表(当前值,可为负):gauge_set / gauge_inc / gauge_dec / gauge_add / gauge_sub
metrics.gauge_set("active_connections", 42, &[("worker", "0")]).unwrap();
metrics.gauge_inc("active_connections", 1, &[("worker", "0")]).unwrap();
// 直方图(Prometheus 累积桶):histogram_record / histogram_observe(value 自带单位,如 us)
metrics.histogram_record("request_duration_us", 1_500, &[("path", "/api")]).unwrap();
// 导出 Prometheus 0.0.4 文本(标签自动转义;histogram 带 le="..." 桶行)
let prom_text = metrics.export_prometheus();
println!("{}", prom_text);
// ══ 审计日志(环形缓冲,默认自动脱敏 IP/头部)══════════════════
let mut audit = AuditLogger::new(); // 无参构造;容量经 audit.capacity() 查询
// 可选挂载文件落盘槽(JSON Lines 追加写):audit.with_file_sink("/var/log/zenith/audit.jsonl")
let event = AuditEvent::new(
zenith_core::current_time_ms(), // timestamp(ms)
Severity::High, // severity
"waf", // category
"10.0.0.1", // actor(IP 自动脱敏)
"block", // action
"GET /api/users", // target
"SQL injection detected", // result
);
audit.log(event); // true=未覆盖旧事件;false=环形缓冲已满覆盖最旧事件
for entry in audit.events() { // 注:非 snapshot(),方法名为 events()
println!("{}", AuditLogger::format_event(&entry)); // JSON Lines 格式化
}
// ══ 故障快照 ═══════════════════════════════════════════════════
let mut recorder = FaultRecorder::new(); // 无参构造;容量经 capacity() 查询
// record(fault_type, affected_component) -> u64(快照 ID)
let _id = recorder.record(FaultType::WorkerPanic, "worker_0");
for snap in recorder.list_recent(5) {
println!("fault #{} {}: {}", snap.snapshot_id, snap.affected_component_str(),
snap.fault_type.as_str());
}
```
**搭配场景**:任意 Rust 服务的可观测性层、Prometheus 导出器、合规审计日志。
### 16.8 仅使用 zenith-fingerprint(全链路指纹识别)
适用于:指纹分析平台、威胁情报系统、自动化安全审计。
```toml
[dependencies]
zenith-fingerprint = { path = "..." }
```
```rust
use zenith_fingerprint::{
FingerprintVector, FingerprintField, DecisionEngine, FingerprintRule, FingerprintMatcher,
DecisionAction, DecisionReason,
};
// 构造指纹向量
let mut fp = FingerprintVector::default();
fp.merge(FingerprintField::IpInitialTtl(64)); // Linux 客户端
fp.merge(FingerprintField::TcpSynWindow(64240)); // Linux 默认窗口
fp.merge(FingerprintField::Ja3Hash([0xe6; 16])); // 已知 JA3
// 决策引擎
let mut engine = DecisionEngine::new();
engine.add_rule(FingerprintRule {
id: 1,
name: "block-known-bot".to_string(),
matcher: FingerprintMatcher::Ja3Prefix { prefix: [0xe6, 0x4d, 0x2b, 0x3c], len: 4 },
action: DecisionAction::Block { reason: DecisionReason::FingerprintBlocklist },
priority: 100,
enabled: true,
});
let action = engine.evaluate(&fp, 0);
// → DecisionAction::Block { reason: FingerprintBlocklist }
```
**搭配场景**:SOAR 平台指纹引擎、API 网关安全层、DDoS 防护系统、爬虫检测。
***
## 17. 🏗️ 链路组合模式
将多个 feature 组合使用,构建完整的安全数据面链路。
> **严格按需**:下图中的 WAF / 指纹黑名单 / 限流等安全阶段,均需在 `ServerConfig`
> 显式开启(`with_waf(true)` / `with_fingerprint_security(true)`)才实际执行;
> 默认 `ProtocolServer::new()` 不启用任何安全中间件。
### 17.1 模式一:最小 Web API 服务
```toml
[dependencies]
zenith = { path = "...", default-features = false, features = ["web", "runtime"] }
```
```
客户端 → HTTP/1.1 或 HTTP/2 → zenith-web 路由 → WAF 检测 → 应用 handler
```
**适用场景**:内部 API 服务、微服务后端、管理面板。
### 17.2 模式二:HTTPS + WAF + 指纹阻断
```toml
[dependencies]
zenith = { path = "...", features = ["web", "runtime", "fingerprint"] }
```
```
客户端 → TLS 1.3 握手 → JA3/JA4 指纹采集 → 指纹决策引擎 → HTTP 解析 → WAF 检测 → 应用 handler
↓ ↓
证书代际管理 403 阻断(恶意指纹)
429 限流(速率超限)
```
**适用场景**:面向公网的 API 网关、高安全要求的 Web 服务。
```rust
// 指纹规则配置示例
use zenith::fingerprint::{DecisionEngine, FingerprintRule, FingerprintMatcher, DecisionAction, DecisionReason};
// 在 SecurityPipeline 中注册指纹规则(通过 ChangeSet 热更新)
let mut engine = DecisionEngine::new();
engine.add_rule(FingerprintRule {
id: 1,
name: "block-curl-bot".to_string(),
matcher: FingerprintMatcher::UaMatch { os: None, browser: Some(4) }, // browser=4 = curl
action: DecisionAction::Block { reason: DecisionReason::FingerprintBlocklist },
priority: 100,
enabled: true,
});
```
### 17.3 模式三:CDN 边缘节点
```toml
[dependencies]
zenith = { path = "...", features = ["web", "proxy", "cache", "runtime"] }
```
```
客户端 → TLS 1.3 → HTTP/2 → zenith-web 路由
├── 缓存命中 → 304/200 直接返回
├── 缓存未命中 → 反向代理 → 后端服务器
└── WAF 检测 → 403 拦截
```
**适用场景**:内容分发网络边缘节点、静态资源加速、API 缓存层。
### 17.4 模式四:L4 透明转发防火墙
```toml
[dependencies]
zenith = { path = "...", features = ["net", "forward", "linux", "runtime"] }
```
```
网卡 → XDP/eBPF 内核态粗过滤 → AF_XDP 零拷贝 → Worker 数据面
↓ ├── SourceAdmissionEngine IP/端口过滤
非预期协议 XDP_DROP ├── ProtocolExpectation 非预期包丢弃
└── TcpRelay L4 转发 → 后端
```
**适用场景**:系统级网络防火墙、透明代理网关、L4 负载均衡器。
> **OS 标注**:此模式依赖 `linux` feature(AF\_XDP + eBPF + io\_uring)。Windows/macOS 自动降级为 `std::net` + `std::io::copy`,L4 转发功能完整但无零拷贝。
### 17.5 模式五:完整全栈安全网关
```toml
[dependencies]
zenith = { path = "...", features = ["full-stack", "fingerprint"] }
```
```
客户端 → XDP 内核态过滤 → AF_XDP → Worker
↓ ├── IP 准入过滤
非预期协议丢弃 ├── ProtocolExpectation 端口/分片/TTL 检查
├── TCP 状态机 + RTT 测量
├── QUIC DCID 路由
↓
zenith-web SecurityPipeline
├── TLS 1.3 + JA3/JA4/JA4S/JA4O/JA4H/JA4L 指纹
├── 指纹决策引擎(14 匹配器 + 评分(白名单/黑名单)+ 固定窗口计数器 + 信誉库)
├── 身份一致性检查(SNI ↔ Host)
├── WAF 6 检测器
├── 缓存查询
├── 反向代理 → 后端
└── 审计日志 + Prometheus 指标
```
**适用场景**:企业级安全网关、零信任网络入口、云原生 API 网关。
> **OS 标注**:XDP/eBPF + AF\_XDP + io\_uring 仅 Linux。其他平台降级为 `std::net`,上层全功能可用。
### 17.6 模式六:指纹分析平台(仅指纹 + 可观测性)
```toml
[dependencies]
zenith-fingerprint = { path = "..." }
zenith-observability = { path = "..." }
zenith-tls = { path = "..." }
zenith-net = { path = "..." }
```
```
网络流量 → zenith-net parse_packet → L3/L4 指纹采集
→ zenith-tls ClientHello → JA3/JA4/JA4S/JA4O 指纹
→ zenith-fingerprint DecisionEngine → 决策
→ zenith-observability AuditLogger → 审计日志
→ zenith-observability MetricsCollector → Prometheus 指标
```
**适用场景**:威胁情报平台、SOAR 自动化响应、DDoS 防护分析、爬虫检测服务。
***
## 18. 🤝 第三方库搭配指南
Zenith 的各 crate 可与 Rust 生态中的其他库搭配使用。
### 18.1 zenith-waf + axum(为 axum Web 框架添加 WAF)
```toml
[dependencies]
zenith-waf = { path = "..." }
axum = "0.7"
```
```rust
use zenith_waf::{WafEngine, RuleBuilder, PatternField, DetectionSeverity, FxHashMap};
use axum::{Router, middleware, extract::Request, response::Response, body::Body};
let mut waf = WafEngine::new();
waf.add_rule(
RuleBuilder::new("block-sqli")
.severity(DetectionSeverity::High)
.pattern(PatternField::Query, "' OR '1'='1")
.build()
);
// axum 中间件中调用 WAF
async fn waf_middleware(req: Request, next: middleware::Next) -> Response {
let method = req.method().as_str();
let path = req.uri().path();
let query = req.uri().query().unwrap_or("");
let mut headers = FxHashMap::default();
for (k, v) in req.headers() {
if let Ok(vv) = v.to_str() {
headers.insert(k.as_str(), vv);
}
}
let result = waf.check_request(method, path, &headers, b"", query);
if result.has_threat {
return Response::builder().status(403).body(Body::empty()).unwrap();
}
next.run(req).await
}
let app = Router::new()
.route("/api", axum::routing::get(|| async { "OK" }))
.layer(middleware::from_fn(waf_middleware));
```
### 18.2 zenith-tls + hyper(为 hyper 自定义 TLS 终止)
```toml
[dependencies]
zenith-tls = { path = "..." }
hyper = { version = "1", features = ["server", "http1", "http2"] }
```
```rust
use zenith_tls::fingerprint::Ja3Fingerprint;
use zenith_tls::cert_manager::CertGeneration;
// 在 hyper 连接 accept 层提取 TLS 指纹
let cert_gen = CertGeneration::from_pem(cert_pem, key_pem)?;
// 在自定义 TLS Accept 后,从 ClientHello 提取指纹
let fp = Ja3Fingerprint::from_client_hello(&client_hello_bytes);
if fp.is_some() {
println!("Client JA3: {}", fp.unwrap().ja3_hash);
// 可用于访问控制、日志审计、指纹阻断
}
```
### 18.3 zenith-cache + actix-web(为 actix-web 添加 CDN 缓存)
```toml
[dependencies]
zenith-cache = { path = "..." }
actix-web = "4"
```
```rust
use zenith_cache::{CacheEngine, CacheEntry, CacheKeyBuilder, CachePolicy, CacheHit};
let cache = std::sync::Arc::new(
CacheEngine::new(65536, 256 * 1024 * 1024)
.with_shared_cache(true)
);
// actix-web handler 中查询缓存
async fn cached_handler(
req: actix_web::HttpRequest,
data: actix_web::web::Data<std::sync::Arc<CacheEngine>>,
) -> impl actix_web::Responder {
let key = CacheKeyBuilder::new("GET", req.path()).build();
let now = zenith_core::current_time_ms();
match data.get(&key, 1, now) {
CacheHit::Fresh(entry) => {
actix_web::HttpResponse::Ok()
.content_type(&entry.content_type)
.body(entry.value.as_ref().to_vec())
}
_ => {
// 未命中:执行业务逻辑,写入缓存
let body = b"computed response".to_vec();
let entry = CacheEntry::new(
key, body.clone(), 200, "text/plain".to_string(),
CachePolicy::public(3600), 1, now,
);
data.put(entry);
actix_web::HttpResponse::Ok().body(body)
}
}
}
```
### 18.4 zenith-net + pnet(网络流量分析)
```toml
[dependencies]
zenith-net = { path = "..." }
pnet = "0.34"
```
```rust
use zenith_net::packet::parse_packet;
use pnet::datalink::{self, Channel::Ethernet};
// 使用 pnet 抓包
let iface = datalink::interfaces().into_iter().next().unwrap();
let mut rx = match datalink::channel(&iface, Default::default()) {
Ok(Ethernet(tx, rx)) => rx,
_ => panic!("channel error"),
};
// 使用 zenith-net 解析
for packet in rx.iter() {
if let Ok(parsed) = parse_packet(&packet) {
if let Some(ipv4) = parsed.ipv4 {
println!("{}:{} → {}:{} proto={}",
ipv4.src_ip().map(|ip| ip.iter().map(|b| b.to_string()).collect::<Vec<_>>().join(".")).unwrap_or_default(),
parsed.tcp.map(|t| t.src_port()).unwrap_or(0),
ipv4.dst_ip().map(|ip| ip.iter().map(|b| b.to_string()).collect::<Vec<_>>().join(".")).unwrap_or_default(),
parsed.tcp.map(|t| t.dst_port()).unwrap_or(0),
ipv4.protocol(),
);
}
}
}
```
### 18.5 zenith-fingerprint + serde(指纹规则序列化/反序列化)
```toml
[dependencies]
zenith-fingerprint = { path = "..." }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
```
```rust
use zenith_fingerprint::{FingerprintRule, FingerprintMatcher, DecisionAction, DecisionReason};
use serde::{Serialize, Deserialize};
// 规则配置文件(JSON)
#[derive(Serialize, Deserialize)]
struct RuleConfig {
id: u32,
name: String,
matcher_type: String, // "ja3_prefix", "ua_match", "rtt_range" 等
matcher_data: serde_json::Value,
action: String, // "block", "monitor", "challenge", "rate_limit"
priority: u16,
}
// 从 JSON 加载规则
fn load_rules(json: &str) -> Vec<FingerprintRule> {
let configs: Vec<RuleConfig> = serde_json::from_str(json).unwrap();
configs.into_iter().map(|c| {
let matcher = match c.matcher_type.as_str() {
"ja3_prefix" => {
let prefix: [u8; 4] = serde_json::from_value(c.matcher_data).unwrap();
FingerprintMatcher::Ja3Prefix { prefix, len: 4 }
}
"ua_match" => {
let obj = c.matcher_data.as_object().unwrap();
FingerprintMatcher::UaMatch {
os: obj.get("os").and_then(|v| v.as_u64()).map(|v| v as u8),
browser: obj.get("browser").and_then(|v| v.as_u64()).map(|v| v as u8),
}
}
"any" => FingerprintMatcher::AnyMatch,
_ => FingerprintMatcher::AnyMatch,
};
FingerprintRule {
id: c.id, name: c.name, matcher,
action: match c.action.as_str() {
"block" => DecisionAction::Block { reason: DecisionReason::FingerprintBlocklist },
"monitor" => DecisionAction::Monitor,
_ => DecisionAction::Allow,
},
priority: c.priority, enabled: true,
}
}).collect()
}
```
### 18.6 zenith-observability + Prometheus + Grafana
```toml
[dependencies]
zenith-observability = { path = "..." }
```
```rust
use zenith_observability::MetricsCollector;
use std::sync::Arc;
let metrics = Arc::new(MetricsCollector::new());
// 在业务代码中记录指标(真实 API 为 counter_*/gauge_*/histogram_*)
let m = metrics.clone();
// 请求总数(按 method+status 打标签)
m.counter_inc("requests_total", &[("method", "GET"), ("status", "200")]).unwrap();
m.counter_inc("requests_total", &[("method", "GET"), ("status", "500")]).unwrap();
// 缓存命中/未命中的经典用法:各自独立计数器
m.counter_inc("cache_hits_total", &[]).unwrap();
m.counter_inc("cache_misses_total", &[]).unwrap();
// WAF 拦截计数
m.counter_inc("waf_blocked_total", &[]).unwrap();
// 请求延迟直方图(单位 us,Prometheus 累积桶自动分箱)
m.histogram_record("request_duration_us", 1_500, &[("path", "/api/users")]).unwrap();
m.histogram_record("request_duration_us", 3_000, &[("path", "/api/users")]).unwrap();
// 导出 Prometheus 格式(用于 /metrics 端点)
let prom_text = metrics.export_prometheus();
// → Prometheus 0.0.4 文本格式,可直接被 Prometheus 抓取
// # TYPE requests_total counter
// requests_total{method="GET",status="200"} 1
// requests_total{method="GET",status="500"} 1
// cache_hits_total 1
// cache_misses_total 1
// waf_blocked_total 1
// # TYPE request_duration_us histogram
// request_duration_us_bucket{le="2500",path="/api/users"} 1
// request_duration_us_bucket{le="+Inf",path="/api/users"} 2
```
Grafana Dashboard 可直接抓取 `/metrics` 端点的输出。
***
## 19. 🗺️ 应用场景与搭配速查
### 19.1 按场景选择 Feature 组合
| 最小 HTTP API | `web, runtime` | — | HTTP/1.1+2+3 + WAF + TLS |
| HTTPS API 网关 | `web, runtime, fingerprint` | — | + 全链路指纹识别 + 阻断 |
| CDN 边缘节点 | `web, proxy, cache, runtime` | — | + 反向代理 + 缓存 |
| 系统级防火墙 | `net, forward, linux` | — | L3/L4 包过滤 + 零拷贝转发 |
| L4 透明代理 | `forward, linux` | — | splice(2) 零拷贝端口转发 |
| TLS 终止网关 | `tls, web` | `zenith-tls` + hyper | TLS 1.3 + JA3/JA4 指纹 |
| WAF 安全层 | `waf` | `zenith-waf` + axum | 为任意框架添加 WAF |
| 指纹分析平台 | `fingerprint, observability` | `zenith-fingerprint` + `zenith-tls` + `zenith-net` | 独立指纹采集 + 决策 + 审计 |
| 缓存加速 | `cache` | `zenith-cache` + actix-web | 为任意框架添加 CDN 缓存 |
| 网络流量分析 | `net` | `zenith-net` + pnet | 零拷贝包解析 + IP 准入 |
| 可观测性平台 | `observability` | `zenith-observability` + Prometheus | 指标 + 审计 + 故障快照 |
| 企业级全栈网关 | `full-stack, fingerprint` | — | 全能力,含 XDP/eBPF |
| DDoS 防护 | `net, forward, linux, fingerprint` | `zenith-net` + `zenith-fingerprint` | XDP 线速过滤 + 指纹阻断 |
| 零信任网络入口 | `full-stack, fingerprint` | — | 全链路指纹 + WAF + 代理 + 证书热切换 |
| 爬虫检测 | `fingerprint` | `zenith-fingerprint` + `zenith-tls` | JA3/JA4 + UA + HTTP 头序指纹 |
### 19.2 按能力选择独立 Crate
| HTTP 请求/响应类型 | zenith-api | 无 | 任意框架的类型适配 |
| TLS 1.3 + 指纹 | zenith-tls | rustls, ring, sha2 | hyper, axum, 自定义代理 |
| WAF 内容检测 | zenith-waf | 无 | axum, actix-web, hyper 中间件 |
| L2-L4 包解析/过滤 | zenith-net | 无(linux 可选) | pnet, 自定义数据面 |
| L4 转发/零拷贝 | zenith-forward | 无(linux 可选 splice) | 端口转发工具 |
| CDN 缓存 | zenith-cache | 无 | axum, actix-web 中间件 |
| 反向代理/负载均衡 | zenith-proxy | rustls, quinn-proto | 网关, API 代理 |
| 指纹识别/阻断 | zenith-fingerprint | zenith-tls, zenith-net | SOAR, 威胁情报 |
| 指标/审计/故障 | zenith-observability | 无 | Prometheus, Grafana |
| 运行时/Supervisor | zenith-runtime | zenith-net, zenith-linux | 全链路数据面 |
| eBPF/XDP 加载 | zenith-ebpf | libbpf-rs | 内核态包过滤 |
| AF\_XDP/io\_uring | zenith-linux | libc | 零拷贝数据面 |
| 能力探测/降级 | zenith-capability | 无 | 跨平台部署 |
| 全栈指纹 | zenith-fingerprint | zenith-tls + zenith-net + zenith-http2 + zenith-http3 | 独立安全引擎 |
### 19.3 OS 降级行为速查
| `linux` | AF\_XDP + io\_uring + splice | 不可用 | 自动跳过,使用 std::net |
| `ebpf` | eBPF + XDP 内核过滤 | 不可用 | 自动跳过,使用用户态过滤 |
| `runtime` | 全链路数据面运行时 | 降级运行时 | Worker 使用 std::net,无 AF\_XDP |
| `forward` | splice(2) 零拷贝 | std::io::copy | API 一致,性能降级 |
| `fingerprint` | 完整(XDP + L4 + L7) | 完整(L4 + L7,无 XDP) | 用户态指纹完整可用 |
| `web` | 完整 | 完整 | 无降级 |
| `tls` | 完整 | 完整 | 无降级 |
| `waf` | 完整 | 完整 | 无降级 |
| `cache` | 完整 | 完整 | 无降级 |
| `proxy` | 完整 | 完整 | 无降级 |
| `observability` | 完整 | 完整 | 无降级 |
| `net` | 完整(含 Worker 数据面) | 完整(Worker 使用 std::net) | 数据面降级,协议解析不变 |
| `capability` | 完整(真实探测) | 完整(真实探测) | 自动选择 Minimal profile |
> **关键**:所有降级由 `EnvironmentDetector` → `ProfileSelector` 自动完成,用户代码无需任何平台条件编译(`#[cfg]`)。API 在所有平台完全一致。
***
## 20. 🚢 部署最佳实践
### 20.1 Linux 生产部署(极致性能)
#### 依赖配置
```toml
[dependencies]
zenith = { path = "...", features = ["full-stack", "fingerprint"] }
```
`full-stack` 包含:web + http + tls + proxy + cache + waf + forward + runtime + capability + observability。`fingerprint` 额外拉入 zenith-fingerprint + tls + http2 + http3。
#### 编译
```bash
# Release 优化编译(LTO + 优化等级 3 + 单代码生成单元 + strip 符号)
cargo build --release --features full-stack,fingerprint --example hello_server
# 二进制位置
ls -lh target/release/examples/hello_server
# → ~12MB(strip 后)
```
#### 启动命令
```bash
# Plain HTTP 模式(端口 18080)
RUST_LOG=info ./target/release/examples/hello_server --mode plain --host 0.0.0.0 --port 80
# TLS 模式(端口 443,自签证书自动生成)
RUST_LOG=info ./target/release/examples/hello_server --mode tls --host 0.0.0.0 --port 443
# HTTP/3 模式(UDP 18443,QUIC + TLS)
RUST_LOG=info ./target/release/examples/hello_server --mode h3 --host 0.0.0.0 --port 443
# 审计日志落盘(JSON Lines 追加写)
RUST_LOG=info ./target/release/examples/hello_server --mode tls --port 443 --audit-log /var/log/zenith/audit.jsonl
```
#### systemd 服务配置
```ini
# /etc/systemd/system/zenith.service
[Unit]
Description=Zenith Web Server
After=network.target
[Service]
Type=simple
User=zenith
Group=zenith
ExecStart=/usr/local/bin/zenith --mode tls --host 0.0.0.0 --port 443 --audit-log /var/log/zenith/audit.jsonl
Environment=RUST_LOG=info
Environment=RUST_BACKTRACE=1
Restart=always
RestartSec=3
LimitNOFILE=65536
# Linux 性能调优
LimitMEMLOCK=infinity # AF_XDP 需要 unlimited memlock
CPUAffinity=0-3 # 绑定 CPU 0-3 核
Nice=-5 # 提高调度优先级
# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/log/zenith
[Install]
WantedBy=multi-user.target
```
```bash
# 启用并启动
sudo systemctl daemon-reload
sudo systemctl enable zenith
sudo systemctl start zenith
sudo systemctl status zenith
```
#### Linux 内核调优
```bash
# /etc/sysctl.d/99-zenith.conf
# 网络缓冲区
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.rmem_default = 262144
net.core.wmem_default = 262144
# 连接追踪
net.netfilter.nf_conntrack_max = 1048576
net.ipv4.tcp_max_syn_backlog = 65535
# TCP 优化
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_syncookies = 1
# 文件描述符
fs.file-max = 1048576
# 应用配置
sudo sysctl --system
```
#### Linux 自动启用的能力
启用 `linux` + `ebpf` + `runtime` feature 后,以下能力自动激活(由 `EnvironmentDetector` 探测):
- AF\_XDP 零拷贝数据面(网卡驱动层旁路)
- eBPF/XDP 内核态过滤(协议白名单 + MTU + 短帧丢弃)
- io\_uring 批量 IO(32 recv + 64 send slot,每批 ≤2 syscall)
- splice(2) 零拷贝转发(TcpSpliceRelay 内核态双向中继)
- CPU 亲和性绑定(sched\_setaffinity)
- 全链路指纹(含 XDP 层 ExpectationMap)
- 三级 Supervisor 自动治理 + ChangeSet 热切换
### 20.2 Windows 开发/测试部署
#### 依赖配置
```toml
[dependencies]
zenith = { path = "...", features = ["web", "proxy", "cache", "fingerprint"] }
# 不启用 linux / ebpf / runtime — Windows 上这些 feature 无效但不会报错
```
#### 编译与启动
```powershell
# 编译
cargo build --release --features "web,proxy,cache,fingerprint" --example hello_server
# 启动(PowerShell)
$env:RUST_LOG="info"
.\target\release\examples\hello_server.exe --mode plain --port 18080
# TLS 模式
.\target\release\examples\hello_server.exe --mode tls --port 18443
```
#### Windows 自动降级行为
| AF\_XDP/eBPF | splice(2) + io\_uring + AF\_XDP | 自动跳过 | `EnvironmentDetector` 探测后选择 Minimal profile |
| TCP 转发 | splice(2) 内核零拷贝 | `std::io::copy` 用户态 | API 完全一致,行为透明降级 |
| CPU 亲和 | `sched_setaffinity` | 返回 `Unsupported` 桩 | 不影响功能 |
| 运行时 | AF\_XDP Worker 数据面 | `std::net` Worker | Worker 使用 `std::net::TcpListener` |
| 指纹系统 | XDP + L4 + L7 三级阻断 | L4 + L7 两级阻断 | 用户态指纹完整可用,XDP 层跳过 |
| WAF/TLS/HTTP | 完整 | 完整 | 无降级 |
> **关键**:用户代码无需任何 `#[cfg(target_os)]` 条件编译。API 在所有平台完全一致。
### 20.3 Docker 容器化部署
#### 最小镜像(仅 Web 功能)
```toml
# Cargo.toml — 最小依赖
[dependencies]
zenith = { path = "...", default-features = false, features = ["web"] }
```
```dockerfile
# Dockerfile
FROM rust:1.97 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release --no-default-features --features web --example hello_server
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/examples/hello_server /usr/local/bin/zenith
EXPOSE 8080
CMD ["zenith", "--mode", "plain", "--host", "0.0.0.0", "--port", "8080"]
# 镜像大小: ~15MB(仅 zenith-web 依赖)
```
#### 完整功能镜像(含指纹 + 代理 + 运行时)
```dockerfile
FROM rust:1.97 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release --features "full-stack,fingerprint" --example hello_server
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates libbpf1 && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/examples/hello_server /usr/local/bin/zenith
EXPOSE 80 443
CMD ["zenith", "--mode", "tls", "--host", "0.0.0.0", "--port", "443", "--audit-log", "/var/log/zenith/audit.jsonl"]
# 镜像大小: ~45MB(含 libbpf + rustls + ring + quinn-proto)
```
#### docker-compose 多协议部署
```yaml
# docker-compose.yml
version: "3.8"
services:
zenith:
build: .
ports:
- "80:80" # HTTP/1.1 + HTTP/2
- "443:443" # TLS + HTTP/2
- "443:443/udp" # HTTP/3 over QUIC
environment:
- RUST_LOG=info
volumes:
- ./logs:/var/log/zenith
restart: unless-stopped
ulimits:
memlock: -1 # AF_XDP 需要 unlimited memlock
nofile: 65536
```
```bash
docker-compose up -d
docker-compose logs -f zenith
```
### 20.4 Kubernetes 部署
#### Deployment + Service
```yaml
# k8s/zenith-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: zenith
labels:
app: zenith
spec:
replicas: 3
selector:
matchLabels:
app: zenith
template:
metadata:
labels:
app: zenith
spec:
containers:
- name: zenith
image: zenith:latest
ports:
- containerPort: 80
name: http
- containerPort: 443
name: https
- containerPort: 443
protocol: UDP
name: h3
env:
- name: RUST_LOG
value: "info"
resources:
requests:
memory: "128Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "2000m"
livenessProbe:
httpGet:
path: /status
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 3
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: zenith
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
name: http
- port: 443
targetPort: 443
name: https
- port: 443
targetPort: 443
protocol: UDP
name: h3
selector:
app: zenith
```
```bash
kubectl apply -f k8s/zenith-deployment.yaml
kubectl get pods -l app=zenith
kubectl scale deployment zenith --replicas=5
```
### 20.5 嵌入式/资源受限部署
#### 最小二进制(仅类型 + WAF)
```toml
[dependencies]
zenith = { path = "...", default-features = false, features = ["api", "waf"] }
```
```bash
# 编译(无重依赖,无 TLS/HTTP/代理)
cargo build --release --no-default-features --features "api,waf"
# 二进制体积: < 2MB
```
```rust
// 仅类型定义 + WAF 检测(零重依赖)
// 适用于 IoT 网关、嵌入式代理、OpenWRT 插件
use zenith::api::{CanonicalRequest, Method};
use zenith::waf::WafEngine;
let mut waf = WafEngine::new();
// 在嵌入式 HTTP 代理中调用 WAF 检测
```
#### 交叉编译(ARM64/aarch64)
```bash
# 添加 ARM64 目标
rustup target add aarch64-unknown-linux-gnu
# 交叉编译
cargo build --release --target aarch64-unknown-linux-gnu --features "web"
# 树莓派 / ARM 服务器部署
scp target/aarch64-unknown-linux-gnu/release/examples/hello_server pi@device:/usr/local/bin/
```
### 20.6 反向代理部署(nginx 前置)
当 Zenith 作为后端应用服务器,前面放 nginx 做静态文件/SSL 终止:
```nginx
# /etc/nginx/sites-available/zenith
upstream zenith_backend {
server 127.0.0.1:18080;
# 多实例负载均衡
# server 127.0.0.1:18081;
# server 127.0.0.1:18082;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/ssl/certs/example.com.pem;
ssl_certificate_key /etc/ssl/private/example.com.key;
# 代理到 Zenith
location / {
proxy_pass http://zenith_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 健康检查
location /health {
proxy_pass http://zenith_backend/health;
access_log off;
}
}
```
```bash
# Zenith 监听 18080,nginx 前置 443
./zenith --mode plain --host 127.0.0.1 --port 18080 &
```
### 20.7 多实例 + 负载均衡
```bash
# 启动 3 个 Zenith 实例
./zenith --mode plain --port 18080 &
./zenith --mode plain --port 18081 &
./zenith --mode plain --port 18082 &
# nginx/HAProxy 轮询分发
# 或使用 Zenith 自身的反向代理功能:
./zenith --mode tls --port 443 \
# /api/* → 后端 3 个实例
# (通过 add_proxy_route 在代码中配置)
```
```rust
// 在代码中配置反向代理
server.add_proxy_route(
"/api",
vec![
("127.0.0.1:18080".to_string(), 1),
("127.0.0.1:18081".to_string(), 1),
("127.0.0.1:18082".to_string(), 1),
],
LoadBalanceStrategy::P2C, // Power of Two Choices(最优)
);
```
### 20.8 日志与监控
#### 审计日志(JSON Lines)
```bash
# 启动时指定审计日志路径
./zenith --mode tls --port 443 --audit-log /var/log/zenith/audit.jsonl
# 查看审计日志
tail -f /var/log/zenith/audit.jsonl
# {"timestamp":"2026-08-06T10:30:00Z","event":"waf_blocked","severity":"high","ip":"1.2.3.4","reason":"SQL injection"}
# {"timestamp":"2026-08-06T10:30:01Z","event":"fingerprint_blocked","severity":"high","ja3":"e64d2b3c...","reason":"blocklist"}
```
#### Prometheus + Grafana
```bash
# Zenith 自动暴露 /metrics 端点(Prometheus 0.0.4 文本格式)
curl http://localhost:18080/metrics
# zenith_requests_total{method="GET",path="/",status="200"} 850765
# zenith_waf_blocked_total 15
# zenith_cache_hits_total 300
# zenith_cache_misses_total 50
# zenith_request_duration_us_sum 1250000
# zenith_request_duration_us_count 850765
```
```yaml
# Prometheus 抓取配置
# /etc/prometheus/prometheus.yml
scrape_configs:
- job_name: zenith
static_configs:
- targets: ['localhost:18080']
metrics_path: /metrics
scrape_interval: 15s
```
#### logrotate 配置
```
# /etc/logrotate.d/zenith
/var/log/zenith/audit.jsonl {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 zenith zenith
postrotate
systemctl reload zenith 2>/dev/null || true
endscript
}
```
***
## 📎 附录
### A. Cargo.toml 完整示例
```toml
[package]
name = "my-app"
version = "0.1.0"
edition = "2024"
[dependencies]
zenith = { path = "../zenith", features = ["web", "proxy", "forward", "runtime"] }
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
tokio = { version = "1", features = ["time"] }
```
### B. 常用 API 速查
| 创建 App | `App::new()` |
| 注册路由 | `app.get(path, handler)` |
| 创建服务器 | `ProtocolServer::new(app)` |
| 配置服务器 | `ProtocolServer::try_with_config(app, cfg)` |
| 处理连接 | `server.serve_std_tcp_conn(stream, peer, tls)` |
| 绑定 QUIC | `server.bind_quic(QuicServerConfig{..}, &cert_gen)`(`use zenith::web::quic_server::QuicServerConfig`) |
| 创建 TLS Acceptor | `TlsAcceptor::new(TlsConfig::new().with_certs(cert, key))` |
| 添加代理路由 | `server.add_proxy_route(prefix, upstreams, strategy)` |
| 上游协议 | `("h3://host:port".into(), 1)` / `("auto://host:port".into(), 1)` / 裸地址 = HTTP/1.1 |
| 触发热切换 | `server.trigger_changeset()` |
| 导出指标 | `server.export_metrics()` |
| TCP 转发 | `TcpRelay::default().relay(&client, &upstream)` |
| IP 准入 | `SourceAdmissionEngine::deny_all().add_rule(...)` |
| CIDR 白名单 | `AddressWhitelist::new().with_allowed_cidr_ip(ip, prefix)` |
| 缓存键 | `CacheKeyBuilder::new("GET", "/api").build()` |
| 缓存读/写 | `cache.put(CacheEntry::new(key, body, 200, ct, policy, tenant_id, now)); cache.get(&key, tenant_id, now)` |
| WAF 自定义规则 | `WafEngine::new().add_rule(RuleBuilder::new(id).pattern(PatternField::UserAgent, "bot").build())` |
| TLS 指纹快照 | `server.security().fingerprint_snapshot()` |
| 全局运行时 | `zenith::rt::init_global(RuntimeConfig::auto())` |
| 异步 spawn | `zenith::rt::spawn(async { ... })` |
| 阻塞执行 | `zenith::rt::block_on(async { ... })` |
#### B.1 核心 API 参数签名(准确描述)
> 以下为经源码核验的真实签名。凡标注"无"者为**不存在**的方法,勿照抄。
**路由与服务器(zenith-web)**
| `App::get/post/put/delete/patch/any(path, handler)` | `path: &str` / `handler: F` | `handler` 签名为 `Fn(&CanonicalRequest, &RouteMatch) -> Result<CanonicalResponse, WebError>`;`RouteMatch::get(name) -> Option<&str>` 取路径参数;`any` 匹配任意方法 |
| `app.middleware(mw)` | `mw: M: Middleware` | 内置 CORS/Auth/Identity/Logging/RequestId,自定义则落入扩展链 |
| `ProtocolServer::new(app)` / `try_with_config(app, ServerConfig)` | — | 后者返回 `Result<_, ServerError>` |
| `serve_std_tcp_conn(stream, client_addr, tls_acceptor)` | `stream: TcpStream` / `client_addr: SocketAddr` / `tls_acceptor: Option<&mut TlsAcceptor>` | `None` = 明文;`Some` = TLS+ALPN 自动协商 |
| `add_proxy_route(prefix, upstreams, strategy)` | `prefix: &str` / `upstreams: Vec<(String,u32)>` / `strategy: LoadBalanceStrategy` | 前缀匹配 `== prefix` 或 `prefix + "/"` 开头;`(地址,权重)` |
| `bind_quic(QuicServerConfig, &CertGeneration)` | 见下 | HTTP/3 绑定 |
| `serve_udp_loop(max_packet_size)` | `max_packet_size: usize` | UDP 数据面循环 |
**QUIC(`zenith::web::quic_server::QuicServerConfig`,结构体字段)**
| `bind_addr` | `SocketAddr` | UDP 监听地址 |
| `version` | `QuicVersion` | `V1`(RFC9000) / `V2`(RFC9369) |
| `max_connections` | `usize` | 最大并发连接(默认 65536) |
| `idle_timeout_ms` | `u64` | 空闲超时毫秒(默认 30000) |
**ProtocolServer 完整方法(`zenith::web::server`)**
| `new(app)` / `with_config(app, cfg)` / `try_with_config(app, cfg)` | `App` / `(App, ServerConfig)` | 构造;后两者区别为是否返回 `Result<_, ServerError>` |
| `config()` / `app()` / `security()` | `&ServerConfig` / `&App` / `&SecurityPipeline` | 访问器 |
| `runtime_snapshot()` | `-> RuntimeSnapshot` | 运行时配置只读快照 |
| `update_runtime(f)` | `f: impl FnOnce(&RuntimeConfigRef)` | 无锁热更新入口 |
| `set_cache_capacity(e, b)` / `set_forward_config(cfg)` / `forward_config()` | `(usize, usize)` / `ForwardConfig` | 缓存容量 / L4 转发引擎参数热更新 |
| `set_proxy_config(cfg)` / `update_proxy_config(f)` / `proxy_config()` | `ProxyConfig` / 闭包 | 反向代理参数热更新 |
| `serve_std_tcp_conn(stream, client_addr, tls)` | `TcpStream` / `SocketAddr` / `Option<&mut TlsAcceptor>` | 单连接处理(明文或 TLS+ALPN) |
| `handle_http1_connection(io, transport, client_ip)` | `IO: Read+Write` | 显式 HTTP/1.1 处理 |
| `handle_http2_connection(io, transport, client_ip)` | `IO: Read+Write` | 显式 HTTP/2 处理 |
| `handle_http2_connection_with_initial(io, transport, initial, fp, sni, ip)` | 初始字节 + 指纹 + SNI | 带初始缓冲的 H2 处理 |
| `is_http2_preface(buf)` | `&[u8] -> bool` | 判断是否 H2 preface(关联函数) |
| `detect_protocol_from_post_tls(d, alpn)` / `detect_protocol_from_peek(d, alpn)` | `-> Protocol` | 协议检测 |
| `bind_quic(cfg, cert_gen)` / `bind_quic_socketless(cfg, cert_gen)` | `-> Result<(), String>` | HTTP/3 绑定(含无 socket 模式) |
| `serve_udp_loop(max_packet_size)` | `usize -> Result<(), ServerError>` | UDP 数据面循环 |
| `serve_udp_quic_datagram(data, from)` | `-> Result<Vec<(Vec<u8>,SocketAddr)>, ServerError>` | 单数据报处理 |
| `quic_local_addr()` / `is_quic_bound()` / `is_quic_socketless()` / `quic_active_connections()` | `-> Option<SocketAddr>` 等 | QUIC 状态观测 |
| `add_proxy_route(prefix, upstreams, strategy)` | `(String, Vec<(String,u32)>, LoadBalanceStrategy)` | 注册反向代理路由 |
| `add_l4_tcp_forward(listen, upstream)` / `add_l4_udp_forward(listen, upstream)` | `-> Result<JoinHandle<()>, ServerError>` | 启动 L4 转发线程 |
| `create_forward_session(client, upstream)` | `-> Option<u64>` | L4 会话登记 |
| `tls_fingerprints()` / `tls_fingerprint_count()` | `Vec<Ja3Fingerprint>` / `usize` | TLS 指纹观测 |
| `export_metrics()` / `audit_log()` | `String` / `Vec<String>` | 指标 / 审计导出 |
| `start_supervisor()` / `stop_supervisor()` / `supervisor_state()` | — | Supervisor 治理(runtime) |
| `trigger_changeset()` / `changeset_state()` | `Result<u64,String>` / `ChangeSetState` | 热切换(runtime) |
| `proxy_stats()` | `Vec<(String, PoolStats)>` | 代理池统计 |
**SecurityPipeline 完整方法(`server.security()`)**
| `update_runtime(f)` / `runtime_snapshot()` / `runtime_bind_addr()` | — | 热更新 / 快照 / 监听地址 |
| `set_cache_capacity` / `set_forward_config` / `forward_config` | — | 缓存 / L4 转发热更新 |
| `set_proxy_config` / `update_proxy_config` / `proxy_config` | — | 代理热更新 |
| `waf_enabled_for_host(host)` | `&str -> bool` | host 是否启用 WAF |
| `add_waf_rule(r)` / `add_waf_rules(rules)` / `remove_waf_rule(id)` / `set_waf_rule_enabled(id, b)` / `clear_waf_rules()` / `clear_waf_detectors()` / `add_waf_detector(Box<dyn Detector>)` / `waf_rule_count()` | — | WAF 规则热更新 |
| `record_fingerprint(fp)` / `fingerprint_snapshot()` / `fingerprint_count()` | — | 指纹记录 |
| `add_fingerprint_to_blocklist(p)` / `remove_fingerprint_from_blocklist(p)` / `clear_fingerprint_blocklist()` / `fingerprint_blocklist_snapshot()` | — | 指纹阻断热更新 |
| `check_fingerprint_blocklist(fp)` / `check_fingerprint_rate_limit(fp, max, window)` / `check_fingerprint_decision(action)` | — | 指纹判定 |
| `fingerprint_rate_limit_snapshot()` | `-> FxHashMap<String,(u64,u32)>` | 限流观测 |
| `audit_snapshot()` | `-> Vec<String>` | 审计观测 |
**RuntimeConfigRef 完整 setter(`zenith::web`,闭包内 `r`)**
> 全部 `&self`,标量经原子 `store`,host 名单经写锁;更新对所有 `clone` 副本立即生效。
| `set_waf_enabled` | `bool` | 全局 WAF 开关 |
| `enable_waf_for_host` / `disable_waf_for_host` | `&str` | host 白名单加入/移除 |
| `bypass_waf_for_host` / `unbypass_waf_for_host` | `&str` | host 黑名单加入/移除 |
| `set_waf_host_lists` | `(Vec<String>, Vec<String>)` | 整体替换黑白名单 |
| `set_fingerprint_security` | `bool` | 指纹安全开关 |
| `set_fingerprint_rate_limit` | `(u32, u64)` | 每窗口请求数 / 窗口 ms |
| `set_waf_offload` | `(usize, u64)` | body 阈值 / 期限 |
| `set_udp_max_sessions` | `usize` | UDP 会话上限 |
| `set_udp_session_idle_timeout_ms` / `set_udp_session_cleanup_timeout_ms` | `u64` | UDP 超时 |
| `set_forward_session_timeout_ms` | `u64` | L4 转发会话超时 |
| `set_supervisor_max_consecutive_5xx` | `u64` | Supervisor 熔断阈值 |
| `set_http1_max_requests_per_conn` | `u32` | keep-alive 请求上限 |
| `set_http1_idle_timeout_ms` | `u64` | Slowloris 空闲超时 |
| `set_max_body_size` / `set_read_buffer_size` / `set_write_buffer_size` | `usize` | 请求体 / 读 / 写缓冲 |
| `set_http2_max_frame_size` | `u32` | HTTP/2 帧长(RFC 钳制) |
| `set_http2_max_concurrent_streams` | `u32` | HTTP/2 并发流上限 |
| `set_http3_max_field_section_size` | `u64` | HTTP/3 字段段上限 |
| `set_metrics_auth_token` | `Option<String>` | /metrics 令牌 |
| `set_bind_addr` | `Option<SocketAddr>` | 端口一致性检查 |
**路由参数提取(`zenith::web::extract`)**
| `query_param(req, name)` | `Result<String, ExtractError>` | 缺失/非法→NotFound |
| `query_param_or(req, name, default)` | `String` | 缺失用默认值 |
| `query_param_parse::<T>(req, name)` | `Result<T, ExtractError>` | 类型解析 |
| `path_param_parse::<T>(params, name)` | `Result<T, ExtractError>` | 路径参数强类型 |
| `header_value(req, name)` | `Option<&str>` | 可选头 |
| `header_required(req, name)` | `Result<&str, ExtractError>` | 必需头 |
| `path_param(params, name)` | `Result<PathParam, ExtractError>` | 返回 `PathParam { name, value }`,`as_str()`/`parse::<T>()` |
| `parse_query(query)` | `FxHashMap<String,String>` | 解析查询串 |
| `url_decode(s)` | `Option<String>` | URL 解码(非法返回 `None`) |
| `Pagination::from_request(req)` | `Pagination` | 字段 `page`/`per_page`,`offset()` |
| `UserId::from_params(params)` | `Result<UserId, ExtractError>` | 强类型用户 ID |
| `trait FromRequest::from_request(req, params)` | `Result<Self, ExtractError>` | 自定义提取器 |
| `trait IntoResponse::into_response(self)` | `CanonicalResponse` | 实现于 `&str`/`String`/`()`/`u16`/`Result<T,ExtractError>` |
**ServerConfig 管线参数(`zenith::web`)**
> 作为依赖库,内置管线所有容量/超时/阈值均**可配置**(默认值 = 安全保守值)。
> 全部通过 `ServerConfig::with_xxx` builder 定制,未配置时按需关闭(严格按需)。
| `with_bind_addr(SocketAddr)` | `None` | 启用 :authority/Host 端口一致性检查 → 421 |
| `with_allowed_hosts([...])` | `[]` | 虚拟主机白名单(非白名 → 421) |
| `with_audit_log_path(path)` | `None` | 审计日志 JSON Lines 落盘 |
| `with_http1_max_requests_per_conn(n)` | `100` | keep-alive 请求上限 |
| `with_http1_idle_timeout_ms(ms)` | `30_000` | Slowloris 空闲超时 |
| `with_http2_max_frame_size(n)` | `16384` | HTTP/2 帧长(RFC 范围) |
| `with_http2_max_concurrent_streams(n)` | `100` | HTTP/2 并发流上限 |
| `with_http3_max_field_section_size(n)` | `1MB` | HTTP/3 字段段上限 |
| `with_read_buffer_size(n)` / `with_write_buffer_size(n)` | `65536` | 读/写缓冲 |
| `with_max_body_size(n)` | `16MB` | 请求体上限(超 → 413) |
| `with_waf(true)` | `false` | 全局开启内置 WAF |
| `with_waf_enabled_hosts([...])` / `with_waf_disabled_hosts([...])` | `[]` | 按 host 白/黑名单差异化 WAF |
| `with_fingerprint_security(true)` | `false` | 启用指纹黑名单 + 限流 |
| `with_fingerprint_rate_limit_requests(n)` | `100` | 指纹限流每窗口最大请求数 |
| `with_fingerprint_rate_limit_window_ms(ms)` | `60_000` | 指纹限流时间窗口 |
| `with_cache_max_entries(n)` | `65536` | 内置缓存条目上限 |
| `with_cache_max_size_bytes(n)` | `16MB` | 内置缓存字节上限 |
| `with_waf_offload_body_threshold(n)` | `65536` | WAF 大 body 卸载阈值(字节) |
| `with_waf_offload_deadline_ms(ms)` | `5000` | WAF 卸载执行期限 |
| `with_udp_max_sessions(n)` | `4096` | L4 UDP 转发会话上限 |
| `with_udp_session_idle_timeout_ms` / `with_udp_session_cleanup_timeout_ms` | `60s`/`300s` | UDP 会话空闲/清理超时 |
| `with_forward_session_timeout_ms(ms)` | `300000` | L4 转发会话超时 |
| `with_forward_config(ForwardConfig)` | `default` | L4 转发引擎容量/带宽 |
| `with_supervisor_max_consecutive_5xx(n)` | `10` | Supervisor 连续 5xx 熔断阈值 |
| `with_proxy(ProxyConfig)` | `ProxyConfig::default()` | 代理池/健康/超时(见下) |
**ProxyConfig 参数(`zenith::proxy`,经 `ServerConfig::with_proxy` 注入)**
| `with_pool_max_total` / `with_pool_max_per_upstream` | `256`/`32` | TCP 连接池上限 |
| `with_tls_pool_max_total` / `with_tls_pool_max_per_upstream` / `with_tls_pool_max_uses` | `128`/`16`/`100` | TLS 池上限 |
| `with_pool_idle_timeout_ms` / `with_tls_pool_idle_timeout_ms` | `60s`/`30s` | 池空闲超时 |
| `with_health_failure_threshold` / `with_health_success_threshold` | `5`/`3` | 健康检查熔断/恢复阈值 |
| `with_health_recovery_timeout_ms` / `with_health_probe_interval_ms` / `with_health_window_ms` | `10s`/`5s`/`60s` | 健康熔断参数 |
| `with_forward_connect_timeout_ms` / `with_forward_read_timeout_ms` / `with_forward_max_response_bytes` | `1s`/`5s`/`1MB` | 上游转发超时/上限 |
| `with_h3_request_timeout_ms` / `with_auto_tls_handshake_timeout_ms` | `5s`/`3s` | H3/auto 上游超时 |
| `with_auto_h2_failure_threshold` / `with_auto_h2_recovery_interval` / `with_auto_h2_stable_success_threshold` | `3`/`100`/`5` | 自动路径 H2 健康阈值 |
**运行时热更新(`zenith::web`,`ProtocolServer`)**
> 上述 `ServerConfig` 的运行参数既可在构建期配置,也可**运行时热更新**(无需重建服务器)。
> **除固定协议规范常量外,所有运行参数均可热更新**。热路径读取一律为**无锁原子加载**
> (`AtomicU64`/`AtomicBool`,单条指令),host 名单仅当 WAF 启用时才触碰 `RwLock` 读锁——
> 默认关闭时零锁、零开销。写(热更新)低于微秒级,不触碰读热路径。更新对所有 `clone`
> 副本立即生效。
```rust
// 构建期:WAF 关闭
let server = ProtocolServer::new(app);
// 运行时热更新:按需一键开启/调整(无需重建服务器)
server.update_runtime(|r| {
r.set_waf_enabled(true); // 全局开启 WAF
r.enable_waf_for_host("api.example.com"); // 白名单:仅此域开 WAF
r.bypass_waf_for_host("static.example.com"); // 黑名单:此域跳过 WAF
r.set_fingerprint_security(true); // 开启指纹黑名单 + 限流
r.set_fingerprint_rate_limit(200, 30_000); // 指纹限流:200 次 / 30s
r.set_udp_max_sessions(8192); // 调整 UDP 会话上限
r.set_forward_session_timeout_ms(120_000); // 调整 L4 转发会话超时
r.set_supervisor_max_consecutive_5xx(3); // 调整熔断阈值
r.set_waf_offload(128_000, 8_000); // 调整 WAF 卸载阈值/期限
r.set_http1_max_requests_per_conn(1000); // 调整 keep-alive 请求上限
r.set_http1_idle_timeout_ms(60_000); // 调整 Slowloris 空闲超时
r.set_max_body_size(32 * 1024 * 1024); // 调整请求体上限
r.set_read_buffer_size(65_536); // 调整读缓冲
r.set_write_buffer_size(65_536); // 调整写缓冲
r.set_http2_max_frame_size(16_384); // 调整 HTTP/2 帧长(RFC 范围钳制)
r.set_http2_max_concurrent_streams(200); // 调整 HTTP/2 并发流上限
r.set_http3_max_field_section_size(2_000_000); // 调整 HTTP/3 字段段上限
r.set_metrics_auth_token(Some("t".into())); // 热启用/轮换 /metrics 令牌
});
// 缓存容量热更新(无需重建引擎)
server.set_cache_capacity(65536, 16 * 1024 * 1024);
// L4 转发引擎参数热更新:并发会话上限 / 单会话带宽,立即生效(无需重建引擎)
server.set_forward_config(
zenith::forward::ForwardConfig::default()
.with_max_concurrent_sessions(8192)
.with_max_bandwidth_per_session(2 * 1024 * 1024 * 1024),
);
let fc = server.forward_config(); // 观测当前值
// 反向代理运行参数热更新(连接池/超时/健康阈值,逐字段或整体替换)
p.health_failure_threshold = 3;
});
server.set_proxy_config(zenith::proxy::ProxyConfig::default().with_pool_max_total(2048));
let pc = server.proxy_config(); // 观测当前值
// 监听地址热更新(启用/切换端口一致性检查 → 421;实际 socket 由调用方持有,
// 新连接生效,默认关闭时零锁快速路径)
server.update_runtime(|r| r.set_bind_addr(Some("127.0.0.1:8443".parse().expect("addr"))));
// 防火墙(WAF)规则热更新:增/删/启停/清空规则、检测器,写锁施加立即生效
server.security().add_waf_rule(RuleBuilder::new("block-admin").path("/admin").build());
server.security().remove_waf_rule("block-admin");
server.security().set_waf_rule_enabled("sqli", false);
server.security().clear_waf_rules();
server.security().add_waf_detector(Box::new(MyDetector::new()));
// 指纹阻断规则热更新:加/删/清空单个 JA3 前缀
server.security().add_fingerprint_to_blocklist("abc123".to_string());
server.security().remove_fingerprint_from_blocklist("abc123");
server.security().clear_fingerprint_blocklist();
// 读取当前运行时配置快照(观测)
let snap: RuntimeSnapshot = server.runtime_snapshot();
println!("waf={} hosts={:?}", snap.waf_enabled, snap.waf_enabled_hosts);
```
> **覆盖范围**:WAF 开关/按 host 黑白名单、**防火墙规则增删改查**(`add_waf_rule`/
> `remove_waf_rule`/`set_waf_rule_enabled`/`clear_waf_rules`/检测器)、**指纹阻断规则**
> (`add_fingerprint_to_blocklist`/`remove_fingerprint_from_blocklist`/`clear_fingerprint_blocklist`)、
> UDP 会话上限/超时、L4 转发会话超时、Supervisor 熔断阈值、WAF 卸载阈值/期限、
> HTTP/1.1 请求上限/空闲超时、请求体上限、读/写缓冲大小、/metrics 认证令牌、**监听地址**、
> 缓存容量、**L4 转发引擎参数**(`set_forward_config`/`forward_config`)、**反向代理运行参数**
> (`set_proxy_config`/`update_proxy_config`/`proxy_config`:连接池/超时/健康阈值)、
> **HTTP/2 帧长/并发流、HTTP/3 字段段上限**(`set_http2_max_frame_size`/
> `set_http2_max_concurrent_streams`/`set_http3_max_field_section_size`)——全部运行时热更新。
> **L2/L3 数据面**(`zenith::net`/`zenith::linux`/`zenith::ebpf`):eBPF `config_map`
> 键(MTU/协议白名单/fail-closed/期望策略)经 `BpfMaps::set_*`/`update_*` 热更新;
> 每包解析步数预算经 `parse_packet_with_budget(data, budget)` 按调用方指定自由权衡;
> `XskConfig` 的 socket 收发缓冲(`so_rcvbuf`/`so_sndbuf`)与 Fill Ring 预填分块
> (`prefill_chunk`)可配置;传输表容量经 `ConnectionTable::new(capacity)`/
> `UdpSessionTable::new(capacity)`/`QuicConnectionTable::new(capacity)` 启动注入,
> `BindTable::with_capacity(n)` 配置监听注册表容量。
> **固定内容**:协议规范常量(QPACK/Huffman、QUIC 版本、IP/TCP 头长、
> 以太网头长、MTU 标准值等)为标准值,不可改;Worker `MAX_BATCH_SIZE` 为固定栈数组
> (`[XdpDesc; N]`),属刻意零堆分配热路径优化,运行时改为堆分配反而降低吞吐,故保持
> 编译期常量。
> **代理热更新语义**:`set_proxy_config`/`update_proxy_config` 热更新后——**转发超时**
> (connect/read/H3/auto-TLS)每请求读取当前值,对既有路由**立即生效**;**连接池/健康阈值**
> 在引擎内固化为活实例,对 `add_proxy_route` 后续注册的新路由生效(路由本身支持运行时
> 增删,`add_proxy_route` 读取当前配置)。
> **说明**:`server.config()` 返回**构建期**快照,运行时更新不影响它;运行时值用
> `runtime_snapshot()` 读取。热更新 API 详见 `RuntimeConfigRef` 的 `set_*`/`enable_*`/`bypass_*`
> 方法集与 `SecurityPipeline` 的 `add_waf_rule`/`add_fingerprint_to_blocklist` 等规则方法。
**WAF(`zenith::waf`)**
内置管线 WAF **默认关闭**(严格按需),用 `ServerConfig` 开关控制:
| `ServerConfig::new().with_waf(true)` | 全局开启内置 WAF(默认 `false`) |
| `with_waf_enabled_hosts([...])` | 按 host 白名单强制启用(即使全局关) |
| `with_waf_disabled_hosts([...])` | 按 host 黑名单跳过(即使全局开) |
| `WafEngine::new()` | 独立引擎(**默认零检测器零规则**,可作完全自定义/关闭) |
| `WafEngine::new().with_default_detectors()` | 追加内置 6 检测器(SQL/XSS/SSRF/命令注入/路径穿越/BotThreat) |
| `WafEngine::new().add_rule(rules)` / `add_detector(d)` | 仅自定义规则 / 自定义检测器 |
| `check_request(method, path, &FxHashMap<&str,&str>, body, query)` | 返回 `WafResult`(`has_threat` / `severity` / `triggered_rules`);另有 `check_canonical(&CanonicalRequest)` |
| `RuleBuilder::new(id)` | 默认 action=Block;`.monitor()` / `.log_only()` 改动作 |
| `.pattern(PatternField, sub)` / `.path_prefix` / `.methods(&[&str])` / `.query_value(name, expected)` / `.and(Vec<RuleCondition>)` / `.or(Vec<RuleCondition>)` | 条件构建 |
| `RuleCondition` 变体 | `Path{pattern,prefix}` `Method{methods}` `HeaderExists{name}` `HeaderValue{name,expected,contains}` `QueryValue{name,expected}` `Pattern{field,pattern}` `DetectorTriggered{detector}` `And` `Or` `Not` `Always` |
**RuleBuilder 完整方法(`zenith::waf`,全部返回 `Self`)**
| `RuleBuilder::new(id)` | `&str` | 规则 ID |
| `.description(desc)` | `&str` | 描述 |
| `.severity(sev)` | `DetectionSeverity` | `Info/Low/Medium/High/Critical` |
| `.path(path)` | `&str` | 精确路径匹配 |
| `.path_prefix(prefix)` | `&str` | 路径前缀匹配 |
| `.methods(&[&str])` | 方法列表 | 方法匹配 |
| `.header_exists(name)` / `.header_value(name, expected)` / `.header_contains(name, pattern)` | `&str` | 头存在/值/包含 |
| `.query_value(name, expected)` | `&str` | 查询参数值 |
| `.path_pattern(p)` / `.query_pattern(p)` / `.body_pattern(p)` | `&str` | 子串包含(非正则) |
| `.pattern(field, pattern)` | `(PatternField, &str)` | 通用字段子串;`PatternField::{Path,Query,Body,UserAgent,Referer}` |
| `.detector_triggered(detector)` | `&str` | 依赖检测器触发 |
| `.and(conds)` / `.or(conds)` | `Vec<RuleCondition>` | 组合 |
| `.disabled()` | — | 默认禁用 |
| `.priority(p)` | `i32` | 优先级 |
| `.monitor()` / `.log_only()` | — | 动作 = Monitor / LogOnly(默认 Block) |
| `.build()` | `-> CompiledRule` | 产出 |
**WafEngine 完整方法(`zenith::waf`)**
| `new()` / `with_default_detectors()` | 空引擎 / 追加内置 6 检测器 |
| `add_rule(r)` / `add_rules(rules)` / `remove_rule(id)` / `set_rule_enabled(id, b)` / `clear_rules()` | 规则增删改查 |
| `add_detector(Box<dyn Detector>)` / `clear_detectors()` | 自定义检测器 |
| `rule_count()` | 规则数 |
| `check_canonical(&CanonicalRequest)` / `check_request(m, path, headers, body, query)` | 检测入口,返回 `WafResult` |
**TLS 指纹安全开关(`zenith::web`)**
| `ServerConfig::new().with_fingerprint_security(true)` | 启用内置指纹黑名单 + 速率限制(默认 `false`,严格按需) |
| `with_fingerprint_rate_limit_requests(n)` | 指纹限流:每时间窗口每个 JA3 最大请求数(默认 `100`) |
| `with_fingerprint_rate_limit_window_ms(ms)` | 指纹限流时间窗口(默认 `60_000`) |
**TLS(`zenith::tls`)**
| `CertGeneration::from_pem(cert_pem: &[u8], key_pem: &[u8])` | PEM 字节 | 返回 `Result<_, CertRotateError>` |
| `to_server_config(alpn: Vec<Vec<u8>>)` | ALPN 协议列表 | 转 rustls ServerConfig(返回 `Result<Arc<ServerConfig>, _>`;不能直接传给 `TlsAcceptor::new`,后者接收 `TlsConfig`) |
| `CertManager::set_default(gen)`、`set_for_domain(domain, gen)`、`swap_domain(domain)` | — | 无 `add_generation` 方法 |
| `CertBank::set_active/set_standby/swap()` | — | 原子热切换 |
| `TlsConfig::with_certs(cert_path, key_path)` | 文件路径 | 从文件读证书 |
**缓存(`zenith::cache`)**
| `CacheEngine::new(max_entries, max_size_bytes)` | 条目/字节上限 | 16 分片 |
| `set_capacity(max_entries, max_size_bytes)` | — | 容量热更新(原子) |
| `with_policy(EvictionPolicy)` | `Lru`/`Fifo`/`Random` | 默认 Lru |
| `with_shared_cache(bool)` | — | 启用 s-maxage |
| `CacheEntry::new(key, value, status, content_type, policy, tenant_id, now_ms)` | `tenant_id: u32` | tenant 为 u32 非字符串 |
| `get(key, tenant_id, now_ms)` | — | 返回 `CacheHit::{Fresh,Stale,Miss}` |
| `peek(key, tenant_id, now_ms)` | — | 不更新计数的只读 |
| `get_conditional(key, tenant_id, now_ms, if_none_match, range)` | `Option<&str>` / `Option<ByteRange>` | 返回 `ConditionalHit` |
| `put(entry)` / `put_at(entry, now_ms)` | — | 写入 |
| `invalidate(key)` / `delete(key)` / `clear()` | — | 失效/删除/清空 |
| `evict_expired(now_ms)` | — | 过期淘汰 |
| `stats()` | `-> CacheStats` | 命中率等 |
| `CacheKeyBuilder::new(method, path)` | `&str` | 额外的 `.host/.query_string/.query_param/.vary/.build()` |
| `CacheKeyBuilder::from_canonical(&CanonicalRequest)` | — | 从规范请求构建 |
| `CachePolicy::public(secs)/private(secs)/no_cache()/no_store()` | — | 便捷构造 |
| `CachePolicyBuilder::new(Cacheability)` + `.max_age/.s_maxage/.stale_while_revalidate/.stale_if_error/.must_revalidate/.proxy_revalidate/.vary/.build()` | — | 精细构造 |
| `CachePolicy::parse_directive(header)` | `&str` | 从 `Cache-Control` 头解析 |
| `ByteRange::parse(header)` / `.validate(total)` / `.content_range(total)` | — | Range 处理 |
**L4 转发(`zenith::forward`)**
| `ForwardEngine::new()` / `with_config(cfg)` | `ForwardConfig` | 默认 / 自定义容量带宽 |
| `set_config(cfg)` / `config()` | `ForwardConfig` | 热更新 / 观测 |
| `with_whitelist(AddressWhitelist)` | — | 双向白名单(防 SSRF) |
| `create_session(protocol, client, upstream)` | `(ForwardProtocol, SocketAddr, SocketAddr)` | 返回 `Option<u64>`(超限/拒绝→None) |
| `get_session(id)` / `get_session_mut(id)` / `close_session(id)` | `u64` | 会话操作 |
| `cleanup_closed(timeout_ms)` | `u64` | 清理超时/关闭会话 |
| `session_count()` / `active_count()` / `total_sessions()` | — | 统计 |
| `reset_bandwidth()` | — | 按当前配置重置配额 |
| `sessions_iter_mut()` | — | 批量记账 |
| `stats()` | `-> ForwardStats` | 统计 |
| `ForwardConfig::default()` + `.with_max_concurrent_sessions(n)` / `.with_max_bandwidth_per_session(bps)` | — | 并发上限 / 单会话带宽 |
| `TcpRelay::new(buf_size)` / `default()` / `.relay(client, upstream)` | `(usize)` / 流对 | 跨平台中继,返回 `(c2u, u2c)` |
| `AddressWhitelist::new()` + `.with_allowed/.with_allowed_cidr/.with_allowed_ip/.with_allowed_cidr_ip/.add_entry/.set_default_allow/.is_allowed/.remove_ip/.clear` | — | 白名单(fail-closed 默认拒绝);`with_allowed`/`with_allowed_cidr` 另需 `Range<u16>` 端口参数,无端口场景用 `with_allowed_ip`/`with_allowed_cidr_ip` |
| `Backpressure::new()` + `.with_watermarks(h,c)/.state()/.usage()/.should_pause()/.should_throttle()/.recommended_window(base_window)` | — | 背压控制(`recommended_window` 需传入 base_window) |
**反向代理(`zenith::proxy`)**
| `LoadBalanceStrategy` | `RoundRobin`/`P2C`/`Rendezvous`/`Ewma`/`WeightedRoundRobin`/`IpHash` |
| 上游 scheme 前缀 | `h3://` `h2://` `https://` `http://` `tcp://` `udp://` `auto://` |
| `ProxyEngine::with_config(strategy, &ProxyConfig)` | 独立引擎;`add_upstream`/`set_upstreams`/`select_upstream`/`get_upstream_mut`/`record_result`/`run_health_checks` |
| `ProxyConfig::default()` + 20 个 `with_*` | 池/超时/健康/auto 阈值(见上表) |
| `forward::ForwardConfig::new()` + `with_connect_timeout_ms`/`with_read_timeout_ms`/`with_max_response_bytes`/`with_h3_request_timeout_ms`/`with_auto_tls_handshake_timeout_ms`/`with_tls_verify` | 单请求转发配置 |
| `parse_upstream_address(addr)` / `format_upstream_address(scheme, addr)` | `(UpstreamScheme, String)` | 上游地址解析/格式化 |
| `UpstreamScheme` | `Http1/Https/H2/H3/Tcp/Udp/Auto`;`is_l4()/is_http()/requires_tls()` |
| `AutoPathHealth::new()` / `with_thresholds(f,t,s)` / `h2_allowed()` / `record_h2_success()/failure()` | 自动路径健康状态 |
**可观测性(`zenith-observability`)**
| `MetricsCollector<N>::new()` | 默认 N=64;`counter_inc/counter_add(name,delta,labels)`、`gauge_set/gauge_inc/gauge_dec/gauge_add/gauge_sub(name,val,labels)`、`histogram_record(name,val,labels)`、`export_prometheus()`。**无 `record_request` 等** |
| `AuditLogger::new()` | 无参;`log(AuditEvent)`、`events()`、`AuditLogger::format_event(e)`。**无 `snapshot()`、无容量参数** |
| `AuditEvent::new(timestamp, severity, category, actor, action, target, result)` | 7 参;IP/头部自动脱敏 |
| `FaultRecorder::new()` | 无参;`record(FaultType, &str)->u64`、`list_recent(limit)`。**无 `record_fault()`** |
**运行时(`zenith::rt`)**
| `init_global(RuntimeConfig)` | `RuntimeConfig::auto()` 自动探测;`new().with_worker_threads(n).with_stack_size(bytes)` |
| `spawn` / `block_on` | 全局运行时便捷函数 |
### C. 平台兼容性矩阵
| HTTP/1.1 解析 | 完整 | 完整 | 完整 | 跨平台 |
| HTTP/2 帧解析 | 完整 | 完整 | 完整 | 跨平台 |
| HTTP/3 over QUIC | 完整 | 完整 | 完整 | 跨平台 |
| TLS 1.3 (rustls+ring) | 完整 | 完整 | 完整 | 跨平台 |
| WAF 6 检测器 | 完整 | 完整 | 完整 | 跨平台 |
| 反向代理/负载均衡 | 完整 | 完整 | 完整 | 跨平台 |
| CDN 缓存 | 完整 | 完整 | 完整 | 跨平台 |
| IP 准入过滤 | 完整 | 完整 | 完整 | 跨平台 |
| L4 TCP 转发 | splice(2) 零拷贝 | std::io::copy | std::io::copy | API 一致,性能降级 |
| L4 UDP 转发 | 完整 | 完整 | 完整 | 跨平台 |
| AF\_XDP 零拷贝 | 完整 | 不可用 | 不可用 | 仅 Linux |
| eBPF/XDP 内核过滤 | 完整 | 不可用 | 不可用 | 仅 Linux |
| io\_uring 批量 IO | 完整 | 不可用 | 不可用 | 仅 Linux |
| splice(2) 零拷贝 | 完整 | 不可用 | 不可用 | 仅 Linux |
| CPU 亲和性 | sched\_setaffinity | 桩(返回 Unsupported) | 桩(返回 Unsupported) | 仅 Linux |
| 全链路指纹系统 | 完整 | 完整(用户态) | 完整(用户态) | 跨平台(XDP 层仅 Linux) |
| ProtocolExpectation 非预期包丢弃 | Worker 层完整 | Worker 层完整 | Worker 层完整 | 跨平台(XDP 层仅 Linux) |
| 运行时 Supervisor | 完整 | 完整(降级) | 完整(降级) | 跨平台 |
| ChangeSet 热切换 | 完整 | 完整 | 完整 | 跨平台 |
| Prometheus 指标 | 完整 | 完整 | 完整 | 跨平台 |
| 审计日志 | 完整 | 完整 | 完整 | 跨平台 |
> **降级策略**:`EnvironmentDetector` 自动探测系统能力 → `ProfileSelector` 评分选择最优 Profile → `degrade()` 三级降级链(Performance → Balanced → Minimal)。用户无需手动处理降级——API 一致,行为自动适配。