ども、大瀧です。
VPC Latticeは、VPC向けのHTTP/Sリバースプロキシサービスです。既定でAWSから提供されるエンドポイントにアクセスできるのですが、ユーザー独自のドメインを利用する様子をご紹介します。
VPC Latticeのカスタムドメイン対応
カスタムドメイン対応は非常にシンプルで、ELBと同様にエンドポイントのホスト名にCNAMEレコードを向ければOKです。設定するDNSホストゾーンはAWSに限らない一般のインターネットDNS、Amazon Route 53パブリックホストゾーンのほか、VPC内でのみ使えるAmazon Route 53プライベートホストゾーンも利用できます。
HTTPSの場合は、カスタムドメインに対応するTLS証明書をVPC Latticeサービスにセットします。現時点でVPC Latticeが対応するのは、ACM(AWS Certificate Manager)のTLS証明書です。ACMで取得できるTLS証明書のほか、自己署名や独自のTLS証明書をインポートして利用することもできます。
Route 53プライベートホストゾーンの設定例
本記事では、VPC内でのみ利用できるRoute 53プライベートホストゾーンと自己署名証明書の例を紹介します。
1. 自己署名証明書の作成とACMへのインポート
まずはHTTPS接続で利用するための自己署名証明書を作成します。HTTPのみの場合は不要なのでこの手順を飛ばしてください。今回はmkcertで作成してみます。
- 仮想マシン: Amazon EC2 東京リージョン
- OS: Amazon Linux 2023 (Arm64)
# mkcertのバイナリのダウンロード
$ curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/arm64"
# 実行権を付与してPATHの通っているディレクトリに移動
$ chmod +x mkcert-v1.4.4-linux-arm64
$ mkdir ~/.local/bin
$ mv mkcert-v1.4.4-linux-arm64 ~/.local/bin/mkcert
$ mkcert
Usage of mkcert:
$ mkcert -install
Install the local CA in the system trust store.
(略)
$ mkcert -install
今回はカスタムドメインとしてlattice.yakiniku.local
を利用します。他への利用も考えてSANsにワイルドカードをセットする証明書を作成してみます。
$ mkcert "yakiniku.local" "*.yakiniku.local"
Created a new certificate valid for the following names 📜
- "yakiniku.local"
- "*.yakiniku.local"
Reminder: X.509 wildcards only go one level deep, so this won't match a.b.yakiniku.local ℹ️
The certificate is at "./yakiniku.local+1.pem" and the key at "./yakiniku.local+1-key.pem" ✅
It will expire on 2 July 2025 🗓
$ ls
yakiniku.local+1-key.pem yakiniku.local+1.pem
$
ファイル名key
の入っている方がプライベートキー、入っていない方が証明書です。続いてAWS管理コンソールのAWS Certificate Manager (ACM)管理画面のメニューから[証明書をインポート]を選択します。証明書本文にyakiniku.local+1.pem
ファイル、証明書のプライベートキーにyakiniku.local+1-key.pem
の内容をコピペし、[次へ] - [次へ] - [インポート]とクリックしてインポートします。
これでTLS証明書の準備はOKです。
2. VPC Latticeサービスの作成とリスナーの追加
続いてVPC Latticeを構成します。以下の記事と同様にサービスネットワークとサービス、ターゲットグループを作成していきますが、記事と同じところは割愛し、差分であるVPC Latticeサービス部分を抜粋します。
サービス作成画面の[カスタムドメイン設定]にある[カスタムドメイン設定を指定]のチェックをオンにし、[カスタムドメイン名]にlattice.yakiniku.local
を入力、[カスタム SSL/TLS証明書]は先ほどインポートしたACM証明書を選択します(HTTPのみの場合は「なし」で構いません)。
これでサービスを作成します。リスナーは以下の記事と同様に404の固定レスポンスをHTTPとHTTPSの両リスナーで設定し作成しました。
% aws vpc-lattice create-listener --output text \
--name "http-80" \
--protocol "HTTP" \
--service-identifier svc-XXXXXXXXXXXXXXXX \
--default-action '{"fixedResponse":{"statusCode":404}}'
arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-XXXXXXXXXXXXXXXX/listener/listener-XXXXXXXXXXXXXXXX listener-XXXXXXXXXXXXXXXX http-80 80 HTTP arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-XXXXXXXXXXXXXXXX svc-XXXXXXXXXXXXXXXX
FIXEDRESPONSE 404
% aws vpc-lattice create-listener --output text \
--name "https-443" \
--protocol "HTTPS" \
--service-identifier svc-XXXXXXXXXXXXXXXX \
--default-action '{"fixedResponse":{"statusCode":404}}'
arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-XXXXXXXXXXXXXXXX/listener/listener-YYYYYYYYYYYYYYYY listener-YYYYYYYYYYYYYYYY https-443 443 HTTPS arn:aws:vpc-lattice:ap-northeast-1:123456789012:service/svc-XXXXXXXXXXXXXXXX svc-XXXXXXXXXXXXXXXX
FIXEDRESPONSE 404
これでOKです。
3. Route 53プライベートホストゾーンの構成
最後にRoute 53を構成します。カスタムドメインに対応するプライベートホストゾーンを作成し、VPC Latticeサービスネットワークに関連付けるVPCをセットします。
作成したホストゾーンにカスタムドメインのCNAMEレコードを設定します。
- レコード名: カスタムドメインの値
- レコードタイプ: CNAME
- 値: VPC Latticeサービスのドメイン名
これでOKです。
動作確認
関連付けたVPCに配置するEC2インスタンス(=前の手順でmkcertを実行したインスタンス)からcURLコマンドでリクエストを送出してみます。
$ curl -v http://lattice.yakiniku.local
* Trying 169.254.171.32:80...
* Connected to lattice.yakiniku.local (169.254.171.32) port 80 (#0)
> GET / HTTP/1.1
> Host: lattice.yakiniku.local
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< content-length: 9
< content-type: text/plain
< date: Sun, 02 Apr 2023 04:24:23 GMT
<
* Connection #0 to host lattice.yakiniku.local left intact
Not Found$
$ curl -v https://lattice.yakiniku.local
* Trying 169.254.171.32:443...
* Connected to lattice.yakiniku.local (169.254.171.32) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
* CApath: none
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN: server accepted h2
* Server certificate:
* subject: O=mkcert development certificate; OU=ec2-user@ip-172-31-18-179.ap-northeast-1.compute.internal (EC2 Default User)
* start date: Apr 2 02:06:52 2023 GMT
* expire date: Jul 2 02:06:52 2025 GMT
* subjectAltName: host "lattice.yakiniku.local" matched cert's "*.yakiniku.local"
* issuer: O=mkcert development CA; OU=ec2-user@ip-172-31-18-179.ap-northeast-1.compute.internal (EC2 Default User); CN=mkcert ec2-user@ip-172-31-18-179.ap-northeast-1.compute.internal (EC2 Default User)
* SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: lattice.yakiniku.local]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0xaaaaf6f707a0)
> GET / HTTP/2
> Host: lattice.yakiniku.local
> user-agent: curl/7.88.1
> accept: */*
>
< HTTP/2 404
< content-length: 9
< content-type: text/plain
< date: Sun, 02 Apr 2023 04:24:19 GMT
<
* Connection #0 to host lattice.yakiniku.local left intact
Not Found$
HTTP、HTTPSどちらも正常に接続できました!(デフォルトアクションで404固定レスポンスを設定しているので、Not Foundレスポンスが期待した挙動です)
今回はmkcertを実行したインスタンスからアクセスしたためCA認証局のエラーなしで接続できましたが、一般に自己署名証明書はHTTPSのサーバー認証で許容されずエラーになります。今回のようにCAファイルをクライアントに配布したり、サーバー認証の設定を調節する必要がある点に留意してください。もちろん、ACMや他の機関で発行した有効なTLS証明書を利用することもできます。
まとめ
VPC Latticeでユーザー独自のドメインを利用する様子をご紹介しました。AWSが発行するエンドポイントは実際に構成するまで確定しないので、VPC Latticeで独自ドメインを利用する機会は多くなるのではと想像しています。 ドメインを購入、用意できるのであれば更新の手間がある自己署名証明書よりも、自動更新機能を備えたACMの発行するTLS証明書の利用をお奨めします。