OpenBSD httpd 7.3: Web サーバー
Tags: openbsd, httpd, web, server
Published: 2023-08-06 03:13:01

## はじめに

OpenBSD は独自の Web サーバーを開発・維持しています。"[httpd](https://man.openbsd.org/httpd.8)" という名前で、[ISC ライセンス (英語)](https://cvsweb.openbsd.org/src/share/misc/license.template?rev=HEAD) が適用されています。
httpd は OS インストール時に自動でインストールされます。

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

さらには、httpd を [relayd](https://man.openbsd.org/relayd.8) という OpenBSD 純正のリレー・デーモンと統合することで、より機能的なサーバー構成にすることもできます。

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

### 環境

- OS: OpenBSD [7.3](https://www.openbsd.org/73.html)
- Web: OpenBSD httpd

## チュートリアル

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

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

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

#### `httpd.conf` の作成

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

```console
$ doas cp -p /etc/examples/httpd.conf /etc/
```

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

```console
$ doas nvim /etc/httpd.conf
```

#### テンプレート内容

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

```apache
# $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
	}
}
```

#### `chroot` の働きを意識しておく

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

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

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

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

```console
$ doas nvim /etc/httpd.conf
```

#### [PHP](https://www.php.net/) [FastCGI](https://www.php.net/manual/en/install.fpm.php) サーバーの場合

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

```apache
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"
}
```

#### TLS 接続の場合

[Let's Encrypt](https://letsencrypt.org/) の証明書は [`acme-client`](https://man.openbsd.org/acme-client.1) で取得できます。

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

```console
$ doas cp -p /etc/examples/acme-client.conf /etc/
```

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

```console
$ doas nvim /etc/acme-client.conf
```

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

```console
$ doas nvim /etc/httpd.conf
```

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

```console
$ acme-client -vd xxx
```

[こちらの記事](https://obsd.solutions/ja/blog/2023/09/09/openbsd-acme-client-70-for-letsencrypt-certificates/index.html) に詳細を記しています。

### `httpd` デーモンの有効化

httpd を有効にします:

```shell-session
# rcctl enable httpd
```

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

```console
# cat /etc/rc.conf.local
httpd_flags=
```

さあ、起動しましょう:

```shell-session
# rcctl start httpd
httpd(ok)
```

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

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

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

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

`index.html` をつくります:

```console
# 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
```

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

```console
$ curl localhost:80
```

*GET* 通信が行われます:

```
Hello, world. from OpenBSD httpd
```

## おわりに

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

```diff
  # httpd.conf
  (...)
+ include "/etc/httpd.d/another.conf"
```

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

---

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

OpenBSD の httpd が登場したのは [5.6](https://www.openbsd.org/56.html) のリリースにおいてです。同バージョンで [Apache](http://httpd.apache.org/) の httpd が彼らの基盤から削除されました。さらに次の [5.7](https://www.openbsd.org/57.html) で [Nginx](https://www.nginx.com/resources/wiki/start/topics/tutorials/openbsd/) も削除されました。

"[ハートブリード (Heartbleed)](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%BC%E3%83%88%E3%83%96%E3%83%AA%E3%83%BC%E3%83%89)" と "[シェルショック (Shellshock)](https://ja.wikipedia.org/wiki/2014%E5%B9%B4%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B7%E3%83%A7%E3%83%83%E3%82%AF%E8%84%86%E5%BC%B1%E6%80%A7)" という、脆弱性とそれらによってもたらされた恐怖を憶えているでしょうか ? この二つ、あるいは他の問題が、2014 年に起こりました。そしてサーバーにおける SSL 接続や CGI 等に悪影響が出ました。

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

### 他の Web サーバーの使用

Nginx / Apach (パッケージ名 "apache-httpd") / [Lighttpd](https://www.lighttpd.net/) / [darkhttpd](https://github.com/emikulic/darkhttpd) も OpenBSD で取得可能です。[Ports](https://www.openbsd.org/faq/ports/ports.html) システムで (ありがたいことに) パッケージとして維持されています。
いずれも [`pkg_add`](https://man.openbsd.org/pkg_add) でインストールできます。
それから [Caddy](https://caddyserver.com/) については、この方法は使えませんが、代わりに手動でのインストールが可能です。

---

Happy serving 🕊