最近、ハイパフォーマンスブラウザネットワーキングを読んでいて、HTTPSについてちょっと勉強しています。勉強にあたっては、実際に試せる場所があったら便利そうなので、自分のさくらVPSにHTTPSのWebサーバを設置してみることにしました。この次はHTTP2の実験もしたいので、先進的なHTTP2の機能が実装されていそうなh2oを使ってみることにしました。
環境
今回の作業は以下のような環境でやりました。
$ uname -a Linux douzemille 4.4.0-36-generic #55-Ubuntu SMP Thu Aug 11 18:01:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
準備
このあとの作業のために以下くらいのパッケージをいれておきます。h2oのmruby機能を使わないのであればruby系とbisonは不要。rotatelogsコマンドのためにapach2-utilとかもいれてます。
- cmake
- build-essential
- libyaml-dev
- ruby
- ruby-dev
- bison
- letsencrypt
- apache2-utils
h2oのビルドとインストール
オフィシャルのドキュメントが丁寧なのでその通りにやりましょう。この手順で、/usr/local
以下にインストールされます。
$ ghq get h2o/h2o $ ghq look h2o/h2o $ git checkout -b build v2.0.4 $ cmake -DWITH_BUNDLED_SSL=on . $ make $ sudo make install
h2oの基本的な設定の準備
Let's Encrypt でHTTPSの鍵を取得するためにstaticなファイルを配信するためのHTTPサーバが必要なので、そのためのh2oの設定を用意します。/usr/local/etc/h2o/h2o.conf.yml
とか好きなところに置きます。
pid-file: /run/h2o.pid error-log: "| rotatelogs /var/log/h2o/error.%Y%m%d 86400" access-log: "| rotatelogs /var/log/h2o/access.%Y%m%d 86400" listen: 80 hosts: "hakobe.douzemille.net:80": # 自分のドメインにする paths: /: file.dir: /home/yohei/web/hakobe # 配信されるファイルのおいてあるパスを指定
h2oをデーモンとして起動するためのsytemdのunit定義を準備
最近のUbuntuはsystemdというやつでデーモンの管理をしているそうです。h2oをsystemdの管理下で動作させるために、/lib/systemd/system/h2o.service
に以下のような内容のファイルを置きます。h2o systemd service file作った - うま味がない をめっちゃ参考にしてます、というかだいたいコピペです。
[Unit] Description=H2O the optimized HTTP/1, HTTP/2 server After=syslog.target network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/run/h2o.pid ExecStartPre=/usr/local/bin/h2o -c /usr/local/etc/h2o/h2o.conf.yml -t ExecStart=/usr/local/bin/h2o -c /usr/local/etc/h2o/h2o.conf.yml -m daemon ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target
ファイルをおいたら以下のようなコマンドで有効化します。
$ sudo systemctl enable h2o.service $ sudo systemctl start h2o.service $ sudo systemctl status h2o.service # これでログが見れる
ここまでで80番ポートでHTTPのサーバが起動している状態になっています。設定ファイルに書いたディレクトリ(この手順では/home/yohei/web/hakobe
にファイルをおいてうまく配信されているか確認しましょう。
Let's Encrypt からHTTPSの鍵をもらう
決められた手順でLet's Encryptとやりとりすることで、Let's Encryptによって署名されたHTTPSの鍵を取得できます(How It Works - Let's Encrypt - Free SSL/TLS Certificates で詳しい仕組みが紹介されています)。自動化されていているので、コマンドを実行するだけですぐに完了します。
ドメインの所有者であることを証明するために、そのドメインでアクセスできるHTTPサーバから鍵を配信する必要があります(そしてもちろんドメイン名から今設定しているサーバのIPが引けるように設定されている必要があります)。ここまででh2oがstaticファイルを配信できるように設定してあるので、コマンドラインのオプションから -w
オプションでファイル配信元のディレクトリを指定します。
$ sudo letsencrypt certonly --webroot -w /home/yohei/web/hakobe -d hakobe.douzemille.net
これで /etc/letsencrypt
以下に鍵や設定が保存されます。よくできてますね。
追記: ちなみにここではletsencrypt
というコマンドを使っていますが、最新版では名称が変わってcertbot
というコマンドになっています。certbotのほうが高機能なようですが、基本的な動きは変わらないようです。certbotのページから自分の使っているOSを選択するとインストール方法を紹介してくれます。Ubuntuの場合はapt-get install letsencrypt
せよと言わるのでしたがっています。
Let's Encrypt の鍵を定期更新する
Let's Encrypt の鍵は3ヶ月でexpireします。必要に応じて更新する手順も自動化されているので sudo crontab -e
とかして以下のように書いておきます。
0 4 * * * letsencrypt renew
h2oでHTTPSのサーバを起動する設定
はじめに作って、/usr/local/etc/h2o/h2o.conf.yml
とかにおいてあった設定を書き換えてHTTPSで動作するようにします。
pid-file: /run/h2o.pid error-log: "| rotatelogs /var/log/h2o/error.%Y%m%d 86400" access-log: "| rotatelogs /var/log/h2o/access.%Y%m%d 86400" listen: port: 443 ssl: certificate-file: /etc/letsencrypt/live/hakobe.douzemille.net/fullchain.pem key-file: /etc/letsencrypt/live/hakobe.douzemille.net/privkey.pem cipher-suite: "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4" cipher-preference: server hosts: "hakobe.douzemille.net:443": paths: /: file.dir: /home/yohei/web/hakobe
あれこれ書いてますが、
listen.port
を443にしてhttpsを受け付けるlisten.ssl.{certificate-file,key-file}
に鍵のファイルを指定listen.ssl.cipher-suite
で弱い暗号スイートを使わないように (参考: Let's EncryptのSSL証明書で、Qualys SSLTestでA+評価を獲得するには - Qiita )listen.ssl.cipher-preference
でサーバ側のcipher-suite
設定を優先させるように
ということをしています。省略してますが80番ポートもlistenして、httpsのURLにリダイレクトしたり Strict-Transport-Security
ヘッダを付けて返したりすると良いです。
できました
とくに何か情報のあるWebサイトではないのですが、とにかくHTTPSで配信できるようになりました。h2oを使っているのでHTTP2も喋れているようです。(HTTP/2 and SPDY indicator - Chrome Web Store で確認しています)
https://hakobe.douzemille.net/
SSL Labs によると A くらいの評価の設定にはなっているようです。がんばればA+になるらしいけどまずはこんなもんで。
これでとにかく現代的なインターネット基盤を実験してみる環境が整いました。めでたいですね。

ハイパフォーマンス ブラウザネットワーキング ―ネットワークアプリケーションのためのパフォーマンス最適化
- 作者: Ilya Grigorik,和田祐一郎,株式会社プログラミングシステム社
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/05/16
- メディア: 大型本
- この商品を含むブログ (3件) を見る