1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

S3のインターフェイスエンドポイントを構築して、閉域から署名付きURLを利用できるか検証する

1
Posted at

はじめに

S3の署名付きURLは、URLに含まれる署名で認証するため、取得する側にS3の権限がなくてもオブジェクトを取得できます。インターネットに接続できないVPCでは、S3への通信をVPCエンドポイント経由にする必要があります。インターフェイスエンドポイントには、エンドポイント固有のDNS名が割り当てられます。署名付きURLはホスト名も署名の対象になるため、今回はインターフェイスエンドポイントだけの構成で、署名付きURLのホスト名と名前解決の組み合わせを検証しました。

検証環境

検証環境の構成は下記の通りです。

aws01.png

リソース 内容
VPC 10.0.0.0/16。プライベートサブネットのみ
S3のインターフェイスエンドポイント セキュリティグループで443番ポートを許可。プライベートDNSは無効で作成
Systems ManagerのVPCエンドポイント ssm、ssmmessages、ec2messagesの3つ。Session ManagerでEC2に接続するために使用
EC2 Amazon Linux 2023。IAMロールはAmazonSSMManagedInstanceCoreのみで、S3の権限は付与しない
S3バケット テスト用のファイル(test2026.txt)を1つ配置

インターネットゲートウェイ、NATゲートウェイ、S3のゲートウェイエンドポイントは作成していません。署名付きURLはCloudShellで発行し、EC2からcurlで取得します。

① S3のインターフェイスエンドポイントのDNS名で署名付きURLを発行する

名前解決と通信の流れは下記の通りです。

fig01.png

S3のインターフェイスエンドポイントのDNS名を確認する

CloudShellでS3のインターフェイスエンドポイントのDNS名を確認します。

aws ec2 describe-vpc-endpoints --region ap-northeast-1 \
  --filters Name=service-name,Values=com.amazonaws.ap-northeast-1.s3 Name=vpc-endpoint-type,Values=Interface \
  --query 'VpcEndpoints[].{Id:VpcEndpointId,Dns:DnsEntries[0].DnsName,PrivateDns:PrivateDnsEnabled}' --output table
+--------------------------------------------------------------------------+-------------------------+--------------+
|                                   Dns                                    |           Id            | PrivateDns   |
+--------------------------------------------------------------------------+-------------------------+--------------+
|  *.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.ap-northeast-1.vpce.amazonaws.com  |  vpce-xxxxxxxxxxxxxxxxx |  False       |
+--------------------------------------------------------------------------+-------------------------+--------------+

CloudShellで署名付きURLを発行する

先頭の*をbucketに置き換えたDNS名を--endpoint-urlに指定して、署名付きURLを発行します。

aws s3 presign s3://<バケット名>/test2026.txt --region ap-northeast-1 \
  --endpoint-url https://bucket.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.ap-northeast-1.vpce.amazonaws.com \
  --expires-in 600
https://bucket.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.ap-northeast-1.vpce.amazonaws.com/<バケット名>/test2026.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Date=...&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=...&X-Amz-Signature=...

バケット名がパスに入る形式で発行されます。

EC2から署名付きURLでファイルを取得する

EC2でS3のインターフェイスエンドポイントのDNS名を名前解決し、curlで署名付きURLにアクセスします。

getent hosts bucket.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.ap-northeast-1.vpce.amazonaws.com
curl -v -o /tmp/case1.txt "<署名付きURL>"
10.0.x.x        bucket.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.ap-northeast-1.vpce.amazonaws.com

*   Trying 10.0.x.x:443...
* SSL connection using TLSv1.3 / TLS_CHACHA20_POLY1305_SHA256 / x25519 / RSASSA-PSS
*   subjectAltName: "bucket.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.ap-northeast-1.vpce.amazonaws.com" matches cert's "bucket.vpce-xxxxxxxxxxxxxxxxx-xxxxxxxx.s3.ap-northeast-1.vpce.amazonaws.com"
< HTTP/1.1 200 OK
< Server: AmazonS3
< Content-Length: 8

S3のインターフェイスエンドポイントのIPアドレスに解決され、200が返ってファイルを取得できました。EC2のIAMロールにS3の権限は付与していません。

② 通常のS3のDNS名ではS3に接続できないことを確認する

名前解決と通信の流れは下記の通りです。

fig02.png

--endpoint-urlを指定せずに発行すると、署名付きURLのホスト名は<バケット名>.s3.ap-northeast-1.amazonaws.comになります。プライベートDNSが無効のため、EC2ではパブリックIPアドレスに解決されます。接続の段階で失敗するため、署名なしのURLで確認しています。

getent hosts <バケット名>.s3.ap-northeast-1.amazonaws.com
curl -v --max-time 10 -o /dev/null https://<バケット名>.s3.ap-northeast-1.amazonaws.com/test2026.txt
52.219.x.x      s3-r-w.ap-northeast-1.amazonaws.com <バケット名>.s3.ap-northeast-1.amazonaws.com
3.5.x.x         s3-r-w.ap-northeast-1.amazonaws.com <バケット名>.s3.ap-northeast-1.amazonaws.com

*   Trying 16.15.x.x:443...
*   Trying 52.219.x.x:443...
*   Trying 3.5.x.x:443...
* Connection timed out after 10001 milliseconds
curl: (28) Connection timed out after 10001 milliseconds

インターネットへの経路がないため、タイムアウトしました。①で取得できたのは、S3のインターフェイスエンドポイントを経由したためです。

③ S3のインターフェイスエンドポイントのプライベートDNSを有効にする

名前解決と通信の流れは下記の通りです。

fig03.png

S3のインターフェイスエンドポイントのDNSの設定を変更する

プライベートDNSを有効にすると、プライベートDNSの「インバウンドエンドポイントのみ」の設定(PrivateDnsOnlyForInboundResolverEndpoint)も既定で有効になります。この設定が有効の場合、VPC内からの通信はゲートウェイエンドポイントを経由します。今回はゲートウェイエンドポイントを作成していないため、この設定を無効にしてプライベートDNSを有効にします。

aws ec2 modify-vpc-endpoint --region ap-northeast-1 --vpc-endpoint-id vpce-xxxxxxxxxxxxxxxxx \
  --private-dns-enabled --dns-options PrivateDnsOnlyForInboundResolverEndpoint=false

変更後、状態がpendingからavailableになるまで数分かかりました。

aws ec2 describe-vpc-endpoints --region ap-northeast-1 --vpc-endpoint-ids vpce-xxxxxxxxxxxxxxxxx \
  --query 'VpcEndpoints[].[State,PrivateDnsEnabled,DnsOptions.PrivateDnsOnlyForInboundResolverEndpoint]' --output text
available       True    False

EC2とCloudShellで通常のS3のDNS名を名前解決する

EC2では、通常のS3のDNS名がS3のインターフェイスエンドポイントのIPアドレスに解決されます。

[EC2]
10.0.x.x        <バケット名>.s3.ap-northeast-1.amazonaws.com

同じDNS名をVPCの外にあるCloudShellで名前解決すると、パブリックIPアドレスが返ります。

[CloudShell]
16.15.x.x       s3-r-w.ap-northeast-1.amazonaws.com <バケット名>.s3.ap-northeast-1.amazonaws.com

EC2から通常のS3のDNS名の署名付きURLでファイルを取得する

--endpoint-urlを指定せずに署名付きURLを発行します。

aws s3 presign s3://<バケット名>/test2026.txt --region ap-northeast-1 --expires-in 1800
https://<バケット名>.s3.ap-northeast-1.amazonaws.com/test2026.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&...&X-Amz-SignedHeaders=host&...&X-Amz-Signature=...

EC2からcurlでアクセスします。

*   Trying 10.0.x.x:443...
*   subjectAltName: "<バケット名>.s3.ap-northeast-1.amazonaws.com" matches cert's "*.s3.ap-northeast-1.amazonaws.com"
< HTTP/1.1 200 OK

通常のS3のDNS名の署名付きURLのまま、S3のインターフェイスエンドポイントを経由してファイルを取得できました。

おわりに

S3のインターフェイスエンドポイントだけの構成で、閉域から署名付きURLを利用できることを確認しました。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?