2
2

NLB + API Gateway プライベート API で IPv6 からアクセスする

Last updated at Posted at 2023-10-24

やりたいこと

NLBまでの通信は、IPv6で通信し、 NLB以降の通信は、IPv4とする。
少々煩雑ですが、構成はこんなイメージです。
test.drawio (1).png

手順

VPC

VPCは既存のものを利用しましたので説明は省きます。
ない場合は、プライベートサブネットが最低2つ以上あるVPCを2つ準備しておきます。

EC2

NLBにリクエストするためにテスト用のEC2を準備しておきます。
IPv6を有効にする必要があるので以下の方の記事を参考に作成しておきましょう。

なお、セキュリティグループのアウトバウンドルールでIPv6を許可しておくことに注意が必要です。
スクリーンショット 2023-10-24 9.47.13.png

EC2の作成が完了したら、ifconfigなどで、IPv6アドレスが取得できていることを確認しておきましょう。

ifconfig
enX0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.31.19.5  netmask 255.255.240.0  broadcast 172.31.31.255
        inet6 fe80::c08:f3ff:fe7b:zzzz  prefixlen 64  scopeid 0x20<link>
        inet6 2406:da14:daa:7d00:yyyy:9f5f:c5c9:b43d  prefixlen 128  scopeid 0x0<global>

VPCエンドポイント

API GatewayのVPCエンドポイントを作成します。

サービス名にcom.amazonaws.ap-northeast-1.execute-apiを指定します。
スクリーンショット 2023-10-23 16.56.52.png

IPアドレスは固定にしておきたいため、「IPv4アドレスの指定」にチェックをいれ、「IPv4アドレス」を入力します。
スクリーンショット 2023-10-23 16.59.37.png

API Gateway と Lambda

API GatewayとLambdaは、SAMでデプロイしてしまいます。

template.yamlの プライベートサブネットid1,プライベートサブネットid2,セキュリティグループは自身のものに置き換えて下さい。
VPCエンドポイントidは先程の手順で作成しAPI GatewayのVPCエンドポイントのidに置き換えます。

後は sam build,sam deployでデプロイしておきます。

ACM

既存のものを利用するので詳しい手順は省きますが、証明書を準備していない場合は、ドキュメントを参考に準備しておきましょう。次のNLBをTLSで通すのに必要です。

NLB

先にターゲットグループを作成しておきます。

ターゲットタイプはもちろん、「IPアドレス」を指定します。
スクリーンショット 2023-10-23 21.01.52.png

「TLS 443」 を指定します。
指定するIPアドレスタイプは「IPv4」です。
VPCはNLBを配置するVPCを選択します。
スクリーンショット 2023-10-23 21.07.46.png

IPアドレスに先程作成したVPCエンドポイントのIPを登録していきます。
スクリーンショット 2023-10-23 21.10.09.png

次にNLBを作成していきます。

スキームはVPC内からのアクセスのみに許可するので、「内部」にします。
IPv4アドレスタイプはもちろん「Dualstack」を選択します。
スクリーンショット 2023-10-23 21.14.15.png

プライベートサブネットを2つ以上選択します。(画像はパブリックサブネットとなっていますが気にしないでください。)
IPv4アドレス、IPv6アドレスは本当は固定にすべきなのですが面倒だったので、動的のままにしてあります。
スクリーンショット 2023-10-23 21.14.53.png

つい最近のアップデートでNLBにセキュリティグループを適用させることができるようになりましたが、今回はシンプルにいきたいので、適用しません。
スクリーンショット 2023-10-24 18.27.07.png

「TLS 443」 を指定し、先程作成したターゲットグループを指定します。
スクリーンショット 2023-10-23 21.15.16.png

こちらは先程作成したACMの証明書を指定します。
スクリーンショット 2023-10-23 21.15.51.png

Route53

プライベートホストゾーンに、NLBを自身のドメインに対して、AAAAレコードを作成します。
スクリーンショット 2023-10-24 18.32.41.png

動作確認

まず、EC2からNLBのDNS名に対して、名前解決ができるか確認しておきます。

dig nlb-XXX.elb.ap-northeast-1.amazonaws.com. AAAA

;; ANSWER SECTION:
nlb-XXX.elb.ap-northeast-1.amazonaws.com. 55 IN AAAA 2406:da14:daa:7d00:aaa:515:446a:879e
nlb-XXX.elb.ap-northeast-1.amazonaws.com. 55 IN AAAA 2406:da14:daa:7d01:bbb:ab6d:c9f7:8dc4
nlb-XXX.elb.ap-northeast-1.amazonaws.com. 55 IN AAAA 2406:da14:daa:7d02:ccc:dde1:6d28:4840

次に自身のドメインに対して名前解決ができるか確認しておきます。

dig test.XXX.com AAAA

;; ANSWER SECTION:
test.XXX.com.    60      IN      AAAA    2406:da14:daa:7d00:aaa:515:446a:879e
test.XXX.com.    60      IN      AAAA    2406:da14:daa:7d01:bbb:ab6d:c9f7:8dc4
test.XXX.com.    60      IN      AAAA    2406:da14:daa:7d02:ccc:dde1:6d28:4840

名前解決ができることを確認できたら、早速自身のドメインに対して通信してみましょう。

curl -v https://test.XXX.com/prod/hello -H 'Host: XXX.execute-api.ap-northeast-1.amazonaws.com'

*   Trying [2406:da14:daa:7d00:aaa:515:446a:879e]:443...
* Connected to test.XXX.com (2406:da14:daa:7d00:aaa:515:446a:879e) port 443
* ALPN: curl 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.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
*  subject: CN=test.XXX.com
*  start date: Oct 23 00:00:00 2023 GMT
*  expire date: Nov 20 23:59:59 2024 GMT
*  subjectAltName: host "test.XXX.com" matched cert's "test.XXX.com"
*  issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
*  SSL certificate verify ok.
* using HTTP/1.x
> GET /prod/hello HTTP/1.1
> Host: XXX.execute-api.ap-northeast-1.amazonaws.com
> User-Agent: curl/8.3.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/1.1 200 OK
< Server: Server
< Date: Tue, 24 Oct 2023 09:43:55 GMT
< Content-Type: application/json
< Content-Length: 26
< Connection: keep-alive
< x-amzn-RequestId: f9421056-52bf-4d50-b23e-d41ae5bfcfe8
< x-amz-apigw-id: NTO6TFMqNjMFy0w=
< X-Amzn-Trace-Id: Root=1-653791db-29199c1f0b7e7f61a2ab530f;Sampled=0;lineage=9f7680ef:0
< 
* Connection #0 to host test.XXX.com left intact
{"message": "hello world"}

無事IPv6から接続できたことが確認できたと思います。

ログ

一応ログを確認しておきましょう。(ログの作成手順は省きます。)

先程AAAAレコーは確認しておきましたが、NLBからAPI Gatewayまでの通信はIPv4になるので先にNLBのAレコードも確認しておきましょう。

dig nlb-XXX.elb.ap-northeast-1.amazonaws.com.  A

nlb-XXX.elb.ap-northeast-1.amazonaws.com. 60 IN A 172.31.3.77
nlb-XXX.elb.ap-northeast-1.amazonaws.com. 60 IN A 172.31.17.207
nlb-XXX.elb.ap-northeast-1.amazonaws.com. 60 IN A 172.31.40.17

NLBのログ

EC2(2406:da14:daa:7d00:yyy:9f5f:c5c9:b43d)からNLB(2406:da14:daa:7d00:aaa:515:446a:879e)までは、IPv6で通信できていることが確認できます。

tls 2.0 2023-10-24T10:07:44 net/nlb/b2d777644ffaacc9 f25f1970aa026308 2406:da14:daa:7d00:yyy:9f5f:c5c9:b43d:53732 2406:da14:daa:7d00:aaa:515:446a:879e:443 77 37 124 352 - arn:aws:acm:ap-northeast-1:123456789012:certificate/- - TLS_AES_128_GCM_SHA256 tlsv13 - test.XXX.com - - - 2023-10-24T10:07:44

API Gatewayのログ

NLB(172.31.17.207)からアクセスが来ていることが確認できました。

 {
    "requestId": "8ecb4541-a106-40db-9785-d3b564917845",
    "ip": "172.31.17.207",
    "caller": "-",
    "user": "-",
    "requestTime": "24/Oct/2023:10:47:11 +0000",
    "httpMethod": "GET",
    "resourcePath": "/hello",
    "status": "200",
    "protocol": "HTTP/1.1",
    "responseLength": "26"
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2