Lighttpd 1.4.85 配置参数详解
Lighttpd 1.4.85 配置指令全实测:server 核心指令、站点行为、日志格式、Basic 认证与 TLS、URL 改写重定向、压缩与多 worker、条件块语法、生产配置模板与取值陷阱 FAQ,回显全部实测(2026-10-20)。
Lighttpd 1.4.85 配置参数详解
目标:把 lighttpd 1.4.85 常用配置指令逐组讲透并全部实测——每条指令给出语法、真实验证回显与行为说明,收尾给一份可直接落地的生产配置模板;文中的坑(
dir-listing.activate的取值陷阱、单引号字符串不被支持等)均为实测发现。安装过程见 B1 安装指南篇。
一、环境信息
本文全部指令在以下环境逐条实测,回显照抄:
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- lighttpd 版本:1.4.85(官方源码 meson 编译,
lighttpd/1.4.85 (ssl),特性含 epoll/sendfile/zlib/zstd/brotli/OpenSSL;编译方法见 B1 方案 B) - 安装前缀:
/usr/local/lighttpd(配置/usr/local/lighttpd/etc/,日志/usr/local/lighttpd/var/log/) - 测试站点根:
/srv/www(含index.html、sub/index.html、secret/data.txt、deny/x.inc、404.html) - 端口:主服务 80;临时测试用 8081;TLS 443
- 对照参考:Ubuntu 22.04 apt 版 lighttpd 1.4.63 的默认主配置(
/etc/lighttpd/lighttpd.conf) - 实测日期:2026-10-20;未实测的默认值均标注「官方文档值」并给出处
二、配置文件体系与加载顺序
本节先讲清 1.4.85 的配置组织方式,避免「改了没生效」类问题。lighttpd 配置是纯文本键值 + 条件块语法,启动时一次性解析;与 Ubuntu 打包版的三层软链体系不同,编译版通常用单文件或 include 组织。
- 主配置入口:
lighttpd -f <file>指定的文件(编译版本文用/usr/local/lighttpd/etc/lighttpd-min.conf;apt 版是/etc/lighttpd/lighttpd.conf)。 - include / include_shell:可把片段并入主配置。Ubuntu 版用
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"把conf-enabled/下全部软链片段依次带入——这就是 Ubuntu「启用模块只建软链」的原理;编译版可直接写include "/usr/local/lighttpd/etc/mime.conf"拆分文件。 - 生效顺序:指令按文件内从上到下解析,后写的同名键覆盖先写的;条件块内部的值覆盖外层全局值(同键嵌套时以最内层为准)。
- 语法自检:改完配置先跑
lighttpd -tt -f <file>(连模块一起加载验证),通过再重载——本文所有配置片段均经过该命令实测验证(-tt的完整用法见 D1 CLI 命令篇)。
三、核心服务器指令(server.*)
本组指令决定进程身份、监听方式与日志落点,是最小可运行配置的骨架。以下逐条实测。
3.1 server.modules(模块加载)
server.modules = (
"mod_accesslog", "mod_dirlisting", "mod_access", "mod_alias",
"mod_auth", "mod_authn_file", "mod_deflate", "mod_redirect",
"mod_rewrite", "mod_openssl", "mod_h2"
)
实测要点:模块名按需列写即可,顺序影响不大(本文做过仅有顺序差异的对照实验,mod_accesslog 在前在后行为一致);但某模块的指令想生效,必须先加载该模块——实测把 dir-listing.activate 写进配置而未加载 mod_dirlisting 时,-tt 报:
WARNING: unknown config-key: dir-listing.activate(ignored)
补上模块后告警消失(-tt 退出码 0)。另注意 1.4.71+ 部分模块(indexfile/access/alias/redirect/rewrite/dirlisting/staticfile 等)已并入主程序,无需对应 .so,但仍要在 server.modules 列出以激活其指令(本文 1.4.85 构建中 mod_dirlisting.so 等同时以动态模块存在)。
3.2 server.port / server.bind(监听)
server.bind = "0.0.0.0"
server.port = 80
实测:改为 server.port = 8080 重启后,curl -sI http://localhost:8080 返回 HTTP/1.1 200 OK(Server: lighttpd/1.4.85),原 80 端口停止响应。server.bind 省略时监听全部地址;只监听本机可设 "127.0.0.1"。端口被占用时启动失败的完整排障实录见 B1 FAQ Q1(can't bind to socket: 0.0.0.0:80: Address already in use)。
3.3 server.document-root(站点根)
server.document-root = "/srv/www"
实测:该目录必须存在且可读,请求 / 时依次尝试 index-file.names;目录无 index 且未开目录列表时返回 403 Forbidden(实测:仅加载 mod_dirlisting 而不设 dir-listing.activate,curl -si http://127.0.0.1:8081/ 返回 HTTP/1.1 403 Forbidden)。这是全配置唯一必填的服务器级指令。
3.4 server.username / server.groupname(运行身份)
server.username = "www-data"
server.groupname = "www-data"
实测说明:以 root 启动时绑定 80 特权端口后降权到该用户运行;Ubuntu apt 版默认即此写法。编译版最小配置省略时进程以启动者身份运行(生产环境建议显式降权)。文件权限需与该身份匹配,否则出现 403/404。
3.5 server.pid-file / server.errorlog / server.upload-dirs
server.pid-file = "/usr/local/lighttpd/var/run/lighttpd.pid"
server.errorlog = "/usr/local/lighttpd/var/log/error.log"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
实测:server.pid-file 写出的主进程号可用于脚本化管理(如 kill -USR1 $(cat ...) 触发优雅重启,见 D1);server.errorlog 指定的文件会在启动时创建,启动成功记录 server started、失败记录具体原因(实测样例行:2026-10-20 17:05:59: (../src/server.c.1973) server started (lighttpd/1.4.85))。server.upload-dirs 是请求体上传的临时目录,Ubuntu 默认 /var/cache/lighttpd/uploads(实测该目录存在且归 www-data)。
四、站点行为指令
本组指令决定「请求进来之后返回什么」。
4.1 index-file.names(目录默认页)
index-file.names = ( "index.html" )
实测:请求目录路径时按序查找;配合 mimetype.assign 使用。Ubuntu 默认值为 ( "index.php", "index.html" )。
4.2 mimetype.assign(MIME 映射)
mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain", ".inc" => "text/plain" )
实测:响应头 Content-Type: text/html 与该映射一致;映射缺失的类型默认按 application/octet-stream 处理。apt 版通过 include_shell "/usr/share/lighttpd/create-mime.assign.pl" 从 /etc/mime.types 自动生成完整表。
4.3 dir-listing.activate(目录列表)—— 含取值陷阱实测
标准用法(只对指定路径开启列表):
$HTTP["url"] =~ "^/sub/" {
dir-listing.activate = "enable"
}
实测(条件作用域):请求 / 返回 HTTP/1.1 403 Forbidden,请求 /sub/ 返回 HTTP/1.1 200 OK 并输出目录索引页——列表只对 /sub/ 前缀生效。
⚠️ 实测发现的取值陷阱:
dir-listing.activate的值只接受"enable"。写成dir-listing.activate = "disable"时,-tt与启动日志都会报WARNING: unknown config-key: dir-listing.activate(ignored),且目录列表实际处于开启状态(实测curl /返回 200 与完整Index of /页面),行为与直觉相反。实测结论:想关闭目录列表,直接不写该指令、或不加载 mod_dirlisting(默认即关,实测不写时返回 403);想全局开、局部关的场景,用条件块把"enable"限定到需要的路径。
4.4 url.access-deny(访问拒绝)
url.access-deny = ( "~", ".inc" )
实测:对 .inc 结尾的请求返回 403 Forbidden(模组 mod_access;保护备份文件 ~ 与源码片段是经典用法)。
4.5 server.error-handler-404(错误处理页)
server.error-handler-404 = "/404.html"
实测:请求不存在的 /no-such-page 返回处理页内容 <h1>custom 404 page</h1>;注意状态码为 HTTP/1.1 200 OK 而非 404(静态文件作为 error-handler 的既有行为,详见 FAQ)。
五、日志指令
5.1 accesslog.filename(访问日志位置)
accesslog.filename = "/usr/local/lighttpd/var/log/access.log"
实测:每个请求一行即时落盘;配合系统 logrotate 轮转(apt 版随包自带 /etc/logrotate.d/lighttpd)。
5.2 accesslog.format(访问日志格式)
默认格式即 Apache CLF(%h %V %u %t "%r" %>s %b)。自定义示例(实测生效):
accesslog.format = "%h %V %u %t \"%r\" %>s %b"
实测自定义格式输出(tail -1 /usr/local/lighttpd/var/log/access.log):
127.0.0.1 127.0.0.1 - [20/Oct/2026:16:44:17 +0000] "GET /big.txt HTTP/1.1" 200 13492
⚠️ 实测发现两条写法约束:① 单引号字符串不被 1.4.85 配置解析器支持——写
accesslog.format = '%h ...'时报invalid character in variable name(configfile parser failed at: =);② 内嵌双引号必须写成\"转义(官方示例同款写法)。常用占位符:%h客户端 IP、%V服务器名、%u认证用户、%t时间、%r请求行、%>s最终状态码、%b响应字节数、%{User-Agent}i请求头。
六、认证与 TLS 指令
6.1 Basic 认证(mod_auth + mod_authn_file)
auth.backend = "plain"
auth.backend.plain.userfile = "/usr/local/lighttpd/etc/auth.users"
auth.require = ( "/secret/" => (
"method" => "basic",
"realm" => "test-realm",
"require" => "valid-user"
) )
用户文件 /usr/local/lighttpd/etc/auth.users 内容为 admin:q1w2e3r4(权限 600)。实测无凭据访问受保护路径:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="test-realm", charset="UTF-8"
带凭据访问(curl -u admin:q1w2e3r4)返回 HTTP/1.1 200 OK 并正常输出 top secret dir。生产建议:密码文件置于站点根之外、权限 600、属主与 server.username 一致。
6.2 TLS/HTTPS(mod_openssl,条件块监听)
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/usr/local/lighttpd/etc/server.pem"
}
自签证书生成与合并(pemfile = 私钥 + 证书顺序拼接):
cd /usr/local/lighttpd/etc
openssl req -x509 -newkey rsa:2048 -nodes -keyout server.key -out server.crt -days 365 -subj "/CN=localhost"
cat server.key server.crt > server.pem
实测 HTTPS 验证(curl -k 跳过自签校验):
HTTP/2 200
解读:1.4.85 的 HTTP/2 由 mod_h2 承载(需在 server.modules 列出),走 TLS ALPN 协商,所以 curl 直接以 HTTP/2 200 响应。生产环境把 ssl.pemfile 换成 CA 签发的全链证书即可,续期后 kill -USR1 优雅重载。
七、URL 处理指令
7.1 alias.url(路径别名)
alias.url = ( "/docs/" => "/srv/www/sub/" )
实测:curl -sI http://127.0.0.1/docs/ 返回 HTTP/1.1 200 OK(内容来自 /srv/www/sub/),对客户端完全透明。
7.2 url.rewrite(内部改写)
url.rewrite = ( "^/nolink/(.*)$" => "/sub/$1" )
实测:curl -s http://127.0.0.1/nolink/ 返回 HTTP/1.1 200 OK、内容为 /sub/ 的 <h1>sub dir</h1>——不产生跳转头,客户端无感知。
7.3 url.redirect(外部重定向)
url.redirect = ( "^/old/(.*)$" => "/sub/$1" )
实测:curl -sI http://127.0.0.1/old/abc 返回:
HTTP/1.1 301 Moved Permanently
Location: /sub/abc
选型记忆:rewrite = 服务端换路径(浏览器地址不变)、redirect = 返回 301/302 让浏览器重新请求。
八、性能与压缩指令
8.1 server.max-worker(多进程)
server.max-worker = 2
实测:重启后进程形态为 1 主 + 2 子(ps -ef 可见 3 个 lighttpd 进程,PID 6936 主、6937/6938 为子进程),多核机器上可提升静态吞吐;小内存机器保持默认单进程即可(默认值 1,官方文档值,官方 wiki《Performance》条目)。
8.2 mod_deflate 响应压缩
deflate.mimetypes = ( "text/plain", "text/html" )
实测(10KB 级文本 big.txt,GET 请求带 Accept-Encoding: gzip):
ETag: "1303632381-gzip"
Vary: Accept-Encoding
Content-Length: 958
Content-Encoding: gzip
原文 13492 字节压缩到 958 字节;ETag 追加 -gzip 后缀以便缓存正确失效。两个实测细节:HEAD 请求不压缩(实测 curl -sI 同一文件无 Content-Encoding);压缩只对 deflate.mimetypes 列出的类型生效。编译版需带 zlib/zstd/brotli 头文件构建(见 B1 5.3 踩坑记录)。连接数类参数 server.max-connections(默认 1024)、server.max-keep-alive-requests(默认 16)、server.max-keep-alive-idle(默认 5 秒)为官方文档值(官方 wiki《Performance - lighttpd wiki》,2026-10-20 实查),一般保持默认。
九、条件块语法
条件块是 lighttpd 配置的精髓,本文已实测三种:
| 条件块 | 含义 | 本文实测场景 |
|---|---|---|
$HTTP["url"] =~ "正则" | 请求路径匹配 | 只对 /sub/ 前缀开目录列表(4.3) |
$SERVER["socket"] == ":443" | 监听套接字匹配 | TLS 监听块(6.2) |
$HTTP["host"] == "域名" | Host 头匹配 | 虚拟主机(语法同款,本文用 IP 直连未触发) |
嵌套规则:条件块可嵌套,内层可覆盖外层同键值;== 精确匹配、=~ 正则匹配。auth.require 的键本身就是「路径前缀 → 参数表」映射,与条件块配合可实现按目录的差异化策略。
十、生产配置模板(1.4.85)
以下模板由本文全部实测片段组装而成,可直接落地(路径按需替换);每一段均在前文对应小节实测验证过:
server.modules = (
"mod_accesslog", "mod_dirlisting", "mod_access", "mod_alias",
"mod_auth", "mod_authn_file", "mod_deflate", "mod_redirect",
"mod_rewrite", "mod_openssl", "mod_h2"
)
server.document-root = "/srv/www"
server.bind = "0.0.0.0"
server.port = 80
server.username = "www-data"
server.groupname = "www-data"
server.pid-file = "/usr/local/lighttpd/var/run/lighttpd.pid"
server.errorlog = "/usr/local/lighttpd/var/log/error.log"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
accesslog.filename = "/usr/local/lighttpd/var/log/access.log"
accesslog.format = "%h %V %u %t \"%r\" %>s %b"
index-file.names = ( "index.html" )
mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain" )
url.access-deny = ( "~", ".inc" )
# 目录列表只对下载区开放(不要用 dir-listing.activate = "disable" 关闭,见 4.3 陷阱)
$HTTP["url"] =~ "^/downloads/" {
dir-listing.activate = "enable"
}
# Basic 认证保护区
auth.backend = "plain"
auth.backend.plain.userfile = "/usr/local/lighttpd/etc/auth.users"
auth.require = ( "/secret/" => (
"method" => "basic", "realm" => "test-realm", "require" => "valid-user" ) )
# 路径别名 / 内部改写 / 外部跳转
alias.url = ( "/docs/" => "/srv/www/sub/" )
url.rewrite = ( "^/nolink/(.*)$" => "/sub/$1" )
url.redirect = ( "^/old/(.*)$" => "/sub/$1" )
# 响应压缩
deflate.mimetypes = ( "text/plain", "text/html" )
# HTTPS(自签证书生产环境请替换为 CA 证书)
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/usr/local/lighttpd/etc/server.pem"
}
上线前三步验证(均实测通过):
/usr/local/lighttpd/sbin/lighttpd -tt -f /usr/local/lighttpd/etc/lighttpd-min.conf && echo CONFIG-TEST-OK
实测回显:
CONFIG-TEST-OK
systemctl restart lighttpd-local && systemctl is-active lighttpd-local
实测回显:
active
curl -skI https://localhost | head -2
实测回显:
HTTP/2 200
十一、常见问题(FAQ)
Q1:dir-listing.activate = "disable" 为什么报警告且行为反直觉?
见 4.3 实测:该指令值只接受 "enable";写 "disable" 会产生 unknown config-key: dir-listing.activate(ignored) 告警且目录列表实际开启。关闭列表的正确姿势:不写该指令(默认关,实测 403)或用条件块只对需要的路径 "enable"。
Q2:配置里用单引号包字符串直接解析失败?
1.4.85 配置解析器不支持单引号字符串。实测 accesslog.format = '%h %V ...' 报:
configfile.c.2204) source: /usr/local/lighttpd/etc/lighttpd-min.conf line: 8 pos: 33 invalid character in variable name
configfile parser failed at: %h %V %u %t
统一用双引号,内嵌双引号转义为 \"(官方示例同款)。
Q3:error-handler-404 指向静态文件后,404 变成了 200?
既有行为:静态文件作为 server.error-handler-404 时响应状态码为处理页自身的 200(实测 /no-such 返回 HTTP/1.1 200 OK + 自定义页内容)。需要真实 404 状态码时改用动态脚本处理或在应用层兜底。
Q4:模块指令写了却提示 unknown config-key?
对应模块没进 server.modules(见 3.1 实测)。补上模块名告警即消失;仍无效则用 -tt 单独最小化复现排查。
Q5:改完配置如何做到不停机生效?
lighttpd -tt 自检通过后执行 systemctl reload lighttpd(或向主进程发 kill -USR1),单元文件里 ExecReload=/bin/kill -USR1 $MAINPID,实测 USR1 后日志先记录 server stopped by UID = 0 PID = 6936 随即 server started,期间服务持续可访问(回显详见 D1 信号控制一节)。
十二、参考链接
- 官方配置 Wiki(含各指令默认值):https://redmine.lighttpd.net/projects/lighttpd/wiki/WikiStart#Configuration
- mod_dirlisting / mod_auth / mod_deflate 官方文档(redmine wiki 对应页面)
- Ubuntu apt 版默认主配置:
/etc/lighttpd/lighttpd.conf(随包文件) - 本文实测:lighttpd 1.4.85(meson 编译,Ubuntu 22.04.5),实测日期 2026-10-20;安装过程见 《Ubuntu 22.04 安装 Lighttpd 指南》,命令行工具用法见 《Lighttpd 1.4.85 常用 CLI 命令详解》