h2oによるhttp/2に対応した備忘録。 主要ブラウザは、HTTP/2に対応しているが、HTTP/2 over TLSのみなので、 SSLサーバ証明書が必要になる。 そのため、証明書には最近話題のLet’s Encrypt を利用した。
SSLサーバ証明書を発行 Let’s Encryptのソースをgitリポジトリからcloneしてくる。
1 2 # cd /usr/local/ # git clone https://github.com/letsencrypt/letsencrypt
Let’s Encrypt の依存するパッケージを自動でインストールする。
1 2 # cd letsencrypt # ./letsencrypt-auto --help
証明書を作成するために、ドメインへのアクセスがあるのでアクセスできるようにしておく。 h2oのでのアクセスログは以下のようなログだった。
1 192.168.0.1 - - [10/Feb/2016:10:04:11 +0900] "GET /.well-known/acme-challenge/4cHoLYVoyqHvhKcW7zMz08ixIUfxT3cO5uQc6wx-cYk HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
証明書発行のコマンドは以下。
1 2 3 4 5 # ./letsencrypt-auto certonly \ --webroot -w /var/www/html/example.com/ \ -d example.com \ -m hoge@example .com \ --agree-tos
なんらかの原因でアクセスできない場合は以下のようなエラーになる。
1 2 3 4 5 6 7 8 9 10 11 12 # ./letsencrypt-auto certonly --webroot -w /var /www/html/example.com/ -d example.com -m hoge@example.com --agree-tos Updating letsencrypt and virtual environment dependencies...... Requesting root privileges to run with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --webroot -w /var /www/html/example.com/ -d example.com -m hoge@example.com --agree-tos Failed authorization procedure . example .com (http-01) : urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Could not connect to http: IMPORTANT NOTES: - The following errors were reported by the server: Domain: example.com Type : urn:acme:error:connection Detail: Could not connect to http: /acme-challenge/QlsKdh9xfkuDr2mm-iIEyC58ep0tsy2gqX3K1nhJo0M
ちなみに今回は、firewallで弾かれていたので、80/443ポートを解放してあげた。
1 2 3 # firewall-cmd --permanent --add-port 80/tcp # firewall-cmd --permanent --add-port 443/tcp # systemctl restart firewalld.service
再度実行で、証明書が作成された。
1 2 3 4 5 6 7 8 9 10 11 12 13 # ./letsencrypt-auto certonly --webroot -w /var /www/html/example.com/ -d example.com -m hoge@example.com --agree-tos Updating letsencrypt and virtual environment dependencies...... Requesting root privileges to run with virtualenv: /root/.local /share/letsencrypt/bin/letsencrypt certonly --webroot -w /var /www/html/example.com/ -d example.com -m hoge@example.com --agree-tos IMPORTANT NOTES : - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2016-05-10. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you like Let's Encrypt, please consider supporting our work by : Donating to ISRG / Let's Encrypt: https: Donating to EFF: https:
証明書の実態は/etc/letsencrypt/archive/[ドメイン]
配下にでき、 /etc/letsencrypt/live/[ドメイン]
がsymlinkとなっている。設定する際は、/etc/letsencrypt/live/[ドメイン]
を利用すると良い。
h2oの設定 /etc/h2o/h2o.conf
にSSL証明書の設定をする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 http2-casper: ON http2-reprioritize-blocking-assets: ON max-connections: 128 num-threads: 1 user: nobodyhosts: "example.com" : listen: 80 listen: port: 443 ssl: certificate-file: /etc/letsencrypt/live/example.com/fullchain.pem key-file: /etc/letsencrypt/live/example.com/privkey.pem minimum-version: TLSv1 cipher-suite: ECDHE -RSA -AES128 -GCM -SHA256 :ECDHE-ECDSA-AES128-GCM-SHA256 :ECDHE-RSA-AES256-GCM-SHA384 :ECDHE-ECDSA-AES256-GCM-SHA384 :DHE-RSA-AES128-GCM-SHA256 :DHE-DSS-AES128-GCM-SHA256 :kEDH+AESGCM :ECDHE-RSA-AES128-SHA256 :ECDHE-ECDSA-AES128-SHA256 :ECDHE-RSA-AES128-SHA :ECDHE-ECDSA-AES128-SHA :ECDHE-RSA-AES256-SHA384 :ECDHE-ECDSA-AES256-SHA384 :ECDHE-RSA-AES256-SHA :ECDHE-ECDSA-AES256-SHA :DHE-RSA-AES128-SHA256 :DHE-RSA-AES128-SHA :DHE-DSS-AES128-SHA256 :DHE-RSA-AES256-SHA256 :DHE-DSS-AES256-SHA :DHE-RSA-AES256-SHA : !aNULL: !eNULL: !EXPORT : !DES : !RC4 : !3 DES: !MD5 : !PSK paths: "/" : file.dir: /var/www/html/example.com access-log: /var/log/h2o/access.log error-log: /var/log/h2o/error.log pid-file: /var/run/h2o/h2o.pid
h2oがうまく起動しない場合、 systemctl status h2o.service
で確認する。以下は、keyファイル名を間違っていて起動できなかった時のログ(h2oのログには出なかった)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # systemctl status h2o.service ● h2o.service - H2O - the optimized HTTP/1, HTTP/2 server Loaded: loaded (/usr/lib/systemd/system/h2o.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code) since 水 2016-02-10 10:27:27 JST; 1min 16s ago Process: 2496 ExecStop=/bin/kill -TERM ${MAINPID} (code=exited, status =1 /FAILURE ) Process: 9099 ExecReload=/bin /kill -HUP ${MAINPID} (code=exited, status =0 /SUCCESS ) Process: 2495 ExecStart=/usr/bin /h2o -m master -c /etc/h2o/h2o.conf (code=exited, status =78 ) Main PID: 2495 (code=exited, status =78 ) 2 月 10 10 :27 :27 example.com systemd[1 ]: Starting H2O - the optimized HTTP /1 , HTTP /2 server ... 2 月 10 10 :27 :27 example.com h2o[2495 ]: [/etc/h2o/h2o.conf:13 ] in command listen, failed to load private key file :/etc/letsencrypt/live/example.com/privkey1.pem 2 月 10 10 :27 :27 example.com h2o[2495 ]: 139896520619968 :error :02001002 :system library :fopen:No such file or directory :bio/bss_file.c :255 :fopen('/etc/letsencrypt/live/cra...1.pem' , 'r' ) 2 月 10 10 :27 :27 example.com h2o[2495 ]: 139896520619968 :error :20074002 :BIO routines:FILE_CTRL:system lib:bio/bss_file.c :257 : 2 月 10 10 :27 :27 example.com h2o[2495 ]: 139896520619968 :error :140 B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib:ssl_rsa.c :596 : 2 月 10 10 :27 :27 example.com systemd[1 ]: h2o.service: main process exited, code=exited, status =78 /n /a 2 月 10 10 :27 :27 example.com kill [2496 ]: kill : cannot find process "" 2 月 10 10 :27 :27 example.com systemd[1 ]: h2o.service: control process exited, code=exited status =1 2 月 10 10 :27 :27 example.com systemd[1 ]: Unit h2o.service entered failed state. 2 月 10 10 :27 :27 example.com systemd[1 ]: h2o.service failed . Hint: Some lines were ellipsized, use -l to show in full .
該当箇所を修正後、無事にh2oが起動した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # systemctl status h2o.service ● h2o.service - H2O - the optimized HTTP/1 , HTTP/2 server Loaded: loaded (/usr/lib/systemd/system/h2o.service; enabled; vendor preset: disabled) Active: active (running) since 水 2016 -02 -10 10 :29 :31 JST; 28 min ago Process: 2496 ExecStop=/bin/kill -TERM ${MAINPID} (code=exited, status=1 /FAILURE) Process: 3155 ExecReload=/bin/kill -HUP ${MAINPID} (code=exited, status=0 /SUCCESS) Main PID: 2523 (perl) CGroup: /system.slice/h2o.service ├─2523 perl -x /usr/share/h2o/start_server --pid-file=/var/run/h2o/h2o.pid --log -file=/var/log /h2o/error.log --port=0.0 .0 .0 :80 --port=[::]:80 --port=0.0 .0 .0 :443 --port=[::]:443 -- /usr/bin/... ├─3157 /usr/bin/h2o -c /etc/h2o/h2o.conf ├─3158 /usr/bin/h2o -c /etc/h2o/h2o.conf └─3163 perl -x /usr/share/h2o/annotate-backtrace-symbols 2 月 10 10 :29 :31 example.com systemd[1 ]: Started H2O - the optimized HTTP/1 , HTTP/2 server. 2 月 10 10 :29 :31 example.com systemd[1 ]: Starting H2O - the optimized HTTP/1 , HTTP/2 server... 2 月 10 10 :29 :31 example.com h2o[2523 ]: start_server (pid:2523 ) starting now... 2 月 10 10 :42 :03 example.com systemd[1 ]: Reloaded H2O - the optimized HTTP/1 , HTTP/2 server.
動作確認 firefoxで、httpsでアクセスしてみると、SSLにてアクセスできていることが確認出来た。
イナヅママークが青くなっていれば、http/2 でアクセスしている。 (※ firefoxのアドオン HTTP/2 and SPDY indicator をインストールする事で利用可能となる)
なお、アクセスログでも確認ができる。
1 192.168.0.1 - - [11/Feb/2016:12:40:14 +0900] "GET / HTTP/2" 200 493 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:40.0) Gecko/20100101 Firefox/40.0"
SSL証明書は以下の通り。
SSL評価 Qualys SSL Report にてSSL評価チェック。
まずまずではないだろうか。
Let’s Encrypt 自動更新設定 Let’s Encryptの証明書有効期間が90日と短いため、自動で更新されるように以下、登録する。
1 00 05 01 * * /usr/local/letsencrypt-auto certonly --webroot -w /var/www/html/example.com -d example.com -m hoge@example.com --renew-by-default && /bin/systemctl reload h2o
参照URL