跳转至内容

lighttpd

来自 ArchWiki

"lighttpd (读作 /lighty/) 是一个安全、快速、符合标准且非常灵活的 Web 服务器,针对高性能环境进行了优化。lighttpd 在高效利用内存和 CPU 的同时支持多种功能,使其成为所有规模系统(无论大小)的理想 Web 服务器。"

安装

安装 lighttpd 软件包。

配置

基本设置

lighttpd 的配置文件为:/etc/lighttpd/lighttpd.conf。默认情况下,它应该会生成一个可运行的测试页面。

要检查 lighttpd.conf 是否有错误,可以使用此命令(有助于快速发现配置错误)

$ lighttpd -tt -f /etc/lighttpd/lighttpd.conf

默认配置文件指定 /srv/http/ 为服务的文档目录。要测试安装情况,请创建一个虚拟文件

/srv/http/index.html
Hello world!

然后 启动/启用 lighttpd.service 并将浏览器指向 localhost,你应该能看到测试页面。

示例配置文件可在 /usr/share/doc/lighttpd/ 中找到。

基础日志记录

lighttpd 可以将错误和访问记录写入日志文件。错误日志默认启用(由 server.errorlog 选项控制)。要启用访问日志,请按如下方式编辑 /etc/lighttpd/lighttpd.conf

server.modules += (
   "mod_accesslog",
)

accesslog.filename = "/var/log/lighttpd/access.log"

启用 HTTPS

警告 计划实现 SSL/TLS 的用户应知晓,某些变体和实现容易受到攻击。详情请参阅 OpenSSL 页面。
提示
自签名证书

可通过参考 OpenSSL#用单条命令生成带私钥的自签名证书 来生成自签名证书。

创建 /etc/lighttpd/certs 目录,并将密钥和证书文件移至该处。

# mkdir -m0700 /etc/lighttpd/certs/

修改 /etc/lighttpd/lighttpd.conf,添加以下行以启用 HTTPS

server.modules += ( "mod_openssl" )

$SERVER["socket"] == ":443" {
   ssl.engine                  = "enable"
   ssl.privkey                 = "/etc/lighttpd/certs/key_filename"
   ssl.pemfile                 = "/etc/lighttpd/certs/cert_filename"
}

详情请参阅 lighttpd TLS 配置

Let's Encrypt

或者,获取一个由 Let's Encrypt 签名的证书。

编辑 /etc/lighttpd/lighttpd.conf,添加以下行

$SERVER["socket"] == ":443" {
    ssl.engine                  = "enable"
    ssl.privkey                 = "/etc/letsencrypt/live/domain/privkey.pem" 
    ssl.pemfile                 = "/etc/letsencrypt/live/domain/fullchain.pem"  
}

详情请参阅 lighttpd 文档中的 引导 Let's Encrypt 部分。

将 HTTP 请求重定向至 HTTPS

你应该在 /etc/lighttpd/lighttpd.conf 的 server.modules 数组中添加 "mod_redirect"

server.modules += ( "mod_redirect" )

$HTTP["scheme"] == "http" {
  url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")
}

$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/etc/lighttpd/certs/server.pem" 
  server.document-root = "..." 
}

若要将网站部分路径(例如 secure 或 phpmyadmin)的所有主机重定向

$HTTP["url"] =~ "^/secure" {
  $HTTP["scheme"] == "http" {
    url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")
  }
}

为目录设置密码保护

用户身份验证需要一个 passwd 文件(lighttpd 中相当于系统的 /etc/passwd)。该设置需要特定的格式和 md5sum 哈希密码,但用户可以参考以下示例快速轻松地创建条目

$ user=foo
$ password=b@R102
$ realm='Password Required'
$ hash=`echo -n "$user:$realm:$password" | md5sum | cut -b -32`

# echo "$user:$realm:$hash" >> /etc/lighttpd/lighttpd.user

修改 /etc/lighttpd/lighttpd.conf,添加以下行以启用目录保护

server.modules += ( "mod_auth", "mod_authn_file" )

auth.backend = "htdigest"
auth.backend.htdigest.userfile = "/etc/lighttpd/lighttpd.user"

# note this entry is relative to the server.document-root
auth.require = ( "/secret" =>
   (
    "method" => "basic",
    "realm" => "Password Required",
    "require" => "valid-user"
   )
)
注意 /etc/lighttpd/lighttpd.conf 中输入的 realm 必须与 /etc/lighttpd/lighttpd.user 中选择的值匹配,身份验证才能生效。

拦截 AI 爬虫

将此内容插入你的配置中,理想情况下是在从 ai.robots.txt 项目获取已知 AI 爬虫的最新匹配项之后。这将过滤掉一些旧版浏览器(很可能是机器人)以及任何声称是浏览器但不支持现代浏览器 HTTP 标头的用户代理(User-Agent)。允许 curl/wget 等非浏览器用户代理。

# Regex for URLs that are always allowed
var.allowURLs = "^(/robots\.txt|/favicon\.ico|/\.well-known/)"
# Allow bots that declare themselves as such
var.allowBotUA = "(?i)bot|spider|crawl"
# Block old browsers (Chrome/Firefox < 100, Opera < 15, MSIE, Safari < 15)
var.oldUA = "(?:Chrome|Firefox)/\d\d?\.| Presto/| Trident/| MSIE |Version/(?:[1-9]|1[0-4])\..{1,20} Safari/"
# Block iPhone/iPad useragents with a non-iOS-version of Safari
var.fakeAppleUA = "(?:iPhone|iPad; CPU) OS (?!18_[67])(\d+).{0,200}Version/(?!\1)"
# Browser-like useragents
var.browserUA = "(?:Chrome|Firefox|Safari|WebKit)/\d"

$HTTP["url"] !~ allowURLs {

  # Paste the $HTTP["useragent"] match from this URL here (regularly updated):
  # https://raw.githubusercontent.com/ai-robots-txt/ai.robots.txt/refs/heads/main/lighttpd-block-ai-bots.conf

  $HTTP["useragent"] !~ allowBotUA {
    $HTTP["useragent"] =~ oldUA {
      url.access-deny = ( "" )
    }
    else $HTTP["useragent"] =~ fakeAppleUA {
      url.access-deny = ( "" )
    }
    else $HTTP["useragent"] =~ browserUA {
      $HTTP["language"] == "" {
        url.access-deny = ( "" )
      }
      else $REQUEST_HEADER["Accept-Encoding"] !~ "(br|deflate)(,|$)" {
        url.access-deny = ( "" )
      }
      else {
        # https://blog.sicuranext.com/sec-fetch-and-client-hints-a-powerful-tool-against-automation/
        $REQUEST_HEADER["Sec-Fetch-Dest"] == "" {
          $HTTP["useragent"] !~ "(Android| Version/15\.)" {
            url.access-deny = ( "" )
          }
        }
        $REQUEST_HEADER["Sec-Ch-Ua-Platform"] == "\"Windows\"" {
          $HTTP["useragent"] !~ "Win" {
            url.access-deny = ( "" )
          }
        }
        else $REQUEST_HEADER["Sec-Ch-Ua-Platform"] == "\"macOS\"" {
          $HTTP["useragent"] !~ "[Mm]ac" {
            url.access-deny = ( "" )
          }
        }
        else $REQUEST_HEADER["Sec-Ch-Ua-Platform"] == "\"Linux\"" {
          $HTTP["useragent"] !~ "Linux" {
            url.access-deny = ( "" )
          }
        }
        else $REQUEST_HEADER["Sec-Ch-Ua-Platform"] == "\"Android\"" {
          $HTTP["useragent"] !~ "Android" {
            url.access-deny = ( "" )
          }
        }
      }
    }
  }
}

你可以使用 server.error-handler 指令向用户显示自定义错误页面,或者将 url.access-deny = ( "" ) 替换为 url.rewrite-once = ( "" => "/blocked.html" ) 。你的自定义错误页面可以包含一个选项,如果用户是人类则设置 cookie,并通过追加内容来禁用拦截

$HTTP["cookie"] =~ "human=true" {
  url.access-deny = ()
  url.rewrite-once = ()
}

CGI

通用网关接口 (CGI) 脚本只需启用 CGI 模块;包含配置文件并确保安装了所选的编程语言解释器。(例如,对于 python,你需要安装 python

创建文件 /etc/lighttpd/conf.d/cgi.conf 并添加以下内容

server.modules += ( "mod_cgi" )

cgi.assign                 = ( ".pl"  => "/usr/bin/perl",
                               ".cgi" => "/usr/bin/perl",
                               ".rb"  => "/usr/bin/ruby",
                               ".erb" => "/usr/bin/eruby",
                               ".py"  => "/usr/bin/python",
                               ".php" => "/usr/bin/php-cgi" )

index-file.names           +=( "index.pl",   "default.pl",
                               "index.rb",   "default.rb",
                               "index.erb",  "default.erb",
                               "index.py",   "default.py",
                               "index.php",  "default.php" )

对于 PHP 脚本,你需要确保 /etc/php/php.ini 中设置了以下内容

cgi.fix_pathinfo = 1

在 lighttpd 配置文件 /etc/lighttpd/lighttpd.conf 中添加

include "conf.d/cgi.conf"

FastCGI

安装 fcgi。现在你拥有了支持 fcgi 的 lighttpd。如果这就是你想要的,那么设置就完成了。需要 Ruby on Rails、PHP 或 Python 的用户请继续阅读。

注意 新的默认用户和组:lighttpd 现在默认以用户/组 http 运行,而不是组 nobody

首先,将示例配置文件从 /usr/share/doc/lighttpd/config/conf.d/fastcgi.conf 复制到 /etc/lighttpd/conf.d

需要在配置文件 /etc/lighttpd/conf.d/fastcgi.conf 中添加以下内容

server.modules += ( "mod_fastcgi" )

index-file.names += ( "dispatch.fcgi" ) #dispatch.fcgi if rails specified

server.error-handler-404   = "/dispatch.fcgi" #too
fastcgi.server = (
    ".fcgi" => (
      "localhost" => ( 
        "socket" => "/run/lighttpd/rails-fastcgi.sock",
        "bin-path" => "/path/to/rails/application/public/dispatch.fcgi"
      )
    )
)

然后在 /etc/lighttpd/lighttpd.conf

include "conf.d/fastcgi.conf"

关于 PHP 或 Ruby on Rails,请参阅接下来的章节。

PHP

使用 php-cgi

安装 phpphp-cgi(另见 PHPLAMP)。

检查 php-cgi 是否正常工作 php-cgi --version

PHP 5.4.3 (cgi-fcgi) (built: May  8 2012 17:10:17)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies

如果你看到类似的输出,则 php 已正确安装。

创建新的配置文件

/etc/lighttpd/conf.d/fastcgi.conf
# Make sure to install php and php-cgi. See:                                                             
# https://wiki.archlinux.org.cn/index.php/Fastcgi_and_lighttpd#PHP

server.modules += ("mod_fastcgi")

# FCGI server
# ===========
#
# Configure a FastCGI server which handles PHP requests.
#
index-file.names += ("index.php")
fastcgi.server = ( 
    # Load-balance requests for this path...
    ".php" => (
        # ... among the following FastCGI servers. The string naming each
        # server is just a label used in the logs to identify the server.
        "localhost" => ( 
            "bin-path" => "/usr/bin/php-cgi",
            "socket" => "/tmp/php-fastcgi.sock",
            # breaks SCRIPT_FILENAME in a way that PHP can extract PATH_INFO
            # from it 
            "broken-scriptfilename" => "enable",
            # Launch (max-procs + (max-procs * PHP_FCGI_CHILDREN)) procs, where
            # max-procs are "watchers" and the rest are "workers". See:
            # https://wiki.lighttpd.net/frequentlyaskedquestions#How-many-php-CGI-processes-will-lighttpd-spawn 
            "max-procs" => "4", # default value
            "bin-environment" => (
                "PHP_FCGI_CHILDREN" => "1" # default value
            )
        )
    )   
)

通过在 lighttpd 配置文件中追加以下行,使 lighttpd 使用新的配置文件

/etc/lighttpd/lighttpd.conf
include = "conf.d/fastcgi.conf"
注意 请记住模块加载的顺序很重要。正确顺序列在 /usr/share/doc/lighttpd/config/modules.conf 中。

重新加载 lighttpd.service

  • 如果在尝试访问 .php 文件时收到 No input file found 之类的错误,可能有几种解释。更多信息请参阅 此 FAQ
  • 确保没有其他模块(如 mod_cgi)尝试处理 .php 扩展名。
使用 php-fpm

为了动态管理 PHP 进程,你可以安装 php-fpm,然后 启动启用 php-fpm.service

注意 你可以通过编辑 /etc/php/php-fpm.conf 文件来配置进程池中的服务器数量并调整其他配置选项。有关 php-fpm 的更多细节可以在 php-fpm 官方网站 找到。请记住,当你对 /etc/php/php.ini 进行更改时,需要 重启 php-fpm.service

/etc/lighttpd/conf.d/fastcgi.conf 中添加

server.modules += ( "mod_fastcgi" )

index-file.names += ( "index.php" ) 

fastcgi.server = (
    ".php" => (
      "localhost" => ( 
        "socket" => "/run/php-fpm/php-fpm.sock",
        "broken-scriptfilename" => "enable"
      ))
)

uWSGI

/etc/lighttpd/lighttpd.conf 中添加

server.modules += ("mod_scgi")

$HTTP["url"] =~ "^/uwsgi/" {
    scgi.protocol = "uwsgi"
    scgi.server   = (
        "/uwsgi/foo" => ((
            "socket"            => "/path/to/socket",
            "check-local"       => "disable"
        )),
        "/uwsgi/bar" => ((
            "host"              => "127.0.0.1",
            "port"              => "8080",
            "check-local"       => "disable"
        ))
    )
}

然后你可以将 uwsgi 应用程序作为 systemd 单元直接 启动。[1] 是来自 digitalocean 的一个很棒的指南,介绍了如何从零开始设置 flask 应用程序。

输出压缩

复制示例配置文件

# mkdir /etc/lighttpd/conf.d
# cp /usr/share/doc/lighttpd/config/conf.d/deflate.conf /etc/lighttpd/conf.d/

/etc/lighttpd/lighttpd.conf 中添加以下内容

include "conf.d/deflate.conf"

最后,重新加载 lighttpd.service,它将动态压缩纯文本和 HTML 内容。

注意 你也可以不这样做(不复制 deflate.conf),而是直接在 /etc/lighttpd/lighttpd.conf 中添加所需内容。

还可以选择需要压缩的内容类型。修改 /etc/lighttpd/conf.d/deflate.conf 中的 deflate.mimetypes 参数

deflate.mimetypes = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml")

你也可以创建缓存目录来存储压缩文件

# mkdir /var/cache/lighttpd/compress
# chown http:http /var/cache/lighttpd/compress

然后取消注释并修改 /etc/lighttpd/conf.d/deflate.conf 中的 deflate.cache-dir 选项

deflate.cache-dir = "/var/cache/lighttpd/compress"

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.