主頁 | 自己紹介 | 日記 | 農業 | 台所 | 電算機 | | 本棚 | | Git

Webサーバーの設定

はじめに

OpenBSDでWebサーバーを公開する方法のメモ。といってもmanページが完璧なのであまり書く必要はない。ドメインのあたりの知識は適当なので間違っていたらごめんなさい。コンピュータの知識は全部独学なので多少間違った理解をしていても訂正されることがない。言葉の定義等細かいことがいいかげんになりがちである。

環境

設定の概要

サーバーを用意
サーバーはウェブサイトのデータを保存し、ブラウザからアクセスされた時にそのデータを送り返すためのものである。ここではさくらのVPSを用いた。
ドメインの取得とDNSの設定
インターネット上のサーバー等はIPアドレスを用いて識別されているが、数字の羅列なので人間には覚えにくい。そのためドメイン名という、好きなアルファベットの文字列をIPアドレスと紐付ける。インターネットにはこのドメイン名を用いて紐付いたサーバーと通信できるような仕組みがあり、これをDomain Name System(DNS)という。ドメインはインターネット上で利用料を支払うことで購入できる。IPアドレスとドメイン名の紐付け等DNSの設定は基本的にはドメインを購入したサイトでできるはずである。
httpdの設定
VPS上でサーバー用のソフトウェアを設定、起動する。
証明書の発行と自動更新の設定
ウェブブラウザとサーバーの間で暗号化された通信を行うために必要なものである。
ホームページのファイルをアップロード
ウェブページで配信したいものをVPSにアップロードする。
接続の確認
手元のブラウザからアクセスできることを確認。

サーバーを用意

サーバーをどこかで契約する。ここではさくらのVPSを利用。

ドメインの取得とDNSの設定

ドメインを好きな場所で取得してDNSを設定する。さくらのドメインではドメインコントロールパネルのゾーン情報から設定できる。ここではサブドメインなしのものと、サブドメインがwwwのものを設定した。VPSのIPアドレスはVPSのコントロールパネルから確認できる。

HOST                    TYPE       POINTS TO            TTL
<server_domain>         A          <server_ip>          3600
www.<server_domain>     A          <server_ip>          3600

HOSTはサーバーのFQDN。コントロールパネル上ではサブドメインの部分だけを設定すればよい。サブドメインが無い場合は@と記入する。TYPEは設定するレコードの属性でIPv4のサブドメインを設定する場合はA。この他、IPv6用のAAAAやメールサーバー用のMX、サーバーの別名を登録するCNAME等がある。POINTS TOはサーバーのIPアドレス。TTLはDNSのキャッシュの生存時間の秒数で、DNSの登録内容を変更した際にその変更が世界中のDNSサーバーに反映されるまでにかかる最大の時間である。世界中から多くのアクセスがあるサーバーの場合、DNSの登録内容を変更する前にTTLを短かくしておかないと、キャッシュが破棄されるまでアクセス不能になる。個人のウェブページではまあそんなにアクセスもないし適当でよさそう。ここでは1時間を指定した。

この設定が反映されれば、ドメイン名からサーバーにアクセスできるようになる。

$ ping <server_domain>
PING <server_domain> (<server_ip>): 56 data bytes
64 bytes from <server_ip>: icmp_seq=0 ttl=243 time=38.032 ms
64 bytes from <server_ip>: icmp_seq=1 ttl=243 time=27.923 ms
^C

httpdの設定

VPSにログインし、httpdを設定する。まずは/etc/examples/にある設定ファイルのサンプルを/etc/にコピーして必要な部分を変更する。

$ doas cp /etc/examples/httpd.conf /etc/
vi /etc/httpd.conf
# $OpenBSD: httpd.conf,v 1.22 2020/11/04 10:34:18 denis Exp $

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

server "<server_domain>" {
	listen on * tls port 443
	tls {
		certificate "/etc/ssl/<server_domain>.fullchain.pem"
		key "/etc/ssl/private/<server_domain>.key"
	}
	location "/.well-known/acme-challenge/*" {
		root "/acme"
		request strip 2
	}
	location "*" {
		root "/htdocs/www.<server_domain>"
		directory auto index
	}
}

一つ目のserverディレクティブは80番ポートにアクセスがあった時の設定。80番ポートは暗号化なしのアクセスなので、二つ目のlocationディレクティブで暗号化ありのhttpsの方にリダイレクトさせるようにしている。一つ目のlocationディレクティブはacme-clientがサーバー証明書を発行する際にアクセスされる場所である。既定値のままにしておけばよい。二つ目のserverディレクティブは443番ポートにアクセスがあった時の設定。tlsディレクティブにおいてサーバー証明書と、暗号化に利用する鍵が設定されている。これも既定値のままでいい。locationディレクティブはウェブサーバーにアクセスがあった時の処理である。一つ目は80番ポートと同じくacme-client用。二つ目はそれ以外である。root(ドキュメントルート)はアクセスがあったときにどこのディレクトリからファイルを探すかを決めるもので、/var/wwwからの相対パスで記述する。ここでは/htdocs/www.<server_domain>にしたのでウェブページのデータは/var/www/htdock/www.<server_domain>/というディレクトリ以下に配置することになる。

ここで一度httpd-nオプションを付けて実行し、設定ファイルのミスがないか確認しておく。

$ doas httpd -n
configration OK

証明書の発行と自動更新の設定

httpsによる暗号化に対応するため、Let's Encryptを使って証明書を発行する。OpenBSDにはacme-clientという便利なスクリプトが付いてきてほぼ全部自動でやってくれる。まずはこのacme-clientの設定を変更して自分のドメインの証明書を取得するようにする。

$ doas cp /etc/examples/acme-client.conf /etc/
$ doas vi /etc/acme-client.conf
#
# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
#
authority letsencrypt {
	api url "https://acme-v02.api.letsencrypt.org/directory"
	account key "/etc/acme/letsencrypt-privkey.pem"
}

authority letsencrypt-staging {
	api url "https://acme-staging-v02.api.letsencrypt.org/directory"
	account key "/etc/acme/letsencrypt-staging-privkey.pem"
}

authority buypass {
	api url "https://api.buypass.com/acme/directory"
	account key "/etc/acme/buypass-privkey.pem"
	contact "mailto:<your_mail_address>"
}

authority buypass-test {
	api url "https://api.test4.buypass.no/acme/directory"
	account key "/etc/acme/buypass-test-privkey.pem"
	contact "mailto:<your_mail_address>"
}

domain <server_domain> {
	alternative names { secure.<server_domain> }
	domain key "/etc/ssl/private/<server_domain>.key"
	domain full chain certificate "/etc/ssl/<server_domain>.fullchain.pem"
	sign with letsencrypt
}

変更箇所はcontactの部分のメールアドレスと、domainの部分のドメイン名。

続いてacme-clientを実行して証明書を発行する。

$ doas acme-client -v <server_domain>

次にcronを用いて証明書の自動更新を行うようにする。

$ doas crontab -e
...
#minute hour    mday    month   wday    [flags] command
19 2 * * * acme-client -v <server_domain> && rcctl reload httpd
...

ここで設定した時間は適当。サーバーが暇そうな時間にする。僕のサーバーはいつも暇。

ホームページのファイルのアップロード

ウェブページに表示させたい内容のファイルをサーバーにアップロードする。試すだけであれば適当なファイルでいい。場所は今回の設定では/var/www/htdocs/www.<server_domain>/以下。ただしhttpd.confchrootや、serverディレクティブのlocationディレクティブのrootの値を変更していれば、<chroot>/<root>/にアップロードする。ここではテストのために適当なものを置いておく。

$ doas mkdir /var/www/htdocs/www.<server_domain>
$ echo '<h1>unko</h1>' | doas tee /var/www/htdocs/pub/index.html

接続の確認

最後にhttpdを起動して接続を確認する。まずはrc.conf.localhttpdの起動を許可するように記入。

$ echo 'httpd_flags=' | doas tee -a /etc/rc.conf/local

続いてrcに登録、起動。

$ doas rcctl start httpd
$ doas rcctl enable httpd

ブラウザでアクセスしてみる。

おわりに

とりあえず残したかったので書いてみたが、冒頭でも言った通り知識が曖昧であることに気づかされた。文章もいまいち分かりにくい箇所が多いがとりあえずこのまま置いておく。日記の記事ではないので気が向いたときに少しずつ改訂できればいいかな。

参考文献