LoginSignup
6
6

More than 5 years have passed since last update.

HHVM に組み込みの Proxygen で SSL/TLS や HTTP/2 を利用する

Last updated at Posted at 2016-09-26

概要

HHVM には HTTP サーバーライブラリの Proxygen が組み込まれており、コマンドラインから起動できます。Proxygen は TLS/SSL および HTTP/2 に対応しています。

PHP のビルトインサーバーは SSL/TLS、HTTP/2 に対応していないので、運用環境でHHVM を使わなくてもテスト環境での選択肢の1つとして考えることができます。HHVM のプロジェクトが配布している Docker イメージを利用することで、導入の敷居が下がります。

テスト環境のために SSL/TLS を利用するほかの選択肢として、Swoole や Event エクステンションを挙げます。コードの例はこちらの記事をご参照ください。

コマンドツールで Proxygen を起動させる

HHVM のコマンドツールから Proxygen を直接させる場合、オプションに -v Server.EnableH2C=true を指定すれば HTTP/2 が利用できます。

hhvm -m server -v Server.Type=proxygen -v Server.EnableH2C=true -p 8080

このオプションは SSL/TSL なしで HTTP/2 を利用するためにあります。主要なブラウザーは SSL/TLS なしでの HTTP/2 通信を許可しないため、curl などのコマンドツールで確認する必要があります。

SSL/TLS もサポートしてみましょう。項目が多いので、ini 設定ファイルを用意して読み込むことにします。

hhvm -m server -c hhvm.prod.ini
hhvm.prod.ini
hhvm.server.type = proxygen
hhvm.server.port = 8080

; http/2
hhvm.server.ssl_next_protocols[] = h2
hhvm.server.ssl_next_protocols[] = http/1.1

; http/2 without ssl/tls
hhvm.server.enable_h2c = true

hhvm.server.enable_ssl = true
hhvm.server.ssl_certificate_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
hhvm.server.ssl_certificate_key_file = /etc/ssl/private/ssl-cert-snakeoil.key

Ubuntu の場合、テスト用の SSL/TLS の証明書は ssl-cert パッケージから入手できます。

Docker の公式イメージを利用する

今度は Docker Hub で配布されている Docker の公式イメージを利用してみましょう。

docker-compose.ymlDockerfilehhvm.prod.inipublic/index.php を用意します。

docker-compose.yml
version: '2'

services:
  hhvm:
    build: ./
    volumes:
      - ./public:/var/www/public
    ports:
      - "80:80"
      - "443:443"
Dockerfile
FROM hhvm/hhvm-proxygen:latest
ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update && apt-get install -y ssl-cert \
  --no-install-recommends && rm -r /var/lib/apt/lists/*

ADD hhvm.prod.ini /etc/hhvm/site.ini

EXPOSE 80 443
hhvm.prod.ini
; https://github.com/hhvm/hhvm-docker/blob/master/hhvm-latest-proxygen/server.ini
; php options

pid = /var/run/hhvm/pid

; php options

pid = /var/run/hhvm/pid

; hhvm specific 

hhvm.server.port = 80
hhvm.server.type = proxygen 
hhvm.server.default_document = index.php
hhvm.server.error_document404 = index.php
hhvm.repo.central.path = /var/run/hhvm/hhvm.hhbc
hhvm.server.source_root=/var/www/public

; default log location is stdout/err, which is good for docker
hhvm.log.use_log_file = true

; http/2
hhvm.server.ssl_next_protocols[] = h2
hhvm.server.ssl_next_protocols[] = http/1.1

; http/2 without ssl/tls
hhvm.server.enable_h2c = true

; ssl/tls
hhvm.server.enable_ssl = true
hhvm.server.ssl_certificate_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
hhvm.server.ssl_certificate_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
public/index.php
<?php
phpinfo();

Docker イメージを起動させる

Docker イメージをもとにサービスを起動させます。

docker-compose up --build -d

サービスを停止させるには次のコマンドを実行します。

docker-compose stop

phpinfo 関数で ini 設定を確認する

ブラウザーから hhvml.server でページ内を検索して、ini ファイルが反映されていることを確認します。じっくり眺めていると、公式マニュアルに掲載されていない項目があるかもしれません。

curl で確かめる

curl で HEAD リクエストを送信して HTTP/2 通信ができるか確かめてみましょう。

curl --http2 -I -v http://localhost:8080

レスポンスに Upgrade: h2cHTTP/2 200 が含まれていることを確認します。

> HEAD / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.50.3
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAAQAAP__
> 
< HTTP/1.1 101 Switching Protocols
HTTP/1.1 101 Switching Protocols
< Upgrade: h2c
Upgrade: h2c
< Date: Mon, 26 Sep 2016 21:41:14 GMT
Date: Mon, 26 Sep 2016 21:41:14 GMT
< Connection: upgrade
Connection: upgrade
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=52
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!

< HTTP/2 200 
HTTP/2 200 
< vary: Accept-Encoding
vary: Accept-Encoding
< content-type: text/html
content-type: text/html
< x-powered-by: HHVM/3.15.0
x-powered-by: HHVM/3.15.0
< content-length: 50947
content-length: 50947
< date: Mon, 26 Sep 2016 21:41:14 GMT
date: Mon, 26 Sep 2016 21:41:14 GMT

今度は SSL/TLS で通信してみましょう。

curl --http2 -I -v https://localhost:8443

レスポンスに ALPN, offering h2HTTP/2 200 が含まれていることを確認します。

* Connected to localhost (127.0.0.1) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /usr/local/etc/openssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* NPN, negotiated HTTP2 (h2)
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Unknown (67):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=11687faae091
*  start date: Sep 26 19:28:39 2016 GMT
*  expire date: Sep 24 19:28:39 2026 GMT
*  issuer: CN=11687faae091
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fbf7f008800)
> HEAD / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.50.3
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
HTTP/2 200 
< vary: Accept-Encoding
vary: Accept-Encoding
< content-type: text/html
content-type: text/html
< x-powered-by: HHVM/3.15.0
x-powered-by: HHVM/3.15.0
< content-length: 50508
content-length: 50508
< date: Mon, 26 Sep 2016 21:44:20 GMT
date: Mon, 26 Sep 2016 21:44:20 GMT
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6