Apache2.4.37でTLS1.3

この記事はMicroAd Advent Calendar 2018の3日目の記事です。
#はじめに
「なあ、TLS1.3が出たのは知っているか。当然我が社でも対応は進めるんだろ？あぁん？」
#試す
そんなこと言う上司は見たこと無いけど対応してみます。政治的なあれは関係なくApacheです。

環境：Amazon linux2

yumだけで簡単にポチポチできなかったのでソースからやらないといけないやつですね。
まずは適当なサイズのインスタンス立ち上げてログインします。そしてコンパイル用にgccをインストールしておきます。
※試すだけなのですべてrootで作業してます

```shell-session
# yum install gcc
```
### openessl-1.1.1のインストール
OpenSSLのサイトからTLS1.3対応した1.1.1をダウンロードしてきます。

```shell-session
# cd /usr/local/src/
# wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz
```

展開してコンパイル、インストール先を--prefixで指定してます。

```shell-session
# tar xfvz openssl-1.1.1a.tar.gz 
# cd openssl-1.1.1a/
# ./config --prefix=/usr/local/openssl-1.1.1
# make
# make install
```
共有ライブラリを設定

```shell-session
# echo /usr/local/openssl-1.1.1/lib > /etc/ld.so.conf.d/openssl-1.1.1.conf
# ldconfig 
```

確認

```shell-session
# /usr/local/openssl-1.1.1/bin/openssl version
OpenSSL 1.1.1a  20 Nov 2018
# /usr/local/openssl-1.1.1/bin/openssl ciphers -v TLSv1.3
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD
```
これでTLS1.3が使えるOpenSSLの準備ができました。
次はApacheのインストールです。

###Apache2.4.37のインストール

実はAmazon Linux2にはApacheのhttp/2化が簡単にできるlibnghttp2, mod_http2がyumで入れられるんです！どうせならhttp/2に対応させたいのでこれをそのまま流用しちゃいましょう。

```shell-session
yum install libnghttp2-devel
yum install apr-devel apr-util-devel
```

ダウンロード

```shell-session
# cd /usr/local/src/
# wget http://ftp.jaist.ac.jp/pub/apache//httpd/httpd-2.4.37.tar.gz
# tar xfvz httpd-2.4.37.tar.gz 
```

コンパイルします。このとき`--enable-ssl`でSSLを有効化して、`--with-ssl`で先程のOpenSSLを指定します。あとはhttp/2も有効化したいので`--enable-http2`を付けてます。

```shell-session
# cd httpd-2.4.37/
# ./configure \
   --prefix=/usr/local/httpd24 \
   --enable-http2 \
   --enable-ssl \
   --with-ssl=/usr/local/openssl-1.1.1 \
   --enable-so \
   --enable-mods-shared=reallyall \
   --enable-mpms-shared=all 
```

これでインストール完了ですが、設定をいじる前にオレオレ証明書を作ります
###オレオレ証明書
せっかくなのでインストールしたOpenSSLを使ってみます。まあ特に差はないんだけど。

秘密鍵の作成

```shell-session
/usr/local/openssl-1.1.1/bin/openssl genrsa -out /etc/pki/tls/private/server.key 2048
```


署名リクエストの作成、対話が面倒なので`--subj`で適当に指定

```shell-session
/usr/local/openssl-1.1.1/bin/openssl req -new -key /etc/pki/tls/private/server.key -out /etc/pki/tls/private/server.csr -subj "/C=JP/ST=Tokyo/O=organization/CN=hoge.example.com" 
```


証明書の作成

```shell-session
/usr/local/openssl-1.1.1/bin/openssl x509 -days 3650 -req -signkey /etc/pki/tls/private/server.key -in /etc/pki/tls/private/server.csr -out /etc/pki/tls/private/server.crt
```

###Apache設定
ほんと雑に動くだけの設定です。

```shell:/usr/local/httpd24/conf/httpd.conf
94行目 セッションキャッシュモジュールの有効化
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so

155行目　SSLモジュールの有効化
LoadModule ssl_module modules/mod_ssl.so

161行目　HTTP/2モジュールの有効化
LoadModule http2_module modules/mod_http2.so

536行目
Include conf/extra/httpd-default.conf

534行目
Include conf/extra/httpd-ssl.conf

```


```shell:/usr/local/httpd24/conf/extra/httpd-ssl.conf
144行目 上記で作った証明書
SSLCertificateFile "/etc/pki/tls/private/server.crt"

154行目 上記で作った秘密鍵
SSLCertificateKeyFile "/etc/pki/tls/private/server.key"

VirtualHost内のどこかで下記１行を追加、</VirtualHost>の上とかでよいかも
Protocols h2 http/1.1
</VirtualHost>
```

設定の確認

```shell-session
# /usr/local/httpd24/bin/apachectl configtest
Syntax OK
```

起動

```shell-session
# /usr/local/httpd24/bin/apachectl start
```
###クライアント（Chrome）からの確認
ツールメニューから「その他のツール」→「デベロッパーツール」を開きます
![スクリーンショット 2018-12-03 17.51.28.png](https://qiita-image-store.s3.amazonaws.com/0/21170/f33cd886-984f-6348-e2e9-029f5f0d93e0.png)
プロトコルがHTTP/2ですね。そして[Security]タブをクリックするとConnection項目があります。
![スクリーンショット 2018-12-03 19.12.18.png](https://qiita-image-store.s3.amazonaws.com/0/21170/9be3b781-2b81-6914-c59c-c43712094b09.png)


TLS1.3になってますね。
当然オレオレ証明書なのでCertificateはエラーになります。。

###サーバ側確認
デフォルトでSSLのSSL_PROTOCOL, SSL_CIPHERのログが出ているのでそこを確認

```shell-session
# tail /usr/local/httpd24/logs/ssl_request_log 
[03/Dec/2018:08:42:54 +0000] xx.xx.xx.xx TLSv1.3 TLS_AES_256_GCM_SHA384 "GET / HTTP/2.0" 45
```
プロトコルがTLSv1.3でCipher SuiteがTLS_AES_256_GCM_SHA384ですね。
こんな具合でTLS1.3環境を構築して、接続の確認ができました。

#まとめ

実際のところ表面的にTLS1.3ですよ！っていうものはなく、こう言うのも何なんですが一般的には気にしなくてもいい部分かと。きっとそのうちCDN側で対応していくと思うし。（すでに対応しているところもありますが。）

ハンドシェイク周りやCipher Suiteも変わっているし、本当は負荷もガッツリ検証したかったんですが時間がなかったのでまた今度。