DockerのBASIC認証で作成した証明書と秘密鍵をAWS ALBで使用する方法

##初めに
以下の手順に沿って進めます。
1. dockerがインストールされたAmazon LinuxにBASIC認証を作成する
2. BASIC認証で発行された秘密鍵と証明書を使用してALBを起動する

用語や認識など間違いがありましたら教えていただけると幸いです。

##手順1 BASIC認証作成

まず初めにopenssl.cnfの253行目subjectAltNameをインスタンスのプライベートアドレスに書き換えます。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudoedit /etc/pki/tls/openssl.cnf
```

以下は書き換えた後、```cat```で表示させたものです。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ cat -n /etc/pki/tls/openssl.cnf | head -n 255 | tail -n 5
   251
   252  # Include email address in subject alt name: another PKIX recommendation
   253  subjectAltName=IP:xxx.xxx.xxx.xxx
   254  # Copy issuer details
   255  # issuerAltName=issuer:copy
```

その後、以下のディレクトリを作ります。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ mkdir certs
```

上記ディレクトリに上記証明書(domain.crt)、秘密鍵(domain.key)を作成します。
```Enter PEM pass phrase:```パスフレーズの入力を求められます。
```Verifying - Enter PEM pass phrase:```2度目の入力が求められます。同じ値を入力します。
なお、このパスフレーズは以降使用しません。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ openssl req -newkey rsa:2048 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt
Generating a 2048 bit RSA private key
........................................................................................+++
........+++
writing new private key to 'certs/domain.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
```

以下はすべて空白でエンターを押します。

```
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
```

以下ではcertsディレクトリに移動しパスフレーズを削除します。
これをしないと次のエラーによりdockerの起動に失敗します。``` msg="tls: failed to parse private key"```
```Enter pass phrase for domain.key:```では先ほどのパスフレーズを入力します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx certs]$ openssl rsa -in domain.key -out new.key
Enter pass phrase for domain.key:
writing RSA key
```

証明書をコピーします。

```
[ec2-user@ip-xxx-xxx-xxx-xxx certs]$ sudo cp certs/domain.crt /etc/pki/ca-trust/source/anchors/xxx.xxx.xxx.xxx.crt
```

再起動を行います。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo update-ca-trust enable
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo update-ca-trust
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo service docker restart
```

パスワードを作成します。
username、passwordにそれぞれユーザー名、パスワードを入力します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ docker run --entrypoint htpasswd registry:2.6.2 -Bbn username password > auth/htpasswd
```

プライベートレジストリ用のコンテナを起動します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ docker run -d -p 5000:5000 \
--restart=always \
--name registry \
-v `pwd`/auth:/auth \
-v `pwd`/certs:/certs \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
-e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt" \
-e "REGISTRY_HTTP_TLS_KEY=/certs/new.key" \
registry:2.6.2
```

ログインできることを確認します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx certs]$ docker login https://xxx.xxx.xxx.xxx:5000
Username: testuser
Password:
WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
```

##手順2 ALBを起動する

aws-cliを使用してログインします。
以下のアクセスキーXXXやシークレットアクセスキーYYYとなっている部分は、
IAM→ユーザーをクリック→認証情報をクリック　で確認できます。

```
[ec2-user@ip-xxx-xxx-xxx-xxx certs]$ aws configure
AWS Access Key ID [None]: XXX
AWS Secret Access Key [None]: YYY
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

certsディレクトリに移動しIAMに証明書をアップロードします。
my-secret-sertは証明書の名前になります。

```
[ec2-user@ip-xxx-xxx-xxx-xxx certs]$ aws iam upload-server-certificate --server-certificate-name my-server-cert \
--certificate-body file://domain.crt --private-key file://new.key 
```


ALBはVPC内にサブネットが2つ必要です。それらを作り終えたらEC2のコンソール画面に移動し、ロードバランサーをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/0ecc2fad-f91b-a8a4-4463-14b90014a3ee.png)

ALBを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/4d578306-bafd-76d8-81ea-83d005aab6cc.png)

HTTPSを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/f462129a-f025-1031-4330-7babe5fea958.png)

VPCの選択では先ほど作成したVPC、サブネットを選択します。
デフォルトの証明書の選択では、アップロードした証明書を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/82a610d1-98a1-42df-7514-b064cb9dd117.png)

ルーティングの設定を以下のように行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/9b1064ad-1855-2d9d-3680-a6d2ce824106.png)

ターゲットの登録では、選択したサブネット内のEC2をターゲットグループに登録できます。
以下のメッセージにより正常に作成されたかどうかを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7a6c6b97-51ba-7aef-f17d-6ef5b9dbdb6b.png)

##参考記事
- OpenSSL でサーバ証明書の作成  
https://rfs.jp/server/setting/ssl-openssl.html
- 四苦八苦しながらELBにSSL証明書をアップロードした話  
https://www.simpline.co.jp/tech/%E5%9B%9B%E8%8B%A6%E5%85%AB%E8%8B%A6%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89elb%E3%81%ABssl%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%9F/