FOSSBilling 0.8.8 配置参数详解
FOSSBilling 0.8.8 配置参数详解:config.php 全部 15 个顶层配置段逐项实测讲解(security/debug/db/cache/twig/api/rate_limiter 等)、限流器 30 条默认策略源码级清单、数据库 setting 表 36 项系统参数、i18n 中文语言包排障实录(系统 locale 与 auto_detect_locale 双因素)、维护模式与缓存属主实测、生产配置模板。
FOSSBilling 0.8.8 配置参数详解
目标:系统讲透 FOSSBilling 0.8.8 的配置体系——文件侧
config.php全部 15 个顶层配置段的逐项含义与实测验证、数据库侧setting表系统参数、限流器默认策略的源码级清单,并把修改参数过程中的真实排障实录(中文语言包、维护模式、缓存属主)沉淀成可直接照做的结论。本文全部配置与命令回显均来自一台 Ubuntu 22.04 实测服务器(实测日期 2026-10-23),安装过程见《Ubuntu 22.04 安装 FOSSBilling 0.8.8 指南》。
一、环境信息
本文所有命令在以下环境中实测执行(与安装篇同一台服务器):
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| 主机名 | billing-server |
| Web 服务 | Apache/2.4.52,监听 8148 端口 |
| PHP | 8.3.36(cli,NTS,via ppa:ondrej/php) |
| 数据库 | 11.4.13-MariaDB |
| FOSSBilling | 0.8.8(官方发行包,安装于 /var/www/html) |
| 站点地址 | http://192.168.1.62:8148/ |
| 管理区前缀 | /admin(管理员 admin / Q1w2e3r4) |
版本核验回显:
$ php /var/www/html/console.php system:version
FOSSBilling 0.8.8
$ mariadb --version
mariadb from 11.4.13-MariaDB, client 15.2 for debian-linux-gnu (x86_64) using EditLine wrapper
二、前置条件
- 已按《Ubuntu 22.04 安装 FOSSBilling 0.8.8 指南》完成 0.8.8 安装,管理区可正常登录(本篇不含安装步骤)。
- 服务器具备 sudo/root 权限,可编辑
/var/www/html/config.php与执行数据库查询。 - 涉及中文语言包实验时需可执行
locale-gen(locales 软件包,Ubuntu 22.04 默认已装)。 - FOSSBilling 的软件定位、架构与模块全景见《FOSSBilling 0.8.8 介绍与选型指南》,本篇专注运行期配置。
三、参数查看与修改方式
FOSSBilling 的配置分散在「文件 + 数据库」两层:安装级参数在 config.php,业务运营参数在数据库 setting 表(由管理后台读写)。动手改参数前,先弄清每类参数住在哪、改了之后怎么生效。
3.1 配置承载位置全景
ls -F /var/www/html/ | head -22
实测回显(安装完成后根目录,config.php 由安装向导生成):
LICENSE
README.md
config-sample.php
config.php
console.php
cron.php
data/
di.php
index.php
ipn.php
library/
load.php
locale/
modules/
public/
rewrite-missing.html
robots.txt
themes/
vendor/
各承载位置的分工:
| 位置 | 承载内容 | 修改方式 | 生效方式 |
|---|---|---|---|
| /var/www/html/config.php | 安装级参数:数据库、安全、缓存、i18n、限流等 | 直接编辑 PHP 数组 | 下次请求即读取(个别场景需清缓存,见 8.3) |
| /var/www/html/config-sample.php | 官方带注释样例(新装手工部署时复制改名用) | 只读参考 | — |
| 数据库 fossbilling.setting 表 | 运营参数:公司信息、发票系列、主题等 36 项 | 管理后台 System 设置页(或 SQL) | 立即(读库) |
| /var/www/html/data/ | 运行时数据:缓存、日志、上传物 | 由 path_data 指定 | — |
| /var/www/html/.htaccess | Apache 重写规则(/admin 路由前提) | 直接编辑 | 下次请求 |
| /etc/php/8.3/apache2/php.ini | PHP 运行时:upload_max_filesize 等 | 直接编辑 + 重启 Apache | 重启后 |
| www-data 的 crontab | cron.php 调度 | crontab -u www-data -e | 下个周期 |
💡 说明:
data/目录下还有一层「文件型配置」——主题配置themes/<主题>/config/settings_data.json与邮件模板(存于email_template表、由模块同步文件模板),属于业务自定义范畴,本篇不展开。
3.2 修改 config.php 并验证生效
config.php 是一个返回 PHP 数组的纯文件,修改即保存。以「开启维护模式」为例演示完整的「改 → 验证 → 还原」闭环:
# 将 maintenance_mode.enabled 改为 true
sed -i "s@'enabled' => false,@'enabled' => true,@" /var/www/html/config.php
grep -A2 maintenance_mode /var/www/html/config.php | head -4
实测回显:
'maintenance_mode' =>
array (
'enabled' => true,
验证前台被拦、管理区不受影响:
curl -s -o /dev/null -w "front=%{http_code}\n" http://127.0.0.1:8148/
curl -s -o /dev/null -w "admin=%{http_code}\n" http://127.0.0.1:8148/admin/staff/login
实测回显:
front=503
admin=200
💡 结论:config.php 修改保存后下次请求立即生效(上例未清缓存前台即 503)。但还原参数时实测出现过前台仍 503 的残留(缓存了 503 响应),执行一次缓存清理后恢复 200,见 8.3 排障实录。
清理缓存的正确姿势——必须以 www-data 身份执行,否则缓存目录属主会变成 root,直接把整站干成 500(见 8.2):
sudo -u www-data php /var/www/html/console.php cache:clear
实测回显:
Successfully cleared the cache.
3.3 修改数据库内系统设置
运营参数存于 setting 表,共 36 项(安装后实测),正常途径是通过管理后台 System 设置页修改,效果等同直接写表:
mariadb -uroot -p fossbilling -N -e "SELECT COUNT(*) FROM setting;"
实测回显:
36
36 项参数全量清单(实测导出,长值截断显示):
company_address_1 Demo address line 1
company_address_2 Demo address line 2
company_address_3 Demo address line 3
company_email support@yourcompany.com
company_favicon public/branding/favicon.ico
company_logo public/branding/logo.svg
company_logo_dark public/branding/logo-dark.svg
company_name Company Name
company_note This is a placeholder for your About Us page. It will be ava
company_privacy_policy This is a sample Privacy Policy. Please replace this with yo
company_signature FOSSBilling.org - Client Management, Invoicing and Support S
company_tel +123 456 12345
company_tos This is a sample Terms of Service. Please replace this with
funds_max_amount 200
funds_min_amount 10
hide_company_public 1
invoice_auto_approval 1
invoice_cn_series CN-
invoice_cn_starting_number 1
invoice_due_days 5
invoice_hash_lifetime_days 90
invoice_issue_days_before_expire 14
invoice_overdue_invoked 2026-10-23 06:01:39
invoice_refund_logic credit_note
invoice_series FOSS
invoice_starting_number 1
issue_invoice_days_before_expire 7
last_cron_exec 2026-10-23 13:35:02
last_error_reporting_nudge 0.8.8
last_patch 118
nameserver_1 NULL
nameserver_2 NULL
nameserver_3 NULL
nameserver_4 NULL
servicedomain_last_sync 2026-10-23 05:56:00
theme huraga
分类解读:
- company_*(12 项):公司名称、联系方式、Logo/图标路径、隐私政策与服务条款文本,出现在发票 PDF、邮件签名与客户区页脚;
hide_company_public=1时前台隐藏公司信息。 - invoice_*(10 项):发票编号前缀与起始号(
invoice_series=FOSS、invoice_cn_series=CN-供贷记单使用)、到期天数invoice_due_days=5、临期自动出票天数、逾期标记时间戳、退款逻辑invoice_refund_logic=credit_note(贷记单模式)。 - funds_*(2 项):客户账户余额充值的单笔下限 10 / 上限 200。
- theme:客户区主题,默认
huraga;管理区主题固定 admin_default,不在此表。 - nameserver_1~4:域名服务类产品对外展示的 NS 地址,默认空。
- last_* / *_last_sync(4 项):系统运行状态记录(最近 cron 执行时间、最近补丁号 118 等),由系统自动回写,无需手工改。
四、参数总览
config.php 共 15 个顶层键,实测安装向导生成的完整文件如下(服务器上为真实生产值,数据库密码即安装篇所设 q1w2e3r4):
<?php
return array (
'security' =>
array (
'mode' => 'strict',
'force_https' => false,
'trusted_proxies' =>
array (
'enabled' => false,
'proxies' =>
array (
),
'headers' => 'x_forwarded',
),
'session_lifespan' => 7200,
'session_regeneration_grace_period' => 300,
'perform_session_fingerprinting' => true,
'debug_fingerprint' => false,
),
'debug_and_monitoring' =>
array (
'debug' => false,
'log_stacktrace' => true,
'stacktrace_length' => 25,
'report_errors' => true,
),
'info' =>
array (
'salt' => '91499a121840efb7b9966bb8e559ba6f',
'instance_id' => '5bfa4e49-331f-472d-925c-001452d82a86',
),
'url' => '192.168.1.62:8148/',
'admin_area_prefix' => '/admin',
'update_branch' => 'release',
'maintenance_mode' =>
array (
'enabled' => false,
'allowed_urls' =>
array (
),
'allowed_ips' =>
array (
),
),
'disable_auto_cron' => true,
'i18n' =>
array (
'locale' => 'en_US',
'auto_detect_locale' => true,
'timezone' => 'UTC',
'date_format' => 'medium',
'time_format' => 'short',
'datetime_pattern' => '',
),
'path_data' => '/var/www/html/data',
'db' =>
array (
'driver' => 'pdo_mysql',
'host' => 'localhost',
'port' => 3306,
'name' => 'fossbilling',
'user' => 'fossbilling',
'password' => 'q1w2e3r4',
),
'cache' =>
array (
'driver' => 'filesystem',
'redis' =>
array (
'host' => '127.0.0.1',
'port' => 6379,
'password' => NULL,
'database' => 0,
'tls' =>
array (
'enabled' => false,
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => NULL,
'allow_self_signed' => false,
),
),
'memcached' =>
array (
'host' => '127.0.0.1',
'port' => 11211,
),
),
'twig' =>
array (
'debug' => false,
'auto_reload' => true,
'cache' => '/var/www/html/data/cache',
'strict_variables' => true,
),
'api' =>
array (
'require_referrer_header' => false,
'allowed_ips' =>
array (
),
'CSRFPrevention' => true,
),
'rate_limiter' =>
array (
'enabled' => true,
'whitelist_ips' =>
array (
),
'policies' =>
array (
),
),
);
15 个顶层键总览(默认值取自官方样例 config-sample.php 与源码默认):
| 顶层键 | 作用 | 默认值 | 详解小节 |
|---|---|---|---|
| security | 会话安全、HTTPS、信任代理 | mode=strict,force_https=true | 5.1 |
| debug_and_monitoring | 调试输出、堆栈、错误上报 | debug=false | 5.2 |
| info | 实例盐值与实例 ID | 安装时随机生成 | 5.3 |
| url | 站点对外地址(带尾斜杠) | localhost/ | 5.4 |
| admin_area_prefix | 管理区路由前缀 | /admin | 5.4 |
| update_branch | 自动更新分支 | release | 5.5 |
| maintenance_mode | 维护模式开关与白名单 | enabled=false | 5.5 |
| disable_auto_cron | 关闭登录兜底触发 cron | true | 5.6 |
| i18n | 语言、时区、日期格式 | locale=en_US,timezone=UTC | 5.7 |
| path_data | 敏感数据目录 | DIR.'/data' | 5.8 |
| db | 数据库连接 | pdo_mysql/127.0.0.1 | 5.9 |
| cache | 应用缓存后端 | filesystem | 5.10 |
| twig | 模板引擎行为 | cache=data/cache | 5.11 |
| api | API 访问控制 | CSRFPrevention=true | 5.12 |
| rate_limiter | 限流器与策略 | enabled=true | 5.13 |
💡 说明:对比安装向导产物与官方样例,有三处差异——
force_https(样例 true,本机 HTTP 安装为 false)、report_errors(样例 false,安装向导错误上报选「关闭」时本机实际落盘 true)、url(样例 localhost/,本机为实际访问地址)。数据库连接五项则由向导按填写值生成。
五、核心参数分类详解
5.1 security:安全与会话
本段控制会话 Cookie 行为、HTTPS 强制与反向代理信任,直接决定登录态安全。
'security' => [
'mode' => 'strict',
'force_https' => true,
'trusted_proxies' => [
'enabled' => false,
'proxies' => [],
'headers' => 'x_forwarded',
],
'session_lifespan' => 7200,
'session_regeneration_grace_period' => 300,
'perform_session_fingerprinting' => true,
'debug_fingerprint' => false,
],
逐项说明:
- mode:取值
strict时,会话 Cookie 追加SameSite=Strict;其他任何值均不追加该属性。源码判据(library/FOSSBilling/Session.php 第 65 行)为if (Config::getProperty('security.mode', 'strict') === 'strict') { $cookieParams['samesite'] = 'Strict'; }。本机实测响应头可验证:Set-Cookie: fossbilling_session=...; path=/; HttpOnly; SameSite=Strict。 - force_https:为 true 时强制按 HTTPS 处理(会话 Cookie 加 Secure 标记,判定逻辑
force_https || request->isSecure())。本机为 HTTP 安装故为 false;生产上 TLS 就绪后必须改回 true。 - trusted_proxies:HTTPS 在反代终结时的信任配置——
enabled总开关、proxies信任的代理 IP 列表、headers取真实 IP 的头(x_forwarded)。仅在「请求确实经过你可控的代理」时开启,否则真实 IP 会被伪造,限流与审计全部失真。 - session_lifespan:会话有效期,秒;默认 7200(2 小时),超期会话在下次请求时被清理。
- session_regeneration_grace_period:会话 ID 重生成的宽限期,秒;默认 300。重生成后旧 ID 在宽限期内仍可用,避免并发请求被踢下线。
- perform_session_fingerprinting:会话指纹校验(绑定 UA/IP 属性),默认 true;换网络环境会掉线,属正常安全行为。
- debug_fingerprint:指纹调试开关,默认 false,排障指纹误杀时临时打开。
5.2 debug_and_monitoring:调试与错误上报
'debug_and_monitoring' => [
'debug' => false,
'log_stacktrace' => true,
'stacktrace_length' => 25,
'report_errors' => false,
],
逐项说明:
- debug:高级调试信息开关。官方注释明确要求:非测试场景保持关闭,否则会向访客暴露服务器信息。排查白屏/500 时临时改 true,页面上会带出详细错误。
- log_stacktrace:异常时记录堆栈(官方注释注明同时要求 debug 开启才生效);默认 true。
- stacktrace_length:堆栈帧数上限,默认 25。
- report_errors:匿名错误/稳定性/性能上报(经 Sentry.io,官方注释声明发送前会脱敏)。样例默认 false;安装向导勾选错误上报时落盘 true。不上报不影响任何功能,只影响社区收集问题的能力。
排障相关的落盘位置在 path_data 之下,data/log/ 目录实测结构:
$ ls /var/www/html/data/log/
application
cron
event
index.html
php_error.log
routing
php_error.log 实测节选(可以看到 debug 关闭时错误仍会落文件,只不展示到页面):
[23-Oct-2026 06:08:56 UTC] The template cache directory could not be written to. Please check the file permissions and available disk space for the "data/cache" directory. at /var/www/html/library/Box/App.php : 250
[23-Oct-2026 06:25:22 UTC] There was an error while updating the IP address database: Failed to connect to github.com port 443 after 21044 ms: Connection refused for "https://github.com/HostByBelle/IP-Geolocation-DB/releases/latest/download/pddl-asn-both.mmdb"..
5.3 info:实例盐值与实例 ID
'info' => [
'salt' => bin2hex(random_bytes(16)),
'instance_id' => 'XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX',
],
- salt:32 位十六进制随机盐,安装时生成(本机实测
91499a121840efb7b9966bb8e559ba6f)。用于安全相关的哈希场景,装好后不要更改,否则既有依赖盐值的校验数据失效。 - instance_id:实例唯一标识(UUID 风格),用于版本信息上报等场景区分实例,同样不要手工改动。
5.4 站点地址与管理区前缀(url / admin_area_prefix)
'url' => 'localhost/',
'admin_area_prefix' => '/admin',
- url:站点对外完整地址,必须带尾斜杠。安装向导按你填的 system_url 生成(本机
192.168.1.62:8148/)。站点换域名/上 HTTPS 后第一件事就是改它;实测中它还参与请求来源校验——php_error.log 里的Invalid request. Make sure request origin is http://192.168.1.62:8148/ 1004.即为来源与 url 不符时的拦截记录。 - admin_area_prefix:管理区路由前缀,默认
/admin,即管理区入口https://站点/admin。改值后管理区入口随之改变(如/manage),适合隐藏常规扫描路径;客户区不受影响。
5.5 update_branch 与 maintenance_mode
'update_branch' => 'release',
'maintenance_mode' => [
'enabled' => false,
'allowed_urls' => [],
'allowed_ips' => [],
],
- update_branch:自动更新跟踪分支,可选
release(稳定版)或preview(预览版);生产保持 release。 - maintenance_mode.enabled:维护模式。开启后拦截前台与 API,但不拦管理区。实测验证:
# enabled=true 时
curl -s -o /dev/null -w "front=%{http_code}\n" http://127.0.0.1:8148/
curl -s -o /dev/null -w "admin=%{http_code}\n" http://127.0.0.1:8148/admin/staff/login
实测回显:
front=503
admin=200
- allowed_urls:维护期间放行的 URL 白名单,支持通配(官方注释示例
'/api/guest/staff/*')——例如支付回调地址需要放行,否则维护期间收款 IPN 会失败。 - allowed_ips:放行的 IP/网段白名单,格式
127.0.0.1、127.0.0.1/32。
5.6 disable_auto_cron:周期任务触发方式
'disable_auto_cron' => true,
FOSSBilling 的业务时钟是 cron.php(出账、催款、服务挂起/终止),触发方式有两路:系统 crontab 定时(推荐)与「管理员登录后台时若太久没跑就补跑一次」的兜底(auto cron)。
disable_auto_cron = true:关闭登录兜底,只认系统 crontab——本机安装后即为该值(安装完成页同时给出了 crontab 配置指引,已配置*/5 * * * * php /var/www/html/cron.php)。false:允许登录后台兜底触发。没有系统 crontab 的极简环境可暂时靠它,但出账时点不可控,生产一律配系统 cron 并保持 true。
cron 执行结果可从两处核实:setting.last_cron_exec(实测 2026-10-23 13:35:02)与 data/log/cron/ 按日滚动的日志:
$ tail -2 /var/www/html/data/log/cron/cron-2026-10-23.log
[23-Oct-2026 06:04:11 UTC] cron.INFO: Executed action to try cover unpaid invoices with client credits.
[23-Oct-2026 06:04:11 UTC] cron.INFO: Executed action to activate paid invoices.
cron 相关的命令行入口(console.php 实测命令清单,共 6 条业务子命令):
cache
cache:clear Clears the cache
cron
cron:run Executes the cron jobs
system
system:releasenotes Returns the release notes of all newer versions of FOSSBilling
system:run-patcher Runs update patches and config migrations
system:version Returns the current version of FOSSBilling
theme
theme:list Returns the list of the installed themes
5.7 i18n:多语言与时区(含中文语言包排障实录)
'i18n' => [
'locale' => 'en_US',
'auto_detect_locale' => true,
'timezone' => 'UTC',
'date_format' => 'medium',
'time_format' => 'short',
'datetime_pattern' => '',
],
逐项说明:
- locale:默认语言代码,0.8.8 发行包内置全部语言包(实测
ls /var/www/html/locale/含zh_CN、zh_TW、de_DE等,中文包为locale/zh_CN/LC_MESSAGES/messages.mo,约 103 KiB)。 - auto_detect_locale:按浏览器
Accept-Language头自动选语言。注意实测结论:开启时无语言头的请求(curl、部分 API 客户端)会落到英文,见下方排障实录。 - timezone:系统默认时区(IANA 名称,如
Asia/Shanghai);渲染时按「客户 → 管理员 → Cookie → 此配置 → UTC」的优先级解析。 - date_format / time_format:
none/short/medium/long四档(对应 PHP IntlDateFormatter 档位)。 - datetime_pattern:显式 ICU 日期时间模式,非空时覆盖上面两档。
排障实录:把 locale 改成 zh_CN 后界面还是英文
- 现象一:改完 locale 页面整体无翻译。 将
'locale' => 'en_US'改为'zh_CN'后,/login页标题仍是Login。 - 定位:FOSSBilling 走 PHP gettext 体系加载
.mo语言包,gettext 依赖操作系统层面已生成对应 locale。实测服务器locale -a只有C / C.utf8 / POSIX,没有 zh_CN:$ locale -a C C.utf8 POSIX - 解决:生成系统 locale 并重启 Apache:
生成后
apt-get install -y locales sed -i 's/^# *zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen locale-gen apache2ctl -k restartlocale -a | grep zh实测出现zh_CN.utf8,再访问/login标题变为登录。 - 现象二:生成 locale 后,浏览器带中文语言的会话已汉化,但 curl 不带头仍英文。 源因是
auto_detect_locale=true时优先读Accept-Language,无语言头的请求被 PHPLocale::acceptFromHttp归一化成en_US,i18n.locale兜底几乎不触发。解决:要求服务端强制默认中文时,把auto_detect_locale改为false,实测同一 curl 命令立即返回<title>登录</title>;浏览器用户自选语言的能力不受影响(可手动切换)。
5.8 path_data:数据目录
'path_data' => __DIR__.'/data',
存放缓存、日志、上传物等运行时数据的目录,默认随安装目录走(本机 /var/www/html/data,安装向导生成为绝对路径)。实测目录结构:
$ ls -la /var/www/html/data/
total 32
drwxr-x--- 5 www-data www-data 4096 Oct 23 06:04 .
drwxr-xr-x 9 www-data www-data 4096 Oct 23 06:20 ..
-rw-r--r-- 1 www-data www-data 73 Oct 3 05:41 .htaccess
drwxr-xr-x 19 www-data www-data 4096 Oct 23 06:09 cache
-rw-r--r-- 1 www-data www-data 1 Oct 3 05:41 index.html
drwxr-xr-x 6 www-data www-data 4096 Oct 23 05:56 log
-rw-r--r-- 1 www-data www-data 208 Oct 23 05:34 update-finalization.json
drwxr-xr-x 2 www-data www-data 4096 Oct 23 05:41 uploads
要点:目录内置 .htaccess 拒绝直接 Web 访问;属主必须是 Web 运行用户 www-data(排障见 8.2);如需迁移到大盘位(如 /data/fossbilling-data),改此键后把原目录内容迁移并保持属主即可。
5.9 db:数据库连接
'db' => [
'driver' => 'pdo_mysql',
'host' => getenv('DB_HOST') ?: '127.0.0.1',
'name' => getenv('DB_NAME') ?: 'fossbilling',
'user' => getenv('DB_USER') ?: 'foo',
'password' => getenv('DB_PASS') ?: 'bar',
'port' => getenv('DB_PORT') ?: '3306',
],
- driver:固定
pdo_mysql(MariaDB/MySQL 共用 PDO MySQL 驱动),不要改。 - host / port:数据库地址与端口;样例支持从环境变量
DB_HOST等读取(手工部署与自动化编排友好),安装向导产物直接落死值(本机localhost:3306)。 - name / user / password:库、账号、密码。账号所需最小权限实测结论(安装篇 9.2 节踩坑):常规增删改查 + DDL 之外,必须含 LOCK TABLES 与 CREATE VIEW,否则安装或升级会 1044 报错。
- 库本身要求 utf8mb4 字符集(安装篇以
CREATE DATABASE fossbilling CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci创建)。
连接与表规模核验:
mariadb -uroot -p -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='fossbilling';"
实测回显:
60
5.10 cache:缓存后端
本段配置应用层缓存(通用缓存、限流器计数、Doctrine ORM 元数据/查询/结果缓存),与 5.11 的 Twig 模板缓存是两回事。
'cache' => [
'driver' => 'filesystem',
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'password' => null,
'database' => 0,
'tls' => [
'enabled' => false,
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => null,
'allow_self_signed' => false,
],
],
'memcached' => [
'host' => '127.0.0.1',
'port' => 11211,
],
],
- driver:
filesystem(默认)/redis/memcached三选一;官方注释注明 redis 需 PHP redis(或 relay)扩展、memcached 需 PHP memcached 扩展,且可从管理后台 System > Settings > Cache 切换。 - redis.*:host/port/password/database,外加 tls 子组——官方注释明确:设置了密码且 host 非回环地址(127.0.0.1/::1/localhost)时必须启用 TLS(
rediss://),verify_peer/verify_peer_name保持 true,自签证书仅限测试环境用allow_self_signed。 - memcached.*:host/port 两项。
💡 技术拓展:应用缓存后端不止 filesystem 一种,三者横向对比——
后端 原理/特点 适用场景 filesystem 落盘到 data/cache,零外部依赖 单机默认,小中型实例 Redis 内存键值存储,支持 TLS/认证,读写快 多实例共享缓存、高并发读写 Memcached 纯内存键值,多线程,协议简单 大规模简单键值、已有 Memcached 基础设施 (数据库) 无独立缓存层 不推荐,徒增数据库压力 FOSSBilling 默认 filesystem,单机部署无性能瓶颈时不必引入额外组件;本方案即保持默认。
5.11 twig:模板引擎
'twig' => [
'debug' => false,
'auto_reload' => true,
'cache' => __DIR__.'/data/cache',
'strict_variables' => true,
],
- debug:Twig 调试模式(模板内 dump() 等调试能力),生产关闭。
- auto_reload:模板文件变更后自动重新编译,默认 true——改主题文件无需手动清缓存。
- cache:Twig 编译产物目录,默认落在 data/cache;该目录不可写时整站 500(php_error.log 出现
The template cache directory could not be written to ... "data/cache",见 8.2)。 - strict_variables:模板引用未定义变量时抛错而不是静默输出空值,默认 true,便于发现主题缺陷;自定义主题开发时若被大量报错困扰可临时关闭。
5.12 api:API 访问控制
'api' => [
'require_referrer_header' => false,
'allowed_ips' => [],
'CSRFPrevention' => true,
],
- require_referrer_header:要求 API 请求携带与本站 URL 一致的 Referer 头,默认 false。开启会挡掉不带 Referer 的常规 API 客户端(curl/SDK),仅在与后台管理页同源调用场景有意义。
- allowed_ips:API 访问 IP 白名单,空数组不限制;对外暴露 API 的生产实例建议收窄到已知调用方。
- CSRFPrevention:CSRF 令牌防护开关,官方注释强烈警告不要关闭(等同打开已知漏洞)。实测 php_error.log 中的
CSRF token invalid 403.即该机制的拦截记录。
5.13 rate_limiter:限流器与默认策略
'rate_limiter' => [
'enabled' => true,
'whitelist_ips' => [],
'policies' => [
// 'client_signup' => ['policy' => 'fixed_window', 'limit' => 5, 'interval' => '1 hour'],
],
],
- enabled:限流总开关,默认 true。
- whitelist_ips:白名单 IP 完全绕过限流(官方注释场景:固定 IP 的对账程序高频调 API)。
- policies:策略覆盖表,留空 = 使用源码内置默认;键为策略名,值为
{policy, limit, interval},可只覆盖需要调整的项。
30 条内置默认策略全清单(实读 0.8.8 源码 library/FOSSBilling/Security/RateLimiter.php 的 getDefaultConfig(),逐行照抄):
| 策略名 | 算法 | 上限 | 窗口 |
|---|---|---|---|
| api_guest | token_bucket | 100 | 60 seconds |
| api_authenticated_ip | token_bucket | 1000 | 1 hour |
| api_authenticated_account | token_bucket | 1000 | 1 hour |
| api_login | fixed_window | 10 | 1 hour |
| client_password_reset_ip | fixed_window | 10 | 1 hour |
| client_password_reset_email | fixed_window | 3 | 1 hour |
| client_password_reset_confirm_ip | fixed_window | 20 | 60 seconds |
| client_password_reset_confirm_post_ip | fixed_window | 20 | 60 seconds |
| client_email_confirm_ip | fixed_window | 20 | 60 seconds |
| staff_password_reset_ip | fixed_window | 5 | 1 hour |
| staff_password_reset_email | fixed_window | 3 | 1 hour |
| staff_password_reset_confirm_ip | fixed_window | 20 | 60 seconds |
| staff_password_reset_confirm_post_ip | fixed_window | 20 | 60 seconds |
| client_signup | fixed_window | 5 | 1 hour |
| client_signup_email | fixed_window | 5 | 1 hour |
| guest_ticket_create | fixed_window | 3 | 1 hour |
| order_generation_ip | fixed_window | 15 | 1 hour |
| domain_lookup_ip | fixed_window | 60 | 1 hour |
| invoice_payment_ip | fixed_window | 10 | 1 hour |
| invoice_payment_hash | fixed_window | 10 | 1 hour |
| invoice_pdf_ip | fixed_window | 10 | 1 hour |
| invoice_pdf_hash | fixed_window | 10 | 1 hour |
| invoice_get_ip | fixed_window | 10 | 1 hour |
| invoice_get_hash | fixed_window | 30 | 1 hour |
| cart_promo_apply_ip | fixed_window | 10 | 1 hour |
| client_email_verification_resend_ip | fixed_window | 30 | 1 hour |
| client_email_verification_resend_account | fixed_window | 3 | 1 hour |
| client_email_resend_ip | fixed_window | 30 | 1 hour |
| client_email_resend_account | fixed_window | 5 | 1 hour |
| profile_password_change_ip | fixed_window | 30 | 1 hour |
| profile_password_change_account | fixed_window | 5 | 1 hour |
关键差异与解读:API 匿名/认证调用用 token_bucket(平滑放行突发),登录、注册、找回密码、发票取回等「敏感写操作」用 fixed_window 严格限死;同一策略常按 IP 与账号(email/hash)各配一条,双维度兜底。超限抛 RateLimitException,响应 429 语义。
💡 技术拓展:限流算法不止 FOSSBilling 用的这两类,主流算法对比——
算法 原理/特点 适用场景 固定窗口 fixed_window 单位时间计数,到顶即拒 简单粗暴的防刷(注册/找回) 令牌桶 token_bucket 恒速补令牌,桶容量容忍突发 API 通用限流(本组件匿名/认证 API) 滑动窗口 sliding window 按滑动时间窗统计,无边界突刺 精确限流的网关 漏桶 leaky bucket 恒定速率放行,削峰填谷 流量整形 FOSSBilling 0.8.8 内置 token_bucket 与 fixed_window 两种,基于 Symfony rate-limiter 组件实现;覆盖策略时只能从这两种里选。
六、生产配置模板
适用场景:2 vCPU / 4 GB 内存 / 40 GB SSD 的单机主机商起步规模(数百客户、日订单几十),Apache + PHP 8.3 + MariaDB 11.4 同机,TLS 由反代或本机证书提供。以下为 config.php 生产向模板(相对安装向导产物的改动处已用注释标出):
<?php
return [
'security' => [
'mode' => 'strict',
'force_https' => true, // TLS 就绪后必改
'trusted_proxies' => [
'enabled' => true, // 仅当 HTTPS 在 Nginx/负载均衡终结时开启
'proxies' => ['10.0.0.10'], // 换成你真实代理的 IP
'headers' => 'x_forwarded',
],
'session_lifespan' => 7200,
'session_regeneration_grace_period' => 300,
'perform_session_fingerprinting' => true,
'debug_fingerprint' => false,
],
'debug_and_monitoring' => [
'debug' => false, // 生产必须 false
'log_stacktrace' => true,
'stacktrace_length' => 25,
'report_errors' => false, // 不参与官方错误上报则 false
],
'info' => [
'salt' => '91499a121840efb7b9966bb8e559ba6f', // 安装时生成,保持不动
'instance_id' => '5bfa4e49-331f-472d-925c-001452d82a86', // 安装时生成,保持不动
],
'url' => 'https://billing.example.com/', // 换正式域名,尾斜杠必带
'admin_area_prefix' => '/admin',
'update_branch' => 'release',
'maintenance_mode' => [
'enabled' => false,
'allowed_urls' => [], // 维护时记得放行支付回调类 URL
'allowed_ips' => [],
],
'disable_auto_cron' => true, // 系统 crontab 为唯一触发源
'i18n' => [
'locale' => 'zh_CN', // 需先 locale-gen zh_CN.UTF-8,见 5.7
'auto_detect_locale' => true,
'timezone' => 'Asia/Shanghai',
'date_format' => 'medium',
'time_format' => 'short',
'datetime_pattern' => '',
],
'path_data' => '/var/www/html/data',
'db' => [
'driver' => 'pdo_mysql',
'host' => 'localhost',
'port' => 3306,
'name' => 'fossbilling',
'user' => 'fossbilling',
'password' => 'q1w2e3r4', // 示例口令;数据库侧同步改,账号权限含 LOCK TABLES/CREATE VIEW
],
'cache' => [
'driver' => 'filesystem', // 出现多机部署再切 redis
'redis' => ['host' => '127.0.0.1', 'port' => 6379, 'password' => null, 'database' => 0,
'tls' => ['enabled' => false, 'verify_peer' => true, 'verify_peer_name' => true,
'cafile' => null, 'allow_self_signed' => false]],
'memcached' => ['host' => '127.0.0.1', 'port' => 11211],
],
'twig' => [
'debug' => false,
'auto_reload' => true,
'cache' => '/var/www/html/data/cache',
'strict_variables' => true,
],
'api' => [
'require_referrer_header' => false,
'allowed_ips' => [], // 对外开放 API 时收窄到调用方 IP
'CSRFPrevention' => true, // 严禁关闭
],
'rate_limiter' => [
'enabled' => true,
'whitelist_ips' => [], // 有固定 IP 的对账程序再加白
'policies' => [], // 留空用内置默认,需调时只覆盖个别键
],
];
配套的系统级动作(缺一不可):
# 1. 收紧配置文件写权限(安装完成页指引)
chmod 644 /var/www/html/config.php
# 2. 系统 cron 承担出账(www-data 身份)
echo "*/5 * * * * php /var/www/html/cron.php" | crontab -u www-data -
# 3. PHP 上传上限按需放宽后重启 Apache(默认 2M/8M 偏小)
# /etc/php/8.3/apache2/php.ini 中 upload_max_filesize=20M、post_max_size=25M
apache2ctl -k restart
七、常见问题(FAQ)
以下 Q1–Q5 均为本机实测触发并解决的真实记录。
Q1:把 i18n.locale 改成 zh_CN 后,界面还是英文?
三层原因叠加,逐层排除:
- 系统未生成对应 locale:PHP gettext 需要操作系统存在
zh_CN.UTF-8。实测 Ubuntu 22.04 默认只有C / C.utf8 / POSIX(locale -a可查)。解决:apt-get install -y locales→ 在/etc/locale.gen取消zh_CN.UTF-8 UTF-8注释 →locale-gen→apache2ctl -k restart。生成后locale -a | grep zh应出现zh_CN.utf8。 - auto_detect_locale 干扰:该值为 true 时按浏览器
Accept-Language自动选语言,无语言头的请求(curl 等)实测落到英文。服务端强制中文:auto_detect_locale改false(实测 curl 不带头也返回<title>登录</title>)。 - 浏览器缓存/会话 Cookie:语言选择会写入 Locale Cookie(一个月有效期),换语言后用无痕窗口或清 Cookie 复测。
Q2:手工清缓存后整站 500,报 The template cache directory could not be written to?
- 现象:以 root 执行过
php /var/www/html/console.php cache:clear或rm -rf data/cache后,前台 500,php_error.log 出现实测记录:[23-Oct-2026 13:37:58 UTC] The template cache directory could not be written to. Please check the file permissions and available disk space for the "data/cache" directory. at /var/www/html/library/Box/App.php : 250 - 原因:root 执行导致重建的 cache 目录属主为 root,Apache 的 www-data 无法写入 Twig 编译缓存。
- 解决:恢复属主并养成以 www-data 执行的习惯:
实测恢复后前台返回 200。
chown -R www-data:www-data /var/www/html/data sudo -u www-data php /var/www/html/console.php cache:clear
Q3:维护模式 enabled 改回 false 后,前台还是 503?
- 现象:实测关闭 maintenance_mode 后,前台仍返回 503。
- 原因:开启期间的 503 响应被缓存命中,参数已生效但页面缓存未失效。
- 解决:清一次缓存即恢复:
实测随后
sudo -u www-data php /var/www/html/console.php cache:clearcurl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8148/返回 200。 - 排查顺序建议:改 config.php 不生效时按「确认文件保存(grep 核对)→ 清缓存(www-data 身份)→ 重启 Apache → 查 php_error.log」四步走。
Q4:config.php 的权限怎么设?
安装完成页明确要求收尾时执行 chmod 644 /var/www/html/config.php——文件必须可被 www-data 读取、但不应可被 Web 进程随意改写(安装器收尾阶段除外)。实测本机安装后权限即为 644、属主 www-data。若曾以 root 安装修复过属主,记得一并复核:
chown www-data:www-data /var/www/html/config.php
chmod 644 /var/www/html/config.php
Q5:限流误伤正常业务怎么办?
- 固定 IP 的程序化调用:把该 IP 加入
rate_limiter.whitelist_ips,完全绕过限流。 - 高频但合理的匿名调用(如对接前端购物车):只覆盖对应策略,如把匿名 API 从 100 次/分钟放宽:
'policies' => [ 'api_guest' => ['policy' => 'token_bucket', 'limit' => 300, 'interval' => '60 seconds'], ], - 不要为了省事整体
enabled => false——登录、找回密码、注册等防刷策略会一并失效。
八、参考链接
- 官方配置文档(Configuration):
https://docs.fossbilling.org/admin-guide/config/ - 官方样例文件(0.8.8 发行包内 config-sample.php,本篇多处注释引自该文件)
- 限流器默认策略源码:发行包内
library/FOSSBilling/Security/RateLimiter.php的getDefaultConfig() - 本专栏安装实战:《Ubuntu 22.04 安装 FOSSBilling 0.8.8 指南》
- 本专栏选型认知:《FOSSBilling 0.8.8 介绍与选型指南》
- PHP IntlDateFormatter(date_format/time_format 档位):
https://www.php.net/manual/en/class.intldateformatter.php - ICU 日期时间模式(datetime_pattern 语法):
https://unicode-org.github.io/icu/userguide/format_parse/datetime/