2023-11-03

openSUSE: Lighttpd and Tcl CGI

Lighttpd 是一款以 BSD 授權條款開源的網頁伺服器, 設計目的以安全、快速、小巧為主要設計理念。Lighttpd 和 Nginx 都是主打性能(二者的效能在伯仲之間)的網頁伺服器, 同時在使用情況上有一定範圍的重覆,只是 Lighttpd 在開始搶佔市佔率的時候被發現有一些 memory leak 的問題, 雖然在之後陸陸續續問題有所修正,但是在之後已無法取得更多的市佔率。

即使如此,當使用的情況主要是以靜態網頁為主並且不需要太多功能(Lighttpd 的 memory leak 主要發生在動態網頁, 而 Lighttpd 在靜態網頁方面十分高效),或者是在硬體有一些限制的情況下,需要設定簡單、輕量級的網頁伺服器, 就十分適合使用 Lighttpd。另外,和 Nginx 不同的是,Lighttpd 同時支援 CGI 與 FastCGI。

Install Lighttpd (@openSUSE):

sudo zypper install lighttpd

注意:Lighttpd 的 conf 目錄在 openSUSE 權限設定為 640,所以一般使用者無法直接讀取。


使用下列的指令查看 Lighttpd 的版本資訊,有 ssl 字樣表示支援 SSL。

sudo lighttpd -v

接下來使用自簽憑證設定 HTTPS。
首先建立 ssl.conf 設定檔:

[req]
prompt = no
default_md = sha256
default_bits = 2048
distinguished_name = dn
x509_extensions = v3_req

[dn]
C = TW
ST = Taiwan
L = Taipei
O = Orange Inc.
OU = IT Department
emailAddress = admin@example.com
CN = localhost

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.localhost
DNS.2 = localhost
IP.1 = 127.0.0.1

透過指令建立開發測試用途的自簽憑證:

openssl req -x509 -new -nodes -sha256 -utf8 -days 3650 \
-newkey rsa:2048 -keyout lighttpd.key -out lighttpd.csr -config ssl.conf

可以透過以下指令查看 lighttpd.csr 內容:

openssl x509 -in lighttpd.csr -text

使用下列的指令產生 lighttpd.pem:

cat lighttpd.key lighttpd.csr > lighttpd.pem

建立 /etc/lighttpd/ssl 目錄,將 lighttpd.pem 複製到 /etc/lighttpd/ssl 目錄下。

修改 /etc/lighttpd/modules.conf,加入下列的內容:

server.modules = (
#  "mod_rewrite",
  "mod_access",
#  "mod_auth",
#  "mod_authn_file",
#  "mod_redirect",
#  "mod_setenv",
#  "mod_alias",
   "mod_openssl",
)

修改 /etc/lighttpd/lighttpd.conf,加入下列的內容:

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

Lighttpd 自 1.4.56 開始支援 HTTP/2(目前預設值為啟用)。
如果你想要嘗試 enable/disable HTTP/2,使用下列的設定:

server.feature-flags += ("server.h2proto" => "enable")

CGI

接下來加入 CGI 支援。

修改 /etc/lighttpd/modules.conf,修改並加入下列的內容:

server.modules = (
#  "mod_rewrite",
  "mod_access",
#  "mod_auth",
#  "mod_authn_file",
#  "mod_redirect",
#  "mod_setenv",
   "mod_alias",
   "mod_cgi",
   "mod_openssl",
)

修改 /etc/lighttpd/lighttpd.conf,加入下列的內容(因為要使用 Tcl 寫 CGI 程式, 所以要避免被視為靜態檔案):

static-file.exclude-extensions = ( ".tcl", ".php", ".pl", ".fcgi", ".scgi" )

Lighttpd 的 CGI 主要可以有二種風格的設定方式,一種是以 file extension 為主:

cgi.assign = ( ".tcl"  => "/usr/bin/tclsh",
               ".cgi" => "/usr/bin/tclsh" )

另外一種則是配合 mod_alias,將 CGI 程式放在 /cgi-bin:

# For execute CGI in /cgi-bin
alias.url += ( "/cgi-bin" => server_root + "/cgi-bin" )
$HTTP["url"] =~ "^/cgi-bin" {
   cgi.assign = ( "" => "" )
}

要使用何種風格的設定方式看使用者的喜好。

FastCGI

接下來是 FastCGI 的設定。
修改 /etc/lighttpd/modules.conf,修改並加入下列的內容:

server.modules = (
#  "mod_rewrite",
  "mod_access",
#  "mod_auth",
#  "mod_authn_file",
#  "mod_redirect",
#  "mod_setenv",
   "mod_alias",
   "mod_cgi",
   "mod_fastcgi",
   "mod_openssl",
)

spawn-fcgi

下面使用的方式配合 spawn-fcgi
我們需要撰寫 spawn-fcgi 的 systemd service,在 /usr/lib/systemd/system 目錄下建立 spawnfcgi.service,內容如下:

[Unit]
Description=Spawn FCGI service
After=nss-user-lookup.target

[Service]
Type=forking
Environment=WORKERS=1
ExecStart=/usr/bin/spawn-fcgi \
    -F ${WORKERS} \
    -u lighttpd \
    -g lighttpd \
    -a 127.0.0.1 -p 9000 \
    -P /var/run/%p.pid \
    -- /usr/bin/rivet-fcgi
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

(其中 -u 指定 user,-g 指定 group,隨著平台的不同可能有不同的設定。)

下面是測試我自己寫的工具 rivet-fcgi 的設定, 修改 /etc/lighttpd/lighttpd.conf

fastcgi.server = (
    ".rvt" =>
        (( "host" => "127.0.0.1",
            "port" => 9000,
            "docroot" => "/srv/www/htdocs"
        )),
    ".tcl" =>
        (( "host" => "127.0.0.1",
            "port" => 9000,
            "docroot" => "/srv/www/htdocs"
        ))
)

而後啟動(或重新啟動)spawn-fcgi 與 lighttpd 的服務,接著進行測試是否有正確設定。

php-fpm

php-fpm 設定檔在 openSUSE 主要為 /etc/php8/fpm/php-fpm.d/www.conf。在安裝以候使用預設值就可以順利執行, 如果有需要再視自己的需求修改。

修改 /etc/lighttpd/lighttpd.conf,加入下面的設定:

fastcgi.server = (
    ".php" =>
        (( "host" => "127.0.0.1",
            "port" => 9000,
            "docroot" => "/srv/www/htdocs"
        ))
)

而後啟動(或重新啟動)spawn-fcgi 與 lighttpd 的服務,接著進行測試是否有正確設定。 在 /srv/www/htdocs 目錄下建立 info.php:

<?php

phpinfo();

?>

如果瀏緊 info.php 可以得到資訊,就表示環境架設成功。

沒有留言: