この記事は JSL (日本システム技研) Advent Calendar 2018 - Qiita の7日目の記事です。
以下の要件がありました。
順を追って設定していきます。3番目の要件は1番めと2番目が実現できればおのずと実現できそうです。
APIへのアクセス制限
AWSのセキュリティグループで80と443ポートについて制限
ImageField+Django storage + S3 backendの基本的な使い方については割愛します。
APIと画像のドメインを同じにする
settigns.pyにAWS_S3_CUSTOM_DOMAIN = 'www.example.com'
を追記します。
この設定についてはdjango storageのS3 backend Amazon S3 — django-storages 1.7.1 documentation に記載されています。CloudFrontの項にあるのですが、CloudFrontを使うかどうかは特に関係ないようです。単にImageFieldのホスト名がここで設定した値になります。http://
や https://
は書きません。既定でhttps://
が付加されます。検証環境など http://
で使いたい場合は AWS_S3_SECURE_URLS = False
をsettings.pyで設定します。
画像のURLへのアクセスをS3に向ける
nginx.confを設定します。
location ~ ^/images/ { proxy_buffering off; resolver 8.8.8.8; proxy_pass http://my-bucket-name.s3-website-ap-northeast-1.amazonaws.com; }
参考: Nginx のDNS 名前解決とS3 やELB へのリバースプロキシ :: by and for engineers
S3をEC2からのアクセスのみに制限する
VPCエンドポイントなるものを設定します。
参考:nginxとS3を使って静的コンテンツを利用者を限定した形で利用できるようにする | DevelopersIO
上記の記事ではバケットポリシーに aws:sourceVpc
でVPCのIDを指定していますが、VPCエンドポイントを作って aws:sourceVpce
でVPCエンドポイントIDを指定しないとうまくいきませんでした。
画像のURLをAPIと同様にアクセス制限する
以上の設定をしていると、画像のURLをアクセス制限できます。