ALBとバックエンドEC2間をHTTPS通信させてみた

こんにちは、コカコーラ大好きカジです。

ALBのターゲットグループ設定でHTTPSが選択できるため、バックエンドEC2とのHTTPS通信設定し通信できるのか確認してみました。

また、利用したサーバ証明書は、ALBはACM、EC2は自己証明書(オレオレ証明書)を利用してみました。

ELBとEC2間をSSL通信にしたい場合、以前だとCLB(Classic Load Balancer)では、TCPリスナーやHTTPS リスナーでBackend Certificateを利用していましたね。

構成

結果

ターゲットグループのプロトコルをHTTPSにするのみで問題なく簡単に通信できました。

前提条件

  • VPC構築済みであること
  • EC2は自己証明書(オレオレ証明書)を利用すること
  • 外部アクセス用にドメインがすでに取得済みであること(今回の私の検証環境はkajihiroyuki.classmethod.info)
  • 外部アクセス用にドメインの証明書をACMですでに発行済みであること(今回の私の検証環境は*.kajihiroyuki.classmethod.info)
  • EC2のSecurity Groupは作成済みで、443(https)のみALBからのアクセス許可済みであること

事前準備

EC2インスタンスにてHTTPSサーバの構築

EC2を2台構築しました。EC2のLaunch部分は省略します。 mod_sslをインストールすると、httpdも一緒にインストールされ、自己証明書も自動的に作成されます。

$ sudo yum install mod_ssl -y
$ sudo systemctl start httpd.service

# ALB ヘルスチェックのためにIndex.htmlを作成
$ sudo vi /var/www/html/index.html
<HTML>
Web1 または Web2
<HTML>

EC2に直接SSL通信確認

リモートマシンから、certコマンドで証明書を確認してみます。自動生成された証明書でアクセスできることを確認できます。

certコマンドはこちら

ブラウザで確認してもOKです。ブラウザの警告「x.x.x.x にアクセスする(安全ではありません)」をクリックして、Test Pageが表示できていることを確認します。

$ cert -k 52.199.37.99:443
DomainName: 52.199.37.99
IP:         52.199.37.99
Issuer:     ip-10-1-11-68.ap-northeast-1.compute.internal
NotBefore:  2019-05-03 12:06:16 +0900 JST
NotAfter:   2020-05-07 13:46:16 +0900 JST
CommonName: ip-10-1-11-68.ap-northeast-1.compute.internal
SANs:       [ip-10-1-11-68.ap-northeast-1.compute.internal]
Error:

$ cert -k 52.193.103.185:443
DomainName: 52.193.103.185
IP:         52.193.103.185
Issuer:     ip-10-1-11-211.ap-northeast-1.compute.internal
NotBefore:  2019-05-03 11:54:56 +0900 JST
NotAfter:   2020-05-07 13:34:56 +0900 JST
CommonName: ip-10-1-11-211.ap-northeast-1.compute.internal
SANs:       [ip-10-1-11-211.ap-northeast-1.compute.internal]
Error:

ALBの構築

ロードバランサーを作成

ALBを選択

名前とリスナーをHTTPSに設定し、AZを指定します。

ACMを指定します。

セキュリティグループもHTTPSのみ許可します。

ターゲットグループでHTTPSを指定します。

ターゲットにEC2を登録

Route53へDNSレコードを登録

外部からALB経由のSSL通信確認

certコマンド

$ cert alb.kajihiroyuki.classmethod.info
DomainName: alb.kajihiroyuki.classmethod.info
IP:         13.231.35.197
Issuer:     Amazon
NotBefore:  2018-10-09 09:00:00 +0900 JST
NotAfter:   2019-11-09 21:00:00 +0900 JST
CommonName: *.kajihiroyuki.classmethod.info
SANs:       [*.kajihiroyuki.classmethod.info kajihiroyuki.classmethod.info]
Error:

curlコマンド

$ curl https://alb.kajihiroyuki.classmethod.info
<HTML>
Web1
<HTML>

$ curl https://alb.kajihiroyuki.classmethod.info
<HTML>
Web2
<HTML>

curlコマンドで以下のエラーが出る場合は、AmazonLinux2のhttpdをALB経由で公開するWeb環境で発生していた、SafariのHTTPS接続エラーを改善してみた の設定を行うことで解決します。

$ curl https://alb.kajihiroyuki.classmethod.info
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

EC2のサーバー証明書をopensslで作成した自己証明書(オレオレ証明書)に変更

念のため、インスタンス構築時に自動生成された自己証明書ではなく、opensslコマンドで自分で作成した証明書でも試してみます。

秘密鍵(key)の作成

[ec2-user@ip-10-1-11-68 ~]$ cd /home/ec2-user/
[ec2-user@ip-10-1-11-68 ~]$ sudo openssl genrsa -aes128 2048 > server.key
Generating RSA private key, 2048 bit long modulus
................................+++
.....................................+++
e is 65537 (0x10001)
Enter pass phrase: パスフレーズ
Verifying - Enter pass phrase: パスフレーズ

公開鍵(csr)の作成

server.keyは先ほど作成したもの

[ec2-user@ip-10-1-11-68 ~]$ openssl req -new -key server.key > server.csr
Enter pass phrase for server.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:Chiyoda-ku
Organization Name (eg, company) [Default Company Ltd]:Classmethod,Inc.
Organizational Unit Name (eg, section) []:AWS Div
Common Name (eg, your name or your server's hostname) []:kaji.local
Email Address []:hogehoge@classmethod.jp

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: 空Enter
An optional company name []: 空Enter
[ec2-user@ip-10-1-11-68 ~]$

デジタル証明書(crt)の作成

server.key、server.csrは先ほど作成したもの

[ec2-user@ip-10-1-11-68 ~]$ openssl x509 -in server.csr -days 365000 -req -signkey server.key > server.crt
Signature ok
subject=/C=JP/ST=Tokyo/L=Chiyoda-ku/O=Classmethod,Inc./OU=AWS Div/CN=*.classmethod.info/emailAddress=hogehoge@classmethod.jp
Getting Private key
Enter pass phrase for server.key:パスフレーズ
[ec2-user@ip-10-1-11-68 ~]$

apache起動時のパスフレーズ入力を無くす方法

[ec2-user@ip-10-1-11-68 ~]$ mv -i server.key server.key.backup
[ec2-user@ip-10-1-11-68 ~]$ openssl rsa -in server.key.backup > server.key
Enter pass phrase for server.key.backup:パスフレーズ
writing RSA key
[ec2-user@ip-10-1-11-68 ~]$
[ec2-user@ip-10-1-11-68 ~]$ cd /etc/httpd
[ec2-user@ip-10-1-11-68 httpd]$ sudo mkdir certs
[ec2-user@ip-10-1-11-68 httpd]$ mv -i /etc/home/ec2-user/server.* certs/

ApacheのConfig変更

$ cd conf.d/
$ pwd
$ /etc/httpd/conf.d
$ sudo cp -ip ssl.conf ssl.conf.org
$ vi ssl.conf
以下の2箇所を書き換え
SSLCertificateFile /etc/httpd/certs/server.crt
SSLCertificateKeyFile /etc/httpd/certs/server.key
# httpdの再起動
$ sudo systemctl restart httpd

2号機側も同じ証明書ファイルを転送して同様に設定しておきます。

EC2に直接SSL通信確認

$ cert -k 52.199.37.99:443
DomainName: 52.199.37.99
IP:         52.199.37.99
Issuer:     kaji.local
NotBefore:  2019-05-03 14:55:08 +0900 JST
NotAfter:   3018-09-03 14:55:08 +0900 JST
CommonName: kaji.local
SANs:       []
Error:

$ cert -k 52.193.103.185:443
DomainName: 52.193.103.185
IP:         52.193.103.185
Issuer:     kaji.local
NotBefore:  2019-05-03 14:55:08 +0900 JST
NotAfter:   3018-09-03 14:55:08 +0900 JST
CommonName: kaji.local
SANs:       []
Error:

ALB経由での通信確認

$ curl https://alb.kajihiroyuki.classmethod.info
<HTML>
Web1
<HTML>
$ curl https://alb.kajihiroyuki.classmethod.info
<HTML>
Web2
<HTML>

EC2のアクセスログで確認

[ec2-user@ip-10-1-11-68 ~]$ sudo tail -f /var/log/httpd/ssl_access_log
10.1.11.216 - - [03/May/2019:06:24:43 +0000] "GET / HTTP/1.1" 200 19
10.1.11.216 - - [03/May/2019:06:24:45 +0000] "GET / HTTP/1.1" 200 19
<省略>

[ec2-user@ip-10-1-11-211 ~]$ sudo tail -f /var/log/httpd/ssl_access_log
10.1.11.216 - - [03/May/2019:06:23:56 +0000] "GET / HTTP/1.1" 200 19
10.1.11.216 - - [03/May/2019:06:23:56 +0000] "GET / HTTP/1.1" 200 19

簡単にALBとEC2間もHTTPS通信ができましたね。どなたかのお役に立てれば光栄です。