OpenBSD httpd 7.3: Web サーバー

nabbisen - Aug 6 '23 - - Dev Community

はじめに

OpenBSD は独自の Web サーバーを開発・維持しています。"httpd" という名前で、ISC ライセンス (英語) が適用されています。
httpd は OS インストール時に自動でインストールされます。

これはシンプルで、堅牢で、セキュアな、すばらしい Web サーバーです。
パフォーマンス面で言うと、ライバルたちと比べて最速というわけではありません。しかしながら十分な速度を有しており、且つ、現在も開発が続いています。例えば gzip 圧縮 (英語) サポートが 7.1 から実装されました。

さらには、httpd を relayd という OpenBSD 純正のリレー・デーモンと統合することで、より機能的なサーバー構成にすることもできます。

本記事で、httpd を設定して動かすための旅にお連れします。良い旅路になりますように 🐡

環境

  • OS: OpenBSD 7.3
  • Web: OpenBSD httpd

チュートリアル

設定ファイル httpd.conf の準備

httpd サービスを有効にするためには、httpd.confが必要です。
デフォルトの場所は /etc/httpd.conf です。include キーワード と組み合わせる (英語) ことも可能です:

include キーワードで、追加の設定ファイル群を include (包含) できます。一例ですが、このように書きます:

include "/etc/httpd.conf.local"

httpd.conf の作成

/etc/examples からテンプレートをコピーします:

$ doas cp -p /etc/examples/httpd.conf /etc/
Enter fullscreen mode Exit fullscreen mode

別の方法として、もちろん、手動でいちから作成することもできます:

$ doas nvim /etc/httpd.conf
Enter fullscreen mode Exit fullscreen mode

テンプレート内容

テンプレートはだいたい以下のようになっています:

# $OpenBSD: httpd.conf,v 1.22 2020/11/04 10:34:18 denis Exp $

server "example.com" {
    listen on * port 80
    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }
    location * {
        block return 302 "https://$HTTP_HOST$REQUEST_URI"
    }
}

server "example.com" {
    listen on * tls port 443
    tls {
        certificate "/etc/ssl/example.com.fullchain.pem"
        key "/etc/ssl/private/example.com.key"
    }
    location "/pub/*" {
        directory auto index
    }
    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }
}
Enter fullscreen mode Exit fullscreen mode

chroot の働きを意識しておく

"SERVERS" セクション (上記の server) において、root プロパティが意味するところを押さえておきましょう。実際は /var/www 以下のディレクトリになります。公式ドキュメントは GLOBAL CONFIGURATION (英語) セクションで次のように言っています:

chroot directory

chroot(2) するディレクトリをセットします。明示的に指定されていない場合、デフォルトの /var/www が使われます。ここは www ユーザーのホーム・ディレクトリです。

設定ファイルのカスタマイズ (オプション)

これで準備ができました。希望のサーバーを立てるために、設定ファイルを更新して行きましょう:

$ doas nvim /etc/httpd.conf
Enter fullscreen mode Exit fullscreen mode

PHP FastCGI サーバーの場合

次のようなサーバー定義を追加することになるでしょう:

server "www.https-example.domain" { 
    alias "https-example.domain" 
    listen on * port 80 
    listen on * tls port 443
    tls {
        key         "/etc/ssl/private/www.https-example.domain.key"
        certificate "/etc/ssl/www.https-example.domain.crt"
    }
    root "/htdocs/www.https-example.domain" 
}

server "www.fastcgi-tcp-example.domain" {
    alias "fastcgi-example.domain"
    listen on * port 80
    fastcgi socket tcp 127.0.0.1 8080
}

server "www.fastcgi-unix-socket-example.domain" {
    alias "fastcgi-example.domain"
    listen on * port 80
    fastcgi socket "/run/example/unix_socket.sock"
}
Enter fullscreen mode Exit fullscreen mode

TLS 接続の場合

Let's Encrypt の証明書は acme-client で取得できます。

まず /etc/examples にある設定ファイルのテンプレートをコピーします:

$ doas cp -p /etc/examples/acme-client.conf /etc/
Enter fullscreen mode Exit fullscreen mode

そして自分のサーバー向けに更新します:

$ doas nvim /etc/acme-client.conf
Enter fullscreen mode Exit fullscreen mode

さらに必要に応じて httpd サーバーも更新します:

$ doas nvim /etc/httpd.conf
Enter fullscreen mode Exit fullscreen mode

最後に以下のコマンドを実行します:

$ acme-client -vd xxx
Enter fullscreen mode Exit fullscreen mode

こちらの記事 に詳細を記しています。

httpd デーモンの有効化

httpd を有効にします:

# rcctl enable httpd
Enter fullscreen mode Exit fullscreen mode

なお初めて行う場合、次のような /etc/rc.conf.local がつくられるでしょう:

# cat /etc/rc.conf.local
httpd_flags=
Enter fullscreen mode Exit fullscreen mode

さあ、起動しましょう:

# rcctl start httpd
httpd(ok)
Enter fullscreen mode Exit fullscreen mode

別の方法: -f オプションで一時的な確認を行う

rcctl -f start httpd を実行することで、デフォルトの設定である httpd_flags=NO (有効化しない) ままで、httpd を強制的に起動することもできます。

サーバーがリッスンしていることを確認する

これで httpd サーバーが HTTP リクエストに応答するようになりました。試してみましょう。

index.html をつくります:

# mkdir -p /var/www/htdocs/www.https-example.domain
# # as needed:
# #chown www:www /var/www/htdocs/www.https-example.domain

$ echo "Hello, world. from OpenBSD httpd" > \
      /var/www/www.https-example.domain/index.html
Enter fullscreen mode Exit fullscreen mode

そしてクライアントから HTTP リエクストを送ります:

$ curl localhost:80
Enter fullscreen mode Exit fullscreen mode

GET 通信が行われます:

Hello, world. from OpenBSD httpd
Enter fullscreen mode Exit fullscreen mode

おわりに

/etc/httpd.conf を更新することで、より多くのサーバーを構築できます。
それから、多数のサーバーをホストする場合は、上述の通り include キーワードで外部ファイルに定義を切り出すこともできます。このような感じです:

  # httpd.conf
  (...)
+ include "/etc/httpd.d/another.conf"
Enter fullscreen mode Exit fullscreen mode

httpd.conf を変更した時は、デーモンの再起動を必ず行いましょう。doas rcctl restart httpd を実行することで行えます。


歴史的な背景 (参考として)

OpenBSD の httpd が登場したのは 5.6 のリリースにおいてです。同バージョンで Apache の httpd が彼らの基盤から削除されました。さらに次の 5.7Nginx も削除されました。

"ハートブリード (Heartbleed)" と "シェルショック (Shellshock)" という、脆弱性とそれらによってもたらされた恐怖を憶えているでしょうか ? この二つ、あるいは他の問題が、2014 年に起こりました。そしてサーバーにおける SSL 接続や CGI 等に悪影響が出ました。

OpenBSD プロジェクトはこの状況を改善するために最大限の努力を払いました。例えば LibreSSL を開発して、OpenSSL に代わる OpenBSD ネイティブのライブラリにしました。それからメモリ・アロケーションの方法も改善しようと努めました。彼らがネイティブの Web サーバー "httpd" を開発したのは、その過程においてのことです。

他の Web サーバーの使用

Nginx / Apach (パッケージ名 "apache-httpd") / Lighttpd / darkhttpd も OpenBSD で取得可能です。Ports システムで (ありがたいことに) パッケージとして維持されています。
いずれも pkg_add でインストールできます。
それから Caddy については、この方法は使えませんが、代わりに手動でのインストールが可能です。


Happy serving 🕊

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .