Ferron 2.8.1 配置参数详解
Ferron 2.8.1 全量配置参数详解:KDL 配置结构、热重载实测、按功能域分类的指令清单(作用域/默认值)、负载均衡与 ACME 质询对比、三套生产模板与真实排障,2026-10-20。
Ferron 2.8.1 配置参数详解
目标:系统梳理 Ferron 2.8.1(官方最新稳定版)的全部配置参数:配置文件组织结构、修改与热重载流程、按功能域分类的指令清单(作用域/默认值/用法)、三套生产配置模板与真实排障记录。指令默认值以官方 2.8.1 版文档为准,配置行为均经真实环境实测验证(查询/实测日期 2026-10-20)。
一、环境信息
| 项 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(jammy),x86_64 |
| 目标软件 | Ferron 2.8.1(Stable 通道,2026-06-17 发布,APT 方式安装) |
| 配置文件 | /etc/ferron.kdl(KDL 格式) |
| 指令默认值依据 | Ferron 2.8.1 官方文档(tag 2.8.1 源码 docs/configuration/,与发布二进制同源) |
| 实测方式 | systemctl 托管运行 + 前台运行对照、curl 验证响应、journalctl 溯源 |
| 查询/实测日期 | 2026-10-20 |
二、前置条件
- 已按《Ubuntu 22.04 安装 Ferron 指南》完成 Ferron 2.8.1 安装,
systemctl status ferron显示active (running)。 - 了解 KDL 语法三要素:节点(指令名 + 空格分隔的参数值)、属性(
key=value形式的具名参数,布尔值用#true/#false,空值用#null)、子块(节点名 { ... }花括号嵌套);//为行注释。 - 理解 Ferron 的配置作用域三层模型:仅全局(只能写在
globals或*块)、全局+虚拟主机(两处均可,主机级覆盖全局)、通用(几乎所有块内可用)。每条指令的实际允许作用域见下文分类清单。
三、配置查看与修改方式
3.1 配置文件与组织结构
Ferron 2.x 的配置文件(默认 /etc/ferron.kdl)由「顶层块」组成,块名即虚拟主机匹配器:
| 块名写法 | 含义 |
|---|---|
globals { ... } | 全局配置(不绑定任何虚拟主机,可放全局级指令) |
:80 { ... } | 匹配任意主机名的 80 端口请求 |
*:80 { ... } | 同上(显式通配写法) |
example.com { ... } | 匹配域名 example.com(443 端口隐含,自动 TLS 生效的前提写法) |
example.com:8080 { ... } | 匹配指定域名与端口 |
"192.168.1.1" { ... } | 按 IP 地址匹配(需加引号) |
location "/admin" { ... } | 主机块内的路径级配置(可嵌套) |
主机块内的 location 块、condition/if/if_not 条件块、snippet 片段与 include 拆分详见「十一、路由、URL 处理与访问控制参数」。
3.2 修改与热重载实测流程
标准修改流程:编辑 /etc/ferron.kdl → sudo systemctl reload ferron → journal 溯源确认 → curl 验证行为。实测(给 :80 块加一条响应头指令后重载):
:80 {
root "/var/www/ferron"
header "X-Test-Header" "ferron-reload-ok"
}
sudo systemctl reload ferron
journal 实测回显:
Oct 20 17:44:43 ferron-web systemd[1]: Reloading Ferron web server...
Oct 20 17:44:43 ferron-web ferron[4395]: Reloading the server configuration...
Oct 20 17:44:43 ferron-web systemd[1]: Reloaded Ferron web server.
验证生效(实测回显,新增头已出现):
curl -sI http://localhost/ | grep -iE "HTTP/|x-test|server:"
HTTP/1.1 200 OK
x-test-header: ferron-reload-ok
server: Ferron
热重载机制:systemd 单元中 ExecReload=kill -HUP $MAINPID,进程收到 SIGHUP 后原地重读配置,监听端口与进程 PID 均不变,适合反代后端不中断场景。
3.3 临时配置与免文件运行
不落盘验证配置用 --config-string 直接内联传入(实测,在 80 端口被占用时换 8088 冒烟测试):
ferron --config-string ':8088 { root "/opt/servetest" }'
HTTP server is listening on [::]:8088...
两个易踩的语义差异(均实测确认):
- 顶层未知指令:热重载时进程直接报
Invalid top-level directive退出,进入 systemd 重启循环(见「十四、常见问题」)。 - 主机块内未知指令:Ferron 2.8.1 静默忽略并正常启动——指令拼写错误不会导致服务失败,但也不会生效,排障时先核对拼写。
3.4 配置拆分与复用
include "/etc/ferron/sites/*.kdl":把站点配置拆分到独立文件(2.1.0+),主文件保持干净。snippet/use:定义可复用配置片段(2.6.0+ 支持跨 include 文件复用),如全局安全响应头只写一次。
四、参数总览(速查表)
高频指令速查(完整语义见后续各章;默认值为官方 2.8.1 文档口径):
| 指令 | 作用域 | 默认值 | 一句话说明 |
|---|---|---|---|
root | 通用 | 无 | 静态站点根目录 |
log / error_log | 全局+主机 | 无(不配置则不落盘) | 访问/错误日志文件路径 |
protocols | 仅全局 | "h1" "h2" | 启用的协议版本 |
timeout | 仅全局 | 300000(毫秒) | 单请求最大处理时长 |
listen_ip | 仅全局 | "::" | 监听 IP |
proxy | 通用 | 无 | 反向代理上游(可多条) |
lb_algorithm | 通用 | "two_random" | 负载均衡算法 |
cache | 通用 | #false | HTTP 缓存开关 |
limit | 通用 | #false | 限流开关(rate 25 rps) |
tls | 全局+主机 | 无 | 手工指定证书与私钥路径 |
auto_tls | 全局+主机 | 条件性 #true | 自动 TLS 开关 |
status | 通用 | 无 | 自定义状态码/认证/跳转/响应体 |
user | 通用 | 无 | Basic 认证用户与哈希 |
allow / block | 全局+主机 | 无 | IP 白/黑名单(CIDR) |
header / header_remove / header_replace | 通用 | 无 | 响应头增/删/改 |
error_page | 通用 | 无 | 自定义错误页 |
rewrite | 通用 | 无 | 正则 URL 重写 |
fcgi_php | 通用 | #null | PHP FastCGI 上游 |
directory_listing | 通用 | #false | 目录列表开关 |
etag | 通用 | #true | ETag 开关 |
💡 布尔语义约定:KDL 中开关型指令的裸写(如
directory_listing)等价于#true;#null多用于「恢复默认/禁用」。
五、HTTP 核心与网络参数
仅全局指令,写在 globals 或 * 块(官方《core directives》页口径):
| 指令 | 默认值 | 说明 |
|---|---|---|
default_http_port | 80 | 域名块隐含的 HTTP 端口;#null 禁用 |
default_https_port | 443 | 域名块隐含的 HTTPS 端口;#null 禁用 |
protocols | "h1" "h2" | 支持 "h1"/"h2"/"h3"(h3 为实验性) |
timeout | 300000 | 请求最大处理毫秒数,超时重置连接;不建议关闭(防 Slow HTTP 攻击) |
listen_ip | "::" | 监听地址,改 "0.0.0.0" 仅 IPv4 |
io_uring | #null(2.4.0+) | #null 表示自动回退(内核支持则启用);对 Tokio 构建无效 |
tcp_send_buffer / tcp_recv_buffer | 无 | TCP 收发缓冲字节数 |
protocol_proxy | #false | 接收 PROXY protocol(前置 LB 传真实 IP 时开启) |
buffer_request | #null | 请求缓冲字节数,可缓解 Slowloris 类攻击 |
buffer_response | #null | 响应缓冲字节数 |
h2_initial_window_size / h2_max_frame_size / h2_max_concurrent_streams / h2_max_header_list_size / h2_enable_connect_protocol | Hyper 默认 | HTTP/2 细调参数 |
六、日志与可观测参数
| 指令 | 作用域 | 默认值 | 说明 |
|---|---|---|---|
log <path> | 全局+主机 | 无 | 访问日志文件,默认 Combined Log Format(实测格式见下) |
error_log <path> | 全局+主机 | 无 | 错误日志文件 |
log_format | 全局 | Combined | 自定义占位符模板,占位符清单见本节末 |
log_date_format | 全局 | "%d/%b/%Y:%H:%M:%S %z" | 时间戳格式(POSIX) |
log_json | 全局 | 禁用(2.7.0+) | JSON 访问日志,启用后 log_format 失效 |
log_stdout / log_stderr | 全局 | #false(2.5.0+) | 访问日志输出到标准流 |
error_log_stdout / error_log_stderr | 全局 | #false(2.5.0+) | 错误日志输出到标准流 |
log_rotate_size / log_rotate_keep | 全局 | #null(禁用,2.6.0+) | 访问日志按大小轮转与保留份数 |
error_log_rotate_size / error_log_rotate_keep | 全局 | #null | 错误日志轮转 |
otlp_service_name | 全局 | "ferron" | OTLP 上报服务名 |
otlp_logs / otlp_metrics / otlp_traces | 全局 | #null protocol="grpc" | OpenTelemetry 三信号上报端点(grpc/http/protobuf/http/json) |
访问日志实测样例(默认 Combined 格式,::ffff: 前缀为 IPv4-mapped IPv6 表示):
::ffff:127.0.0.1 - - [20/Oct/2026:17:11:57 +0000] "GET / HTTP/1.1" 200 2411 "-" "curl/7.81.0"
可用占位符(官方 placeholders 参考页):{client_ip}、{auth_user}、{timestamp}、{method}、{path_and_query}、{version}、{status_code}、{content_length}、{header:Referer}、{header:User-Agent} 等。
七、静态文件与内容参数
| 指令 | 默认值 | 说明 |
|---|---|---|
root <path> | 无 | 站点根目录;#null 禁用静态服务 |
index | "index.html" "index.htm"(静态) | 目录请求的索引文件序列(FastCGI 场景默认含 index.php) |
etag | #true | ETag 响应头 |
compressed | #true | 静态文件动态压缩,算法优先级 zstd → br → gzip → deflate(2.8.0 起) |
precompressed | #false | 直出预压缩文件(.gz/.br/.zst/.deflate),配合 ferron-precompress 工具预生成 |
directory_listing | #false | 目录列表(生产建议保持关闭) |
mime_type <ext> <type> | 无 | 追加 MIME 映射 |
file_cache_control <value> | #null | 静态文件 Cache-Control 响应头 |
dynamic_compressed | #false | 动态内容(反代/FastCGI 响应)压缩 |
replace <a> <b> / replace_last_modified / replace_filter_types | text/html 过滤 | 响应体字符串替换(2.1.0+) |
预压缩实测:ferron-precompress /var/www/ferron 后站点目录出现成套压缩产物(实测清单节选):
index.html index.html.br index.html.deflate index.html.gz index.html.zst
favicon.ico favicon.ico.br favicon.ico.deflate favicon.ico.gz favicon.ico.zst
FunnelSans-Bold.woff2 FunnelSans-Bold.woff2.br FunnelSans-Bold.woff2.gz ...
八、缓存参数
HTTP 缓存模块(cache)参数(反代场景常用,静态文件本身有 file_cache_control 控制客户端缓存):
| 指令 | 默认值 | 说明 |
|---|---|---|
cache | #false | 缓存开关 |
cache_max_entries | 1024 | 缓存条目上限(#null 不限;键由方法+重写后 URL+Host+Vary 头构成) |
cache_max_response_size | 2097152(2 MB) | 可缓存的响应体大小上限 |
cache_vary | 无 | 参与缓存键区分的请求头 |
cache_ignore | 无 | 缓存时忽略的响应头 |
九、反向代理与负载均衡参数
核心是 proxy 指令,可写多条实现上游池:
:80 {
proxy "http://localhost:3000"
proxy "http://localhost:3001"
lb_algorithm "round_robin"
lb_health_check
}
| 指令 | 默认值 | 说明 |
|---|---|---|
proxy <url> | 无 | 上游地址(http/https/Unix socket unix= 属性);limit=/idle_timeout=(默认 60000ms)属性可限连接与空闲超时 |
lb_algorithm | "two_random" | 算法见下表 |
lb_health_check | #false | 被动健康检查开关 |
lb_health_check_max_fails | 3 | 连续失败次数阈值 |
lb_health_check_window | 5000 | 健康检查统计窗口(毫秒) |
lb_retry_connection | #true | 连接失败自动重试其他后端 |
proxy_keepalive | #true | 到后端保持连接 |
proxy_concurrent_conns | 16384(2.3.0+) | 到后端并发连接上限 |
proxy_no_verification | #false | 跳过后端 TLS 证书校验(自签场景) |
proxy_intercept_errors | #false | 拦截后端错误响应改由本机处理 |
proxy_request_header / proxy_request_header_remove / proxy_request_header_replace | 无 | 请求头增/删/改(值支持 {path} 等占位符) |
proxy_http2 | #false | 后端走 HTTP/2(需 https 上游) |
proxy_http2_only | #false | 仅 HTTP/2(gRPC 场景) |
proxy_proxy_header | #null | 向后端发送 PROXY protocol("v1"/"v2") |
proxy_srv <url> | 无 | 基于 DNS SRV 记录的动态上游(http://_http._tcp.example.com/) |
💡 技术拓展:
lb_algorithm四种负载均衡算法对比——
算法 调度策略 适用场景 random纯随机选取 后端性能同质、请求量均匀 round_robin依次轮转 后端性能同质、需要确定性分布 least_conn当前并发请求数最少者 请求处理耗时不均(长连接/WebSocket 混布) two_random(默认)随机取两个、选并发更少者(power of two choices) 通用默认,兼顾随机性与负载感知 默认
two_random是「随机 + 最少连接」的折中:无全局锁开销,负载倾斜概率远低于纯随机。
十、TLS 与安全参数
10.1 手工证书与协议级参数
| 指令 | 默认值 | 说明 |
|---|---|---|
tls <cert> <key> | 无 | 手工指定证书链与私钥路径 |
tls_min_version / tls_max_version | "TLSv1.2" / "TLSv1.3" | TLS 版本区间 |
tls_cipher_suite | Rustls 默认 | 套件白名单(启用 h3 时必须保留 TLS_AES_128_GCM_SHA256) |
tls_ecdh_curves | Rustls 默认 | ECDH 曲线 |
tls_client_certificate | #false | 客户端证书校验(mTLS;字符串值指定 CA 路径) |
ocsp_stapling | #true | OCSP 装订 |
trust_x_forwarded_for | #false | 信任上游 X-Forwarded-For(处于反代之后时开启) |
10.2 自动 TLS(ACME)参数
| 指令 | 默认值 | 说明 |
|---|---|---|
auto_tls | 条件性 #true | 块名为公网域名且端口未显式指定时自动开启 |
auto_tls_contact | #null | ACME 账户邮箱 |
auto_tls_challenge | "tls-alpn-01" | 质询方式:http-01/tls-alpn-01/dns-01 |
auto_tls_letsencrypt_production | #true | #false 切换 Let's Encrypt staging 环境 |
auto_tls_directory | 无 | 自定义 ACME 目录(覆盖上一条) |
auto_tls_cache | OS 用户数据目录(~/.local/share/ferron-acme) | ACME 数据缓存目录 |
auto_tls_on_demand | #false | 按需签发(首次访问时申请,务必配合下一条防滥用) |
auto_tls_on_demand_ask | #null | 按需签发白名单校验 URL(?domain= 参数回调) |
auto_tls_eab | #null | ACME External Account Binding |
auto_tls_save_data <cert> <key> | #null(2.5.0+) | 导出自动获取的证书与私钥 |
auto_tls_post_obtain_command | #null(2.5.0+) | 获证后回调命令(注入 FERRON_ACME_* 环境变量) |
💡 技术拓展:三种 ACME 质询方式对比——
质询 验证途径 前置条件 典型场景 http-0180 端口回读令牌 80 可从公网访问 常规网站 tls-alpn-01(默认)443 端口 TLS ALPN 握手 443 可从公网访问 只开 443 的站点 dns-01DNS TXT 记录 DNS API 凭据 通配符证书、内网源站、CDN 后源站
dns-01需以provider=<服务商>属性指定 DNS 服务商并配凭据(内置 Cloudflare、Route 53、bunny.net、deSEC、DigitalOcean、OVH、Porkbun 等 10+ 家)。
10.3 访问控制与限流参数
| 指令 | 默认值 | 说明 |
|---|---|---|
status <code> | 无 | 多功能状态码指令:realm=+users= 做 Basic 认证(401)、location= 做跳转、body= 自定义响应体、allowed=/not_allowed= 按 IP 生效、url=/regex= 按路径生效 |
user <name> <hash> | 无 | Basic 认证用户(哈希用 ferron-passwd 生成,Argon2/PBKDF2/scrypt) |
allow / block | 无 | IP/CIDR 白名单与黑名单(可多条) |
abort | #false(2.6.0+) | 直接断开连接不回包 |
limit | #false | 限流:rate= 平均速率(默认 25 rps)、burst= 峰值(默认 4 倍 rate) |
Basic 认证实测配置(生成哈希与生效验证):
:80 {
root "/var/www/ferron"
status 401 realm="Restricted Area" users="admin"
user "admin" "$argon2id$v=19$m=19456,t=2,p=1$..."
}
实测三态:无凭据 401;curl -u admin:<密码> 200;错误凭据 401,错误日志出现 Authorization failed for user "admin" and client "::ffff:127.0.0.1"。
十一、路由、URL 处理与访问控制参数
| 指令 | 默认值 | 说明 |
|---|---|---|
header / header_remove / header_replace | 无 | 响应头增/删/改(值支持 {path} 占位符;实测见 3.2) |
error_page <code> <path> | 无 | 自定义错误页 |
server_administrator_email | 无 | 默认 500 页展示的管理员邮箱 |
rewrite <regex> <replacement> | 无 | 正则重写;directory=/file=/last=/allow_double_slashes= 属性 |
rewrite_log | #false | 重写行为写入错误日志(排障利器) |
wwwredirect | #false | 裸域跳 www |
no_redirect_to_https | #false | 关闭 HTTP→HTTPS 强制跳转(块端口显式指定时恒为 true) |
no_trailing_redirect | #false | 关闭目录尾斜杠跳转 |
allow_double_slashes | #false | 允许 URL 双斜杠 |
disable_url_sanitizer | #false | 关闭 URL 清洗(有路径穿越风险,仅特殊应用需要) |
结构块(组合指令实现精细化路由):
example.com {
location "/api" {
proxy "http://localhost:3000"
}
location "/static" {
root "/var/www/assets"
}
condition "is_admin_ip" {
is_remote_ip "10.0.0.0/8"
}
if_not "is_admin_ip" {
status 403 body="Forbidden"
}
}
condition "<名>" { ... }:命名条件块,内部放is_remote_ip/is_forwarded_for/is_equal/is_regex/is_not_*/is_rego(OpenPolicyAgent Rego 策略)/is_language等判定指令。if "<名>" { ... }/if_not "<名>" { ... }:条件通过/不通过时生效的指令组。set_constant <k> <v>:定义配置内常量(2.1.0+)。
十二、应用后端参数(CGI/SCGI/FastCGI)
| 指令 | 默认值 | 说明 |
|---|---|---|
fcgi_php <url> | #null | PHP FastCGI(仅 .php 请求转发),TCP(tcp://localhost:9000/)或 Unix socket(unix:///run/php/php-fpm.sock) |
fcgi <url> | #null pass=#true | 通用 FastCGI 上游,pass=#false 时仅作为 location 命中处理 |
fcgi_extension / fcgi_environment | 无 | FastCGI 处理的扩展名与环境变量 |
scgi <url> | #null | SCGI 上游 + scgi_environment |
cgi | #false | CGI 处理开关 |
cgi_extension / cgi_interpreter / cgi_environment | 内置解释器映射 | CGI 脚本扩展名、解释器(.pl/.py/.sh/.rb/.php 等已预置)与环境变量 |
十三、生产配置模板
13.1 模板一:静态站点(资源需求:内存 ~6 MB / 磁盘 <100 MB)
globals {
log "/var/log/ferron/access.log"
error_log "/var/log/ferron/error.log"
log_rotate_size 10485760
log_rotate_keep 7
}
example.com {
root "/var/www/site"
precompressed
file_cache_control "public, max-age=3600"
header "X-Content-Type-Options" "nosniff"
header "X-Frame-Options" "DENY"
header "Referrer-Policy" "strict-origin-when-cross-origin"
error_page 404 "/404.html"
}
适用:文档站、博客、下载站。precompressed 配合 ferron-precompress 预生成 .zst/.br/.gz 省运行时 CPU。
13.2 模板二:反向代理 + 缓存 + 限流(资源需求:内存 ~10-20 MB / 磁盘视缓存条目而定)
globals {
log "/var/log/ferron/access.log"
error_log "/var/log/ferron/error.log"
buffer_request 65536
}
app.example.com {
proxy "http://10.0.0.11:3000"
proxy "http://10.0.0.12:3000"
lb_algorithm "least_conn"
lb_health_check
cache
cache_max_entries 4096
cache_max_response_size 1048576
limit rate=100 burst=400
proxy_request_header_replace "X-Real-IP" "{client_ip}"
}
适用:为多个内网服务做统一 TLS 网关与流量防护。
13.3 模板三:PHP 站点(资源需求:内存 ~6 MB + PHP-FPM 自身开销 / 磁盘 <100 MB)
blog.example.com {
root "/var/www/wordpress"
fcgi_php "unix:///run/php/php-fpm.sock"
index "index.php" "index.html"
}
适用:WordPress 等 PHP 应用。前置条件:PHP-FPM 池监听套接字的属主需改为 ferron 用户(listen.owner = ferron、listen.group = ferron),否则报 503(官方默认配置内注释亦提示此点)。
十四、常见问题(FAQ)
14.1 改了配置不生效或重载失败
先分层排查(均实测复现):
sudo systemctl reload ferron后 journal 出现Reloading the server configuration...即重载已触发;未出现则服务本体已挂,systemctl status ferron看真相。- 顶层未知指令重载时报
Error while running a server: Invalid top-level directive at "/etc/ferron.kdl",进程退出并触发Restart=on-failure重启循环;修复配置后需sudo systemctl reset-failed ferron && sudo systemctl start ferron(失败计数不清除时直接 start 会报Job for ferron.service failed)。 - KDL 语法错误(如缺闭合花括号)前台运行会给出带行号的 miette 诊断:
Failed to parse KDL document ... No closing '}' for child block。 - 主机块内未知指令被静默忽略(如误写
bad_directive "x"服务照常启动)——「改了没生效」先查拼写。
14.2 Basic 认证哈希导致解析错误
ferron-passwd 生成的哈希粘入 user 指令时夹带换行/回车,实测报 Unexpected newline in single-line quoted string(miette 定位到行:列)。确保哈希单行粘贴且无尾随空白。认证生效判据:无凭据/错误凭据 401、正确凭据 200,错误日志含 Authorization failed for user。
14.3 端口冲突
Error while running a server: Cannot listen to HTTP port: Address already in use (os error 98):80/443 被占用。sudo ss -ltnp | grep :80 定位占用者;或用 :8080 形式块名换端口(注意:块名显式写端口后,auto_tls 默认逻辑关闭,需手工 tls 指令或 default_https_port 调整)。
14.4 域名块开了但 443 不通/证书没签下来
- 域名 DNS 未指向本机或 80/443 未对公网开放(云安全组/防火墙);
auto_tls_challenge与可达端口不匹配(只开 80 用http-01,只开 443 用默认tls-alpn-01,内网/通配符用dns-01);- 调试期可
auto_tls_letsencrypt_production #false切 staging 环境规避限频。
十五、参考链接
- 官方配置文档(2.x 世代):https://ferron.sh/docs(配置语法与指令参考)
- 配置基础页:https://www.ferronweb.org/docs/configuration/fundamentals/syntax
- Ferron 2.8.1 源码内配置文档(与二进制同源):https://github.com/ferronweb/ferron/tree/2.8.1/docs
- DNS-01 服务商对接与凭据:官方文档 Automatic TLS 章节
- 本平台关联文档:《Ubuntu 22.04 安装 Ferron 指南》、《Ferron 介绍与选型指南》、《Ferron 2.8.1 常用 CLI 命令详解》