ELBをNLB(non SSL Termination)からNLB(on SSL Termination)にオンラインで変更したよ

# 対応にあたる経緯
以前の [ELBをCLB(Classic Load Balancer)からNLB(Network Load Balancer)にオンラインで変更した時のメモ - Qiita](https://qiita.com/takarake/items/c35c2f65ab1b16b2ab3e) の対応以後、SSL TerminationがEC2内で行われることから、その負荷に対応するためにインスタンスタイプを上げたり、EC2内でnginxへSSLの設定を加えたり、毎年なり２年おきなりにSSL証明書の更新作業が入って、運用コストがかかっていまして、、、
あー、、、ACMで自動更新できるようにならないかなー :sweat: ってずっと思ってたんですが、先日、AWSから下記のアップデートが :exclamation: :exclamation: :exclamation: 

[Network Load Balancer が TLS ターミネーションのサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2019/01/network-load-balancer-now-supports-tls-termination/)

お、これは :exclamation:  :eyes: ということで、軽く検証したところ、SSL証明書をACM化できちゃいました :thumbsup: 
ということで早速、ちょうどSSL証明書の期限切れアラートがきているシステムがあるので、実際に本番へ反映しちゃいます 

# 対応手順の前に取り急ぎ検証した手順 :star: 
<font color="Red">※今の本番URL（www.XXXXXXX.jp）とは別で（nlb.XXXXXXX.jp）にてアクセスできるようにAWS管理コンソールを色々触りますので注意</font>

###1. まずは下記のデモの手順にそって新しいNLBを作成します。
- [AWS Elastic Load Balancer Demos](https://network.exampleloadbalancer.com/nlbtls_demo.html)
- NLB作成時にElastic IPが１つ以上必要なので、作成しました。（ケチって１つだけにしてます :grin: ）
- NLBへセットするリスナーにて、新しいターゲットグループも作成しました。

###2. 作成したNLBへ現在の本番のNLBに接続されているプロキシサーバをぶらさげます。
- せっかくNLBにて `SSL Termination` してくれるのであれば、それ以降のバックエンドではHTTPでいいだろってことでポートも `80` にします。
- ターゲットグループでステータスが `healthy` にならなくて少しハマりました。。。。 :sweat: 
    - 原因は受け側にいるEC2 の SG（セキュリティグループ）にて、80ポートの解放を NLBを配置した subnetのCIDRからアクセスできるように設定する必要があった感じでした :boom: 

###3. また、EC2で動いている nginx でも `80` でアクセスして動作するような設定が必要ということで、取り急ぎ、 `/etc/nginx/conf.d/XXXX-http.conf` をコピーで作成して設定

```bash:/etc/nginx/conf.d/XXXXXXX-http.conf
server {
    listen       80;
    server_name  nlb.XXXXXXX.jp;

<後はコピー元と同じ>
```

###4. んで、nginx再起動でできあがりです :rocket: 

```
$ sudo service nginx reload
```

本当にできてるのか？って思ったので、下記の資料の方法を使って、SSL通信でなくて、HTTPでアクセスされるのかをアクセスログを見て、チェックしました。
SSLじゃない場合は `-[ハイフン]` で出るんですね。勉強になります :notebook:  

- [security - How can I let nginx log the used SSL/TLS protocol and ciphersuite? - Server Fault](https://serverfault.com/questions/620123/how-can-i-let-nginx-log-the-used-ssl-tls-protocol-and-ciphersuite)


# ってことで次は本番反映にトライ！
検証はできたので、次はじゃあどうやってオンラインで変更するか :exclamation: :question: ですよね
どうやってやろうかなーってことで、下記の前提条件がありながら、下記の手順を考えました :exclamation: :thinking: 

## 前提条件と必要条件
- 今のNLBのグローバルIPは変えたくない
    - 理由は外部からシステムへアクセスする方がVPNをはってアクセスしてくる際に、またルーティングの変更が必要になる。
- NLBのリスナーは複数作成できそうだったので、試したが同じポートだと作成できない。。。やろうとしたらエラーになっちゃいました・・・ :sweat: 
    - 現在：TCP:443
    - 作成トライしたやつ：TLS:443
- せっかくNLBで Termination してくれるんだからバックエンドはもう http にしたい。
- バックエンドのnginxはHTTPS、HTTPの両方で動く状態にしておく。具体的には下記。

```
server {
    listen       80;
    listen       443 ssl;
    server_name  clb.XXXXXXX.jp  www.XXXXXXX.jp;

# ここはコメントアウトしてね
#    ssl                  on;
    ssl_certificate      /etc/pki/tls/certs/XXXXXXX.pem;
    ssl_certificate_key  /etc/pki/tls/certs/XXXXXXX.key;
    ssl_session_timeout  10m;
    ssl_session_cache shared:SSL:10m;
    ssl_protocols  SSLv2 TLSv1.2;
```

## 対応手順
1. まずは新しく、CLB（Classic Load Balancer）を作成。　<font color="Red">※これを選んだのは単純に使い慣れてるのと、コンソール上でわかりやすいからでしたw</font>
2. 作成できたら今のプロキシEC2をぶらさげて下記を対応
    - CLBへ今回反映しようとしているACMのSSL証明書を設定
    - SG（セキュリティグループ）は取り急ぎ社内LANからのHTTPSを解放
    - ぶらさげたEC2のSGへは社内LANからのHTTPSを解放したSGを送信元としたHTTPを解放するように設定
    - `clb.XXXXXXX.jp`で、このCLBのエンドポイントが名前解決されるようにRoute53へCNAMEレコード追加(Aレコードでもできた)
    - https://clb.XXXXXXX.jp でアクセスできるかチェック
3. 今、NLBにぶらさがってるプロキシEC2のSGをCLBへも設定
4. Route53で`www.XXXXXXX.jp` の名前解決先をCLBへ変更
    - これで、アクセスの許可されたユーザが社外からの場合はVPNのルーティングが要変更だが、社内からのアクセスは可能となります
5. NLBへのアクセスがなくなった時点で、NLBの設定変更に着手
    - リスナーにて、TCP:443からTLS:443へ設定を変更し、新しく作成したACMを設定。
    - ぶら下がってるEC2のSGにて、一時的にHTTPを全解放するように設定
6. Route53で`clb.XXXXXXX.jp`にてNLBのエンドポイントに名前解決されるように設定し、アクセス確認
7. 問題なければ、Route53にて、`www.XXXXXXX.jp`の名前解決先をNLBへ変更して、アクセスできれば完了！
8. 一時的に解放したHTTPの全解放をクローズしてアクセス確認
9. 問題なければ、Route53で`clb.XXXXXXX.jp`の削除
10. 最初に作成したCLBの削除などでお片づけして終了 :heart: 

これでちゃんと、Amazon発行の証明書になります！
そして、SSL証明書の年間費用は不要となりましたとさ :exclamation: めでたし、めでたし :smile: 

# 参考資料
- [Network Load Balancer が TLS ターミネーションのサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2019/01/network-load-balancer-now-supports-tls-termination/)
- [AWS Elastic Load Balancer Demos](https://network.exampleloadbalancer.com/nlbtls_demo.html)
- - [security - How can I let nginx log the used SSL/TLS protocol and ciphersuite? - Server Fault](https://serverfault.com/questions/620123/how-can-i-let-nginx-log-the-used-ssl-tls-protocol-and-ciphersuite)