lighttpd

2007/10/23更新

対応バージョン: 1.4.18

事象

Mac OS X、Windows XP双方からWebDAVサーバへの接続が失敗する。

失敗時にはそれぞれ以下のようなダイアログが表示される。

Mac OS X

「ネットワーク上にサーバが見つからないため、このサーバに接続できません。後でもう一度やり直すか、別のURLを試してください。」

Windows XP

「入力したフォルダは有効ではないようです。別のフォルダを選択してください。」

サーバには以下のログが出力されている。

"OPTIONS <リクエストURL> HTTP/1.1" 200 0

また、Windowsのみ以下のログも出力されるが、これはサーバをFrontPageサーバと誤認識して同サーバの情報を得るために発行するリクエストなので、無視してよい。

"GET /_vti_inf.html HTTP/1.1" 404
"POST /_vti_bin/shtml.exe/_vti_rpc HTTP/1.1" 404

参考情報(マイクロソフト)

原因

以下のような原因が考えられる。

サーバ側でWebDAVを有効にしているパスの設定が誤っている。

単なる記述ミス以外に、例えば以下のような設定の場合、リクエストするパスの最後は「/」で終わっている必要がある(「http://foo.bar.com/public/」など)。

$HTTP["url"] =~ "^/public/" {
  webdav.activate = "enable"
:

これを「/」で終わっていてもいなくても問題なく処理できるようにするには以下のようにする。

$HTTP["url"] =~ "^/public($|/)" {
  webdav.activate = "enable"
:

2007/9/19更新

対応バージョン: 1.4.18

lighttpd.confに以下の設定を追加する。

server.modules = (
                   :
                  "mod_webdav", ← WebDAVモジュールの組み込み
                   :
                 )

$HTTP["url"] =~ "^/public($|/)" {   ← WebDAVでアクセスするパス (*)
  webdav.activate = "enable"    ← WebDAV有効化(デフォルトはdisable)
  webdav.is-readonly = "enable" ← 読み込みのみ設定(デフォルトはwritable)
}

(*) パス指定の終了パターンを「($|/)」としておくことによって、クライアントからの要求が「/」で終わっていてもいなくても問題なく動作する。

2007/9/19更新

対応バージョン: 1.4.18

バーチャルホスト毎に以下のように設定する。

$HTTP["host"] == "<アクセス先ホスト1>" {
  :
}

$HTTP["host"] == "<アクセス先ホスト2>" {
  :
}

例)

$HTTP["host"] == "aaa.bar.com" {
  server.document-root = "/public/aaa"
  server.errorlog      = "/var/log/errlog_aaa.log"
  dir-listing.activate = "enable"
}

$HTTP["host"] == "bbb.bar.com" {
  server.document-root = "/public/bbb"
  server.errorlog      = "/var/log/errlog_bbb.log"
  ssi.extension        = ( ".shtml" )
}

2007/10/23更新

対応バージョン: 1.4.18

libpcre(Perl互換正規表現ライブラリ)がインストールされていないので、インストール後に再度lighttpdをインストールする。

関連資料・記事

2007/9/19更新

対応バージョン: 1.4.18

server.pemファイルにサーバ証明書のPRIVATE KEY(秘密鍵)の設定が含まれていない。

同ファイルには以下の内容が含まれている必要があるので、例えばこれらが複数ファイルに分かれている場合は単にcatなどで1ファイルに結合すればよい。

-----BEGIN RSA PRIVATE KEY-----
:
(サーバ証明書の秘密鍵)
:
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
:
(サーバ証明書)
:
-----END CERTIFICATE-----

関連資料・記事

2007/9/19更新

対応バージョン: 1.4.18

サーバインストール時にOpenSSLが有効になっていない。

以下のオプションを付けてconfigureを行い、サーバを再インストールする。

--with-openssl=/usr/local/ssl

関連資料・記事

2007/9/19更新

対応バージョン: 1.4.18

lighttpd.confに以下の設定を追加する。

ssl.engine = "enable"
ssl.pemfile = "<サーバ証明書>"

バーチャルホスト上でSSLを使用する場合は以下のように設定する。

$SERVER["socket"] == "xx.xx.xx.xx:443" {
  ssl.engine           = "enable"
  ssl.pemfile          = "<サーバ証明書>"
  server.name          = "<サーバ名>"
  server.document-root = "<ドキュメントルート>"
}

証明書はPEM形式の必要があるが、秘密鍵(.key)と証明書(.crt)を別々に所有している場合は以下の手順で両者を結合する。

# cat server.key server.crt > server.pem

また、通常はサーバ起動時にパスフレーズの入力を求められるが、これを省略して自動起動させたい場合は多少セキュリティに難があるが以下のようにサーバ証明書の秘密鍵からパスフレーズを削除すればよい。

# mv server.key server.key.org
# openssl rsa -in server.key.org -out server.key

2007/9/19更新

対応バージョン: 1.4.18

HTML内に以下のような記述をして外部プログラムを呼び出そうとしても機能しない。

<!--#exec cmd="<コマンド>"-->

他に以下のオプションがサポートされない。

ネストされたvirtual指定
#config errmsg
#echo encoding

2007/9/19更新

対応バージョン: 1.4.18

lighttpd.confに以下の設定を追加する。

server.modules = (
                   :
                  "mod_ssi", ← SSIモジュールの組み込み
                   :
                 )

ssi.extension = ( ".shtml" ) ← SSI対象となるファイルを指定

2007/9/19更新

対応バージョン: 1.4.18

CGIは以下のように拡張子毎に特定のプログラムを割り当てることによって各CGIの内容を判断してスクリプトの場所を特定する必要がなくなり処理を高速化できる。

cgi.assign = ( ".pl"  => "/usr/bin/perl",
               ".cgi" => "/usr/bin/ruby" )

しかし、同じ拡張子でもプログラムによって動作させたい言語やパスが異なる場合は以下のようにプログラムを未設定にしておけばよい。

cgi.assign = ( ".pl"  => "/usr/bin/perl",
               ".cgi" => "" )

2007/9/19更新

対応バージョン: 1.4.18

認証方式

ユーザ認証は以下の2種類がサポートされている。

ベーシック認証
ダイジェスト認証

また、それぞれの認証方式は複数のバックエンドに対応している。

ベーシック認証

プレーンテキスト
Apache htpasswd方式
Apache htdigest方式

(*) reply attackへの対応が完全ではない。

LDAP

ダイジェスト認証

プレーンテキスト
Apache htdigest方式

以上をふまえてlighttpd.confへの具体的な設定方法を説明する。

モジュール定義

server.modules = (
                   :
                  "mod_auth",
                   :
                 )

デバッグモード

auth.debug = <設定値>

設定値

0

デバッグモードOFF

1

デバッグモードON(auth-okログのみ出力)

2

デバッグモードON(詳細ログを出力)

バックエンドタイプ

auth.backend = "<設定値>"

設定値

plain
htpasswd
htdigest
ldap

バックエンド毎設定

バックエンドの種類により、それぞれ以下の設定を追加する。

plain

auth.backend.plain.userfile = "<パスワードファイル>"

パスワードファイルは1行につき1アカウント情報を以下のフォーマットで設定する。

<アカウント>:<パスワード(平文)>

htpasswd

auth.backend.htpasswd.userfile = "<パスワードファイル>"

パスワードファイルは1行につき1アカウント情報を以下のフォーマットで設定する。

<アカウント>:<パスワード(htpasswdにて生成)>

パスワードファイルは以下の方法で生成する。

% htpasswd [-c] <パスワードファイル> <アカウント>
New password: ***** ← パスワード
Re-type new password: ***** ← パスワード
-c (create)

新規にパスワードファイルを作成する場合のオプション

htdigest

auth.backend.htdigest.userfile = "<パスワードファイル>"

パスワードファイルは1行につき1アカウント情報を以下のフォーマットで設定する。

<アカウント>:<Realm>:<パスワードを含むMD5値(htdigestにて生成)>
とはこのアカウントに紐付けるサービス名のような意味で、任意の文字列を指定してよい。またこの文字列は後述のauth.requireにて認証エリアを指定する際のRealm名としても使用し、ブラウザの認証ダイアログにも表示される。

パスワードファイルは以下の方法で生成する。

% htdigest [-c] <パスワードファイル> <Realm> <アカウント>
Adding password for neo in realm <Realm>.
New password: ***** ← パスワード
Re-type new password: ***** ← パスワード

パスワードはアカウント情報(1行分)全体をMD5で生成したダイジェスト値なので以下のようにして生成してもよい。

% echo -n "<アカウント>:<Realm>:<パスワード(平文)>" | md5sum | cut -b -32
8440869e50d27992146e9a4d87ea1a83

% echo "<アカウント>:<Realm>:<上記の文字列> >> <パスワードファイル>

ldap

まず、LDAPサーバへの接続情報を設定する。

auth.backend.ldap.hostname = "<LDAPサーバ>"
auth.backend.ldap.base-dn  = "<ベースDN>"
auth.backend.ldap.filter   = "(uid=<LDAPサーバ接続アカウント>)"

TLS(SSL)接続をする場合、以下の設定も追加する。

auth.backend.ldap.starttls = "enable"
auth.backend.ldap.ca-file  = "<LDAPサーバのCA証明書ファイル>"

認証エリア設定

認証を必要とするエリアを認証方法とともに設定する。

auth.require = ( "<認証エリア>" =>
                 (
                   "method"  => "<認証方法>",
                   "realm"   => "<Realm>",
                   "require" => "<許可アカウント>"
                 ),
                 :
                 必要数分
                 :

認証エリア

対象となるエリア(パス)

認証方法

以下のいずれか

basic

ベーシック認証

digest

ダイジェスト認証

Realm

認証ダイアログに表示されるサービス名
ダイジェスト認証の場合はパスワードファイル内のとも比較される

許可アカウント

以下のいずれか

valid-user

パスワードファイル全てのアカウントが対象

user=<アカウント>|user=<アカウント>...

パスワードファイル中の指定したアカウントのみ対象

「|」区切りで複数指定可能

例)

auth.require = ( "/pub/" =>
                 (
                   "method"  => "basic",
                   "realm"   => "download archive",
                   "require" => "valid-user"
                 ),
                 "/manager" =>
                 (
                   "method"  => "digest",
                   "realm"   => "manager area",
                   "require" => "user=manager1|user=manager2"
                 )
               )

2007/11/5更新

対応バージョン: 1.4.18

公式サイト

準備

あらかじめインストールしておくもの

libpcre

導入OS

Fedora Core 6

インストール

配布ファイル展開

% tar jxvf lighttpd-1.4.18.tar.bz2
% cd lighttpd-1.4.18

make,インストール

% ./configure <オプション>
% make
% su
# make install

デフォルトで以下のモジュール/機能が有効になる。

<モジュール>
mod_access
mod_accesslog
mod_alias
mod_auth
mod_cgi
mod_compress
mod_dirlisting
mod_evhost
mod_expire
mod_extforward
mod_fastcgi
mod_flv_streaming
mod_indexfiles
mod_proxy
mod_rrdtool
mod_scgi
mod_secdownload
mod_setenv
mod_simple_vhost
mod_staticfile
mod_status
mod_userdir
mod_usertrack
mod_webdav
<機能>
auth-crypt
compress-deflate
compress-gzip
large-files
network-ipv6

また、以下のモジュール/機能がデフォルトで無効になる。

<モジュール>
mod_cml
mod_magnet
mod_mysql_vhost
mod_redirect
mod_rewrite
mod_ssi
mod_trigger_b4_dl
<機能>
auth-ldap
network-openssl
regex-conditionals
stat-cache-fam
storage-gdbm
storage-memcache
webdav-locks
webdav-properties

インストール物 (man,infoは除く)

lighttpd本体
/usr/local/sbin/lighttpd-angel
/usr/local/sbin/lighttpd

/usr/local/bin/spawn-fcgi
モジュール
/usr/local/lib/mod_*

設定ファイル設置

# cp doc/lighttpd.conf /usr/local/etc

各種設定

/usr/local/etc/lighttpd.confにて基本的な設定を行う。以下、主な設定項目について説明する。

モジュール有効化

有効化したいモジュールのコメントを外す。また必要があれば追加する。使用可能なモジュールは/usr/local/lib/mod_*としてインストールされている。

server.modules = (
#                 "mod_rewrite",
#                 "mod_redirect",
                   :
                 )

以下のモジュールは有効化すべきである。

mod_access
mod_accesslog

また、以下のモジュールはデフォルトで有効になる。

mod_dirlisting
mod_indexfiles
mod_staticfile

尚、モジュールには記述順序があるので、以下の点に注意して記述する。

最初にmod_rewrite、mod_redirect、mod_accessといった前処理モジュールを記述する。
次にmod_authを記述する。これは以降のモジュールに影響する。
続いてmod_fastcgi、mod_cgi、mod_scgi、mod_proxyのような外部ハンドラを記述する。
最後にmod_accesslogのような後処理モジュールを記述する。

ドキュメントルート

通常のドキュメントルートを設定する。バーチャルホストの場合はserver.virtual-*で設定する。

server.document-root = "/srv/www/htdocs/"

エラーログ

エラーログの出力先を指定する。

server.errorlog = "/var/log/lighttpd/error.log"

インデックスファイル

リクエストが「/」で終わっている場合にインデックスファイルとして検索するファイルを指定する。

index-file.names = ( "index.php", "index.html",
                     "index.htm", "default.htm" )

MIMEタイプマッピング

リクエストされたファイルの拡張子とMIMEタイプのマッピングを行う。

最終行はデフォルトのMIMEタイプである。

mimetype.assign = (
  ".pdf" => "application/pdf",
  ".sig" => "application/pgp-signature",
  :
  ""     => "application/octet-stream",

アクセスログ

エラーログの出力先を指定する。

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

アクセス拒否ファイル指定

アクセスを拒否するファイルを指定する。ファイル名は一部でよい。

url.access-deny = ( "~", ".inc" )

静的ファイルの対象外となるファイルの指定

PHPやPerl、Rubyなど動的に動作するファイルを指定する。

これらはmod_fastcgi/mod_cgi配下で動作する。

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

サーバの待ち受けポート

デフォルトは80。

#server.port = 81

サーバのバインドホスト(ネットワークインタフェース)

デフォルトは全てのインタフェース。

#server.bind = "127.0.0.1"

バーチャルホスト

以下の3つのパラメータの組み合わせで設定する。

デフォルトはバーチャルホスト未設定。

#simple-vhost.server-root   = "/srv/www/vhosts/"
#simple-vhost.default-host  = "www.example.org"
#simple-vhost.document-root = "/htdocs/"

ドキュメントルートにchroot()するかどうか

デフォルトはchroot()しない。この設定はデーモン実行ユーザがrootの場合のみ有効になる。

#server.chroot = "/"

デーモン実行ユーザ/グループ

デフォルトはデーモンを実行した時のユーザ/グループ。

#server.username  = "wwwrun"
#server.groupname = "wwwrun"

デーモン実行PID

#server.pid-file = "/var/run/lighttpd.pid"

ディレクトリリスト表示可否

デフォルトは拒否。サーバからはステータスコード404が返る。

#dir-listing.activate = "enable"

各モジュール毎設定

ここでは割愛する。

動作確認

lighttpd.confで指定したログファイルの格納ディレクトリをあらかじめ作成しておく。ファイルは作成不要。

デーモンを起動する。

# /usr/local/sbin/lighttpd -f /usr/local/etc/lighttpd.conf

待ち受けポートがLISTENになっているか確認する。

# netstat -nat|egrep '(Proto|80)'
Proto Recv-Q Send-Q Local Address   Foreign Address  State      
tcp        0      0 xx.xx.xx.xx:80  0.0.0.0:*        LISTEN      

WebブラウザでlocalhostにアクセスできればOKである。

initスクリプト設置

スクリプト作成

/etc/rc.d/init.d/lighttpdを作成する。

#!/bin/bash
#
# lighttpd
#
# chkconfig: 345 80 20
# description: lighttpd server

TARGET=lighttpd
DST_PREFIX=/usr/local
DST_BIN=${DST_PREFIX}/sbin/${TARGET}
DST_CONF=${DST_PREFIX}/etc/${TARGET}.conf
DST_PIDF=/var/run/${TARGET}.pid

[ -f ${DST_BIN} ] || exit 0
[ -f ${DST_CONF} ] || exit 0

start()
{
  echo -n "Starting ${TARGET}: "
  ${DST_BIN} -f ${DST_CONF}
  echo
}

stop()
{
  echo -n "Shutting down ${TARGET}: "
  kill `cat ${DST_PIDF}`
  echo
}

restart()
{
  stop
  start
}

case "$1" in
  start)
    start
    ;;

  stop)
    stop
    ;;

  restart)
    restart
    ;;

  *)
    echo "Usage: `basename $0` {start|stop|restart}" >&2
    exit 1
esac

exit 0

サービス登録

# chkconfig --add lighttpd
# chkconfig --list lighttpd
lighttpd  0:off  1:off  2:off  3:on  4:on  5:on  6:off