オフィスのみからS3へHTTPSアクセスする
コンニチハ、千葉です。
とある環境で、オフィスのみからWebアクセスしたいという要件がありました。ただ、S3はパブリック接続がデフォルトなのでどうやったらいいのか悩んでました。そこへやってきた大栗からグッドなアイデアをもらいました。で、実際試していけることが確認できたので共有しますぜぃ。
構成
構成のイメージはこれです。
- VPCエンドポイントを利用してS3へプライベート接続する
- S3バケットポリシーを利用して、特定のVPCからのみGETを許可する
- DX経由でアクセスさせるためにリバースプロキシを用意する
ポイントはリバースプロキシが必要になるところです。VPCエンドポイントは、Gateway型とInterface型の2種類あります。Interface型の場合はDX経由で接続できますが、Gateway型の場合はDX経由で接続できないので、リバースプロキシが必要になるんです。 因みにDXをパブリック接続にすることでリバースプロキシは不要になりますが、パブリック接続を利用している環境は少ないと思うのでこのような構成にしています。
やってみた
まず、S3エンドポイントを作成します。
これで、VPCからプライベートな接続でS3へアクセスできます。 次に接続対象のS3バケットポリシーを更新します。特定のVPCエンドポイントからGETを許可します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadForGetBucketObjects", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::vpc-s3-chiba/*", "Condition": { "StringEquals": { "aws:sourceVpce": "vpce-xxxxxxx" } } } ] }
リバースプロキシにはNginxを利用しました。nginx.confのデフォルトから以下のように変更しました。ハイライト部分は適宜変更します。
server { listen 80 default_server; listen [::]:80 default_server; server_name www.example.com; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { resolver 172.31.0.2 valid=5s; proxy_pass https://s3-ap-northeast-1.amazonaws.com/; }
試してみる
本来であれば、DXを通してリバースプロキシ経由でS3にアクセスしますが、環境がないのでリバースプロキシサーバからGETできるかという観点で確認しました。リバースプロキシはNginxやApacheなどを用意しましょう。
リバースプロキシにログインしてバケットにGETしてみます。
$ curl https://s3-ap-northeast-1.amazonaws.com/vpc-s3-chiba/index.html test
次に、ローカル端末からアクセスしてみます。
$ curl https://s3-ap-northeast-1.amazonaws.com/vpc-s3-chiba/index.html <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>CB134BAC5F2644F1</RequestId><HostId>Iz83iHXCIchahav16udLA0aKP9PvkvPZrm9ryrr4H9VxG3D3kYEyXrPTNkjie4pKgMZkm1LjIGM=</HostId></Error>
ローカルからだとアクセスできませんね。最後に、設定したS3バケットポリシーを削除して、リバースプロキシサーバからアクセスしてみます。
$ curl https://s3-ap-northeast-1.amazonaws.com/vpc-s3-chiba/index.html <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>FB6D9B8F8372703B</RequestId><HostId>vqX15EDvKT+sjtK/1rCsg7PVzaqRt7ZYTFQfWXI9I2Ns4ksIqMp8tKAX0VSYICri+F0LuNoJ0yY=</HostId></Error>
アクセスできなくなったことを確認できました。
最後に
これで、Web用のEC2を管理せずに内部公開できるようになりました。EC2上にWebサーバを用意すると管理や運用が大変なので、これでいきたいと思います。