菜单

FastCGI

相关源文件

FastCGI 是一种用于将 Web 服务器与应用程序连接的协议,特别适用于动态内容生成。本文档详细介绍了 Caddy 的 FastCGI 实现,它允许 Caddy 与 PHP-FPM 等 FastCGI 应用程序进行通信。有关通用反向代理的信息,请参阅反向代理

概述

Caddy 将 FastCGI 作为其反向代理处理程序的传输协议来实现。这种集成使 Caddy 能够高效地将请求转发到 FastCGI 应用程序并处理它们的响应。该实现包括针对 PHP 的特殊优化,因为 PHP 是 FastCGI 最常见的用例。

Sources: modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go116-209

架构

Caddy 中的 FastCGI 实现是作为反向代理处理程序的专用传输机制。此实现的核心是 fastcgi 包中的 Transport 结构体。

Sources: modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go43-85

Transport 结构体实现了 http.RoundTripper 接口,这使得它可以用作反向代理处理程序的传输机制。当接收到请求时,RoundTrip 方法会构建相应的 CGI 环境变量,建立与 FastCGI 服务器的连接,并使用 client 类型管理通信。

配置

JSON 配置

FastCGI 传输可以直接在 Caddy 的 JSON 配置中进行配置。下面是可用的配置选项表

字段类型描述
root字符串FastCGI 应用程序的根目录(默认为虚拟主机的根目录)
split_path[]string用于分割 URL 的路径段(第一部分成为脚本名,第二部分成为 PATH_INFO)
resolve_root_symlinkbool是否解析根路径中的符号链接
envmap[string]string要传递给 FastCGI 应用程序的额外环境变量
dial_timeoutduration建立连接的超时时间(默认:3秒)
read_timeoutduration从 FastCGI 服务器读取的超时时间
write_timeoutduration写入 FastCGI 服务器的超时时间
capture_stderrbool是否捕获并记录 FastCGI 应用程序的 stderr 输出

Sources: modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go43-85

Caddyfile 配置

对于 PHP 应用程序(FastCGI 最常见的用例),Caddy 为 Caddyfile 提供了 php_fastcgi 指令。此指令为 PHP 处理设置了完整的配置。

基本语法

php_fastcgi [<matcher>] <upstream>

其中

  • <matcher> 是一个可选的路径匹配器
  • <upstream> 是 FastCGI 服务器的地址,例如 localhost:9000

其他选项

php_fastcgi [<matcher>] <upstream> {
    root <path>
    split <extensions...>
    env <key> <value>
    index <filename>
    try_files <files...>
    resolve_root_symlink
    dial_timeout <duration>
    read_timeout <duration>
    write_timeout <duration>
    capture_stderr
}

Sources: modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go37-122 modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go207-302

PHP 集成

php_fastcgi 指令经过特殊设计,旨在高效处理 PHP 应用程序。它设置了多个协同工作的路由,以提供正确的 PHP 处理

Sources: modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go124-447

此设置提供了针对 PHP 应用程序的几个关键功能

  1. 目录处理:将目录请求重定向以包含尾部斜杠
  2. 索引文件解析:在请求目录时尝试查找索引文件
  3. PHP 文件处理:将 PHP 文件请求代理到 FastCGI 服务器

在底层,php_fastcgi 指令创建了多个路由和处理程序

  1. 用于重定向请求以在目录后添加尾部斜杠(如果需要)的路由
  2. 带有文件匹配器的路由,用于尝试不同的文件并重写为找到的第一个文件
  3. 带有 PHP 文件路径匹配器的路由,使用 FastCGI 传输来代理请求

Sources: modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go310-383 modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go385-417

请求处理

当请求由 FastCGI 传输处理时,会发生以下步骤

  1. 环境变量准备buildEnv 方法从 HTTP 请求构建 CGI 环境变量
  2. 连接建立:与 FastCGI 服务器建立连接
  3. 请求转发:请求通过连接转发到 FastCGI 服务器
  4. 响应处理:FastCGI 服务器的响应被转换为 HTTP 响应

环境变量

FastCGI 传输设置了标准的 CGI 环境变量,包括

  • DOCUMENT_ROOT:为 FastCGI 应用程序配置的根目录
  • SCRIPT_FILENAME:正在执行脚本的绝对路径
  • SCRIPT_NAME:脚本的 URL 路径
  • PATH_INFO:脚本名后的额外路径信息(如果启用了路径分割)
  • REQUEST_URI:客户端请求的原始 URI
  • QUERY_STRING:URL 中的查询字符串
  • HTTP 头(以 HTTP_ 为前缀)
  • env 中配置的额外环境变量

Sources: modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go212-372

路径分割

FastCGI 传输的一个重要功能是路径分割,它将脚本名与额外路径信息分开。这对于需要通过 $_SERVER['PATH_INFO'] 访问路径信息的 PHP 应用程序特别有用。

例如,如果路径为 /script.php/extra/info,分割路径为 .php,传输将设置

  • SCRIPT_NAME/script.php
  • PATH_INFO/extra/info

Sources: modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go376-392

安全考量

FastCGI 实现,特别是针对 PHP 的实现,如果配置不当,可能会带来安全风险。Caddy 的 FastCGI 实现中的一些关键安全功能包括

  1. 空字节拒绝:路径中包含空字节(\x00)的请求将被拒绝,以防止 PHP 相关的潜在安全问题
  2. 路径净化:路径在用于构建 SCRIPT_FILENAME 之前会进行净化
  3. 符号链接解析选项:当根目录是符号链接时,resolve_root_symlink 选项有助于防止 PHP opcache 的问题

Sources: modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go119-124

配置示例

基本的 PHP-FPM 设置

PHP 应用程序的基本 Caddyfile 配置

example.com {
    root * /var/www/html
    php_fastcgi localhost:9000
    file_server
}

此配置

  1. 将根目录设置为 /var/www/html
  2. 将 PHP 请求代理到运行在 localhost:9000 的 FastCGI 服务器
  3. 提供静态文件

高级配置

具有自定义设置的更高级配置

example.com {
    root * /var/www/html
    
    php_fastcgi /app/* localhost:9000 {
        root /var/www/html/app
        env APP_ENV production
        split .php
        index index.php
        try_files {path} {path}/index.php index.php
        dial_timeout 5s
        read_timeout 30s
        write_timeout 30s
    }
    
    file_server
}

此配置

  1. 只处理 /app/ 路径下的 PHP 请求
  2. 为 FastCGI 应用程序设置特定的根目录
  3. 添加一个环境变量
  4. 配置自定义超时
  5. 指定自定义的索引和 try_files 设置

Sources: modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go37-122 modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go171-302