GCPのCloud SQLでネットワークタグを用いた接続制限を行う方法
概要
意外と言及している記事が見当たらない、GCEのVMインスタンスからCloud SQLインスタンスに対してネットワークタグを使った接続制限を行う方法を記載する。
方法としてはプライベートサービス接続を作成し、VMとCloud SQLをプライベートIPで接続可能とした上で、VMからの送信トラフィックをデフォルト拒否、接続させたいVMのネットワークタグだけ送信トラフィックを許可する形。
はじめに~Cloud SQLの接続方法について~
まず始めにGCPのCloud SQLインスタンスに対してVMインスタンスから接続許可する方法としては主に以下の2つがある。
①承認済みネットワークで接続
いわゆるIP許可。Cloud SQLインスタンスの接続画面から承認済みネットワークとしてVMの外部IPを許可設定する形。
Cloud SQLのコンソール上では接続方法として真っ先にこの方法が案内される。
しかしこの方法には以下のような問題点がある
ちょっとした開発や小さいアプリケーションなら問題ないが、少し規模が大きくなるとこれは現実的ではない。
②Cloud SQL Proxyを使う方法
もう一つの方法としてCloud SQL Proxyを利用する方法がある。
認証用のCloud SQLの権限を持ったサービスアカウントを作成、jsonファイルをVMに配備、cloud_sql_proxyをVMでDLして実行する。
参照:https://cloud.google.com/sql/docs/mysql/connect-admin-proxy?hl=ja
この場合、①で上げられた問題点は解消され、VMインスタンス起動時にこのツールを起動する様に構築すれば良い。
しかしこの方法にも以下のような問題点がある
- 接続IPがローカルIP(127.0.0.1)になる為、プログラム側では「どこにつないでいるか」がプログラム側の設定ファイルから確認しづらくなる。
- 複数のCloud SQLインスタンスと接続しようとすると、インスタンス毎にポートを分ける必要がある
- ツール起動が手間
- ツール起動時の引数をミスる可能性もある。
一応接続用のライブラリも存在するが、javaとGoだけしか無いようで、phpやその他の言語では使えない状態になっている。
ネットワークタグを使って制御したい
以上を解決する為には、VMインスタンスの接続制限のようにネットワークタグを使えると非常に便利。
ネットワークタグを元にしたファイアウォールを利用する事で、Cloud SQLインスタンスに対して接続できる/できないVMインスタンスを制御出来れば、以下のような事が実現できる。
- オートスケールでVMが建てられてもファイアウォールによってCloud SQLインスタンスに自動で接続可能になる
- Cloud SQLインスタンスが増えた際もファイアウォールの追加/編集で管理できる
- プログラム側もCloud SQLインスタンスのIPを設定ファイルから確認できる上、ポートも同じモノが利用できる
- ツール起動が要らない
これを実現する方法について備忘録も兼ねて記載する。
①プライベートサービス接続の作成
まずはCloud SQLインスタンスにプライベートIPで接続できるようにする為、VPCネットワーク側にプライベートサービス接続を作成する。
Cloud SQLインスタンスと接続したVPCネットワークの詳細画面を開き、「プライベートサービス接続」タブを押下する。
①-1.IP範囲の割当
タブのIP範囲の割当を押下し、
名前を任意に入力し、Cloud SQLインスタンスに付与されるプライベートIPの範囲を指定する。
既存のサブネットと範囲を被らせない様にする必要もあるので、本番運用する際は、設定値に注意する必要はあるが、ここでは「自動」で設定し、サイズは16を指定した。
参考:https://cloud.google.com/vpc/docs/configure-private-services-access?hl=ja
①-2.プライベートサービス接続の作成
「サービスへのプライベート接続」タブを押下し、接続の作成を押下
接続サービスプロデューサーは「Google Cloud Platform」、割当を上で作ったIP範囲に設定、接続を押下
以上でプライベートサービス接続が作成できる。
②Cloud SQLインスタンスにプライベートIPを追加
Cloud SQLインスタンスの構築/編集(編集の際は接続メニュー)にてプライベートIPのチェックを入れる。
VPCネットワークの選択が出るので、プライベートサービス接続を作成したVPCを選択。正常であれば以下のような表示になる。
③ファイアウォールの設定
②ままではVPCネットワーク内の全てのVMインスタンスからCloud SQLインスタンスにデフォルトで疎通可能となってしまう。
※以下のように任意のVMから疎通できる。(IPを隠す意味は無い気がするが念の為)
その為、ファイアウォールを設定しVMインスタンスとCloud SQLインスタンスへの接続を制御する。
③-1.デフォルト拒否
まずはデフォルトとして、全てのVMインスタンスからCloud SQLインスタンスへの接続をNGとするファイアウォールを設定する。
この時Cloud SQLインスタンスの上り(受信)トラフィックを制御する訳ではなく、VMインスタンスからの下り(送信)トラフィックを制御する。
名前 | ネットワーク | 優先度 | トラフィックの方向 | 一致した時のアクション | ターゲット | ソースフィルタ | IP範囲 | プロトコルとポート |
deny-vm-to-mysql ※適当 |
test-cloudsql-vpc ※VMがあるVPC |
2000 ※後で設定する許可より優先度を下げる |
下り(送信) ※GCPは上り/下りが一般の認識と逆 |
拒否 | ネットワーク上の全てのインスタンス | IP範囲 | [プライベートサービス接続の割当IP範囲] | 3306 |
③-2.対象のネットワークタグのみ接続許可
次にCloud SQLインスタンスと接続したいVMに付けるネットワークタグからはCloud SQLインスタンスへ接続できるようファイアウォールを設定する。
こちらもVMインスタンスからの下り(送信)トラフィックを制御する形。
名前 | ネットワーク | 優先度 | トラフィックの方向 | 一致した時のアクション | ターゲット | ターゲットタグ | ソースフィルタ | IP範囲 | プロトコルとポート |
allow-mysqlclient-vm-to-mysql ※適当 |
test-cloudsql-vpc ※VMがあるVPC |
1000 | 下り(送信) | 許可 | 指定されたターゲットタグ | mysql-client-vm | IP範囲 | [プライベートサービス接続の割当IP範囲] ※ここはIPを直指定でも良いと思う。全てが全て接続できて良いわけではないと思うので |
3306 |
まとめ
以上の方法を行えば、VMインスタンスとCloud SQLインスタンスをネットワークタグを用いて接続制御が出来る。
公式ドキュメント(https://cloud.google.com/sql/docs/mysql/connect-compute-engine?hl=ja)にも書いてないの、ホント不親切というか……
以上。
久々にエンジニアっぽい記事書いた。