こちらは バイセルテクノロジーズ Advent Calendar 2021 の 22日目の記事です。
前日の記事は飯島さんの「SentryでGoのcustom errorをstack trace付きで表示する」でした。
こんにちは。開発 2 部の今井です。 バイセルでは主にサーバサイドの開発に携わっています。
本記事では、現在進めている新規プロジェクトのインフラを構築するうえで検討する機会がありました「GCP でセキュアなサービスを構築するうえで考えたこと」についてご紹介します。
アーキテクチャの全体像
私が所属しているプロジェクトでは GCP を利用しており、簡単な全体像は以下のようになっています。
フロントエンド
フロントエンドではTypeScript
のビルトインサポート等ほぼゼロコンフィグでの開発が可能となるNext.js
を採用し、CSR で配信しています。
またホスティング先にはCloud Storage
を採用しています。バックエンド
バックエンドでは PostgreSQL サーバより GraphQL API を自動生成する Hasura GraphQL Engine(以降、Hasura
) を採用しています。また独立した GraphQL サーバとして gqlgen を採用し、Remote Schema としてHasura
に統合しています。
またデプロイ先にはともにフルマネージド版のCloud Run
を採用しています。
※ なお以降で「Cloud Run
」と記載あるものはフルマネージド版を指します。
本記事で紹介すること
GCP でセキュアなサービスを構築するうえで検討できる箇所は多くあると思いますが、今回は以下の2つについて書いていきます。
Cloud Storage
のアクセス制限についてCloud Load Balancer
を利用したアクセス制限について
Cloud Storage
のアクセス制限について
前述したように本プロジェクトではフロントエンドのホスティング先として Cloud Storage
を採用しています。
続いてバケットへのアクセス制限をかける必要があるため調査したところ、Cloud Storage
には AWS の S3 のようにバケット単位での IP 制限ができないことがわかりました。
そこで以下のような点を検討し、どのようにしてバケットのセキュリティを担保するかを考えました。
- 案1
Access Context Manager
とVPC Service Controls
を組み合わせてプロジェクト全体に IP 制限をかける。 - 案2
Cloud Storage
ではなく、Cloud Run
を利用する。- Next.js を SSR で配信するようにし、
Cloud Load Balancer
と組み合わせることでIAP
を実現することが可能。しかし SSR で配信することは要件に沿わず、CSR と比較しデプロイ時にも考慮する点が増えてしまう。 - かつ他のバケットのアクセス制限については解決できていない。
- Next.js を SSR で配信するようにし、
- 案3 公開範囲を制限したいコンテンツを置くバケットには、AWS の S3 を採用する。
- クラウドサービスをまたぐことになり、管理が煩雑になる可能性がある。そのためこの方法は可能な限り避けるべきと判断。
最終的には 案1の Access Context Manager
と VPC Service Controls
を組み合わせてプロジェクト全体に IP 制限をかける方法を採用しました。
Access Context Manager
を活用することで IP アドレスやサービスアカウント等のアクセスレベルを定義し、VPC Service Controls
を併用することプロジェクト全体に対して通信を制御することができます。
注意点
VPC Service Controls
を利用したアクセス制限には以下のような注意点があります。
- バケット個別での制御ではなく、あくまでプロジェクト全体に適用されること。
- API の制限となる為、Web ブラウザ上の表示も不可能となること。
Terraform
利用している際にtfstate
の管理場所として採用している場合やCI/CD
を実行するうえでは、必要なサービスアカウントをAccess Context Manager
で許可する必要があること。こちらを適用していない場合、権限不足でアクセスが拒否される。
Cloud Load Balancer
を利用したアクセス制限について
前述したように私が所属しているプロジェクトでは、バックエンドに Hasura
を採用しています。
Hasura
を利用したプロダクトではデプロイ先として Hasura Cloud が採用されるケースが多いようですが、Hasura Cloud
は IP 制限に対応していないことがわかりました。
そのため Hasura Cloud
の前段に Cloud Load Balancer
を配置すれば Cloud Load Balancer
へのアクセスに限り制限可能ですが、直接 Hasura Cloud
にアクセスされる場合は制限ができません。
そのため Hasura
のデプロイ先として Cloud Run
を採用し、以下のような設定を適用することでアクセス制限を実現しました。
前述した
Cloud Run
(Hasura) を Serverless Network Endpoint Group として管理し、Cloud Load Balancer
を前段に配置し、Cloud Armor
を併用することで IP 制限をかける。
Cloud Run
(Hasura)は、Ingress オプションでアクセスを「内部とCloud Load Balancer
」に絞る。
Cloud Run
(Remote Schema) は Ingress オプションでアクセスを「内部のみ」に絞り、トラフィックを VPC コネクタ経由でルーティングする。(Serverless VPC Access)
まとめ
GCP を利用してセキュアなサービスを構築するうえで検討できる点は数多くありますが、今回は Cloud Storage
のアクセス制限と
Cloud Load Balancer
を利用したアクセス制限をご紹介しました。
セキュアなサービスを構築するうえでまだまだ検討できる箇所は多くあるので、共有できることがありましたら再度ブログを書きたいと思います。
最後に
バイセルではエンジニアを募集しています。ご興味のある方はぜひご連絡ください。
明日のバイセルテクノロジーズ Advent Calendar 2021は、杉田さんによる「過去一やらかしにやらかしを重ねた話を供養する」です。