AWS EC2上のApache HTTPDでHTTP/2に対応する方法まとめ
こんにちは、irucaです。
最近HTTP/2の機能が気になってきたので自分のサーバでサクッと試してみました。
AWSのEC2インスタンスを使って、Amazon Linuxで動かしています。
CentOS6でも同じ操作になるかと思います。
[root@ip-172-31-25-63 conf.d]# cat /etc/system-release Amazon Linux AMI release 2017.03
まずHTTP/2の機能を試す前提として、HTTPSで自分のサーバにアクセスできるように準備が整っている必要があります。
www.iruca21.com
こちらの記事を参考に、HTTPS用のSSL証明書作成などを終えておきましょう。
mod_http2有効化のためのhttpdビルド
webサーバとしてApache httpd 2.4 を使う前提で書いています。
自分の前の記事でhttpd24をインストールさせておいて心苦しいですが、
残念ながら私が調べたところ2017年8月現在yumなどのパッケージ管理ツールを使ってApache httpd上でhttp2を簡単に有効化する方法はないです。
mod_http2をインストールすることを念頭に、Apache httpd2.4の最新版をソースからビルドしていく方法をとります。
色んな記事を調べた結果、Amazon Linux上からやる人は下記の記事がもっともハマりポイントが少なく、
最短でhttpdをビルドできました。
blog.apar.jp
この記事で詰まるところがあるとすれば、すでにhttpd v2.4.23は脆弱性が発見されたためアップロードされておらず、
wget http://ftp.riken.jp/net/apache//httpd/httpd-2.4.23.tar.gz
の箇所を
wget http://ftp.riken.jp/net/apache//httpd/httpd-2.4.27.tar.gz
など、最新のバージョンに変更する必要があるくらいです。
こちらを参考に、openssl1.0.2, nghttp2, apr, apr-util, httpdと順を追ってビルド、インストールしていきましょう。
少なくとも私のAmazon Linuxでは全くつまづくことなくhttpdインストールまではできました。
httpd設定
インストールはできましたが、httpd起動・終了やその他細々とした設定がまだできていません。
下記の手順を参考にしながら自分なりにチューニングしてみてください。
httpdにパスを通す
上記手順通りにやれば /usr/local/apache2/ 配下にソースからビルドしたhttpdがインストールされているかと思います。
まずはインストール先のhttpdをPATHに通しておきましょう。
echo "export PATH=\$PATH:/usr/local/apache2/bin" > /etc/profile.d/httpd2-4-27.sh source /etc/profile.d/httpd2-4-27.sh
サービス起動・終了スクリプトなどを作る
yum install httpd24
でhttpdをインストールしたたときには、ソースコードをビルドしたものだけでなく、サービス起動・終了用のスクリプトやlogrotateの設定、デフォルトのhttpd.confの設定などが入りますが、ソースからビルドしてインストールしたときにはそういったものが入りません。
yumでインストールしたとき相当のファイルも欲しいひとは、下記の方法でhttpdのRPMパッケージに含まれているファイルが得られるのでローカルに移動しましょう。
mkdir /tmp/httpd24-test cd /tmp/httpd-24-test yum install yum-utils yumdownloader httpd24 # rpmの中身をカレントディレクトリに展開 rpm2cpio httpd24-2.4.25-1.68.amzn1.x86_64.rpm | cpio -id # 必要に応じてファイルを移動させる cp etc/rc.d/init.d/httpd /etc/rc.d/init.d/ cp etc/logrotate.d/httpd /etc/logrotate.d/
サービススクリプト(/etc/init.d/httpd)がエラーはかなくするために、
ln -s /usr/local/apache2/bin/httpd /usr/sbin/httpd
でシンボリックリンクを張り、
/etc/init.d/httpdを開いて
pidfile=から始まる行を
pidfile=${PIDFILE-/usr/local/apache2/logs/${prog}.pid}
に変えておきましょう。
/etc/httpdに設定ファイル用シンボリックリンクを作成
/usr/local/apache2 配下の設定ファイルがデフォルトで読まれるようになっているのでそちらを常に変更する癖をつけてもよいのですが、
/etc/httpd/ 配下を読む癖がついている人も多いと思うのでシンボリックリンクを張っておきます。
すでに /etc/httpd/conf, /etc/httpd/conf.d ディレクトリができてしまっている人は一度よけておいて、シンボリックリンクの先にファイルを移動させましょう。
ln -s /usr/local/apache2/conf /etc/httpd/conf ln -s /usr/local/apache2/conf.d /etc/httpd/conf.d
/etc/httpd/conf/httpd.conf修正
ソースに付属しているhttpd.confは何かとハマりポイントが多いので先にhttpd.confの下記ポイントを編集してしまいましょう。
/etc/httpd/conf -> /usr/local/apache2/conf へのシンボリックリンクは張り終えている前提です。
#LoadModule ssl_module modules/mod_ssl.so #LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
の行のコメントアウトをそれぞれ外します。
DocumentRoot "/usr/local/apache2/htdocs" <Directory "/usr/local/apache2/htdocs">
の2行を
DocumentRoot "/var/www/html" <Directory "/var/www/html">
に変更します。
コンテンツを /usr/local/apache2/htdocs に配置する癖をつけてもいいですが、
これもyumなどで今まで入れていた人向けの配慮です。
/etc/httpd/conf.d/ssl.conf
すでにhttpd 2.4をyumなどでインストールしていた状態からソースコードビルドを試した人は、
/etc/httpd/conf.d/ssl.confにすでにファイルがあり、
httpd起動時にこいつの中の文法がエラーになってしまうかと思います。
SSLPassPhraseDialog: file '/usr/libexec/httpd-ssl-pass-dialog' does not exist
と怒られることがあるので、とりあえずssl.confの中を
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
↓
SSLPassPhraseDialog builtin
と書き換えましょう。
こちらを参考にしました。
norm-nois.com
ちなみに私はapp.iruca21.comというドメインをHTTP/2テスト環境として整えようとしています。
ドキュメントは/var/www/html/http2/に置くことにします。
その場合、/etc/httpd/conf.d/ssl.confの中身は以下のようになっています。
Listen 443 https SSLPassPhraseDialog builtin SSLSessionCache shmcb:/run/httpd/sslcache(512000) SSLSessionCacheTimeout 300 SSLRandomSeed startup file:/dev/urandom 256 SSLRandomSeed connect builtin SSLCryptoDevice builtin <VirtualHost _default_:443> ServerName app.iruca21.com:443 ErrorLog logs/ssl_error_log TransferLog logs/ssl_access_log LogLevel warn SSLEngine on SSLProtocol all -SSLv3 SSLProxyProtocol all -SSLv3 SSLHonorCipherOrder on SSLCertificateFile /etc/letsencrypt/live/app.iruca21.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/app.iruca21.com/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf Protocols h2 http/1.1 H2Direct on <Files ~ "\.(cgi|shtml|phtml|php3?)$"> SSLOptions +StdEnvVars </Files> <Directory "/var/www/cgi-bin"> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog logs/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" # check if http2 is working... DocumentRoot /var/www/html/http2/ <Directory /var/www/html/http2/ > Options Indexes FollowSymLinks MultiViews AllowOverride FileInfo AuthConfig Order allow,deny allow from all </Directory> </VirtualHost>
ブラウザから信頼されるSSL証明書をすでにこちらの記事で設定済みです。
コンテンツを配置してみる
試しにこちらのページを参考に、bootstrapを使ったサンプルコンテンツを配置してみます。
techacademy.jp
index.htmlの中身はこんな感じです。
<html> <head> <title>hello http2 world</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- BootstrapのCSS読み込み --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- jQuery読み込み --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <!-- BootstrapのJS読み込み --> <script src="js/bootstrap.min.js"></script> </head> <body> <h1> Hello, HTTP/2 world!</h1> </body> </html>
bootstrapをダウンロードしてcss, jsフォルダ内にそれぞれ配置します。
結果として以下のような感じになりました。
[root@ip-172-31-25-63 http2]# pwd /var/www/html/http2 [root@ip-172-31-25-63 http2]# ls -al total 24 drwxr-xr-x 5 root root 4096 Aug 1 17:29 . drwxr-xr-x 9 root root 4096 Aug 1 00:36 .. drwxr-xr-x 2 root root 4096 Aug 1 12:51 css drwxr-xr-x 2 root root 4096 Aug 1 12:51 fonts -rw-r--r-- 1 root root 567 Aug 1 13:04 index.html drwxr-xr-x 2 root root 4096 Aug 1 12:51 js
起動してブラウザからアクセスしてみる
さて、準備は整ったので設定ファイルの文法を確認してからhttpdを起動して、
ブラウザからアクセスしてみます。
[root@ip-172-31-25-63 http2]# httpd -t Syntax OK [root@ip-172-31-25-63 http2]# service httpd start Starting httpd: [ OK ]
ちゃんとHTTP/2でアクセスできてるかどうかのChromeでの確認方法はこちらを参考にします。
CloudFrontでHTTP2対応する方法とChromeでの確認方法 - Qiita
さて、どれどれ…
おお、ちゃんとh2(http2)になってる。
満足だ。
みなさんも自分のウェブサイトをHTTP/2に対応するときの参考にしてみてください。