【アップデート】Cloud SQL for MySQLでブルートフォース攻撃の検知と保護機能がリリースされました
はじめに
こんにちは。
クラウド事業本部コンサルティング部の渡邉です。
2025年11月10日にCloud SQL for MySQLにて「ブルートフォース攻撃に対する防御機能(Brute-Force Protection)」がサポート(GA)されました。
本機能は、不正なログイン試行から自動的にデータベースインスタンスを保護し、セキュリティ脅威を検知・緩和する機能になります。
本記事では、この機能についての紹介と検証結果について記載します。
ブルートフォース攻撃とは
ブルートフォース攻撃(総当たり攻撃)は、パスワードやアクセス認証を破るために、可能な組み合わせを片っ端から試す攻撃手法です。データベースに対するブルートフォース攻撃は以下のようなリスクをもたらします。
- 不正アクセスによるデータ漏洩
- システムリソースの消費
- サービス停止のリスク
- セキュリティインシデント対応コストの増加
ブルートフォース攻撃に対する防御機能(Brute-Force Protection)の概要
Cloud SQLは、2つのレベルでブルートフォース攻撃からインスタンスを保護します。特にCloud SQLへデータベースフラグの設定など行う必要はなく、暗黙的に有効化になっているようです。
1. ブルートフォース検知(Brute-Force Access Detection)
対象エディション 全てのCloud SQLエディション(Enterprise、Enterprise Plus)
機能概要
- Cloud SQLが各インスタンスのログイン試行を継続的に監視
- 連続したログイン試行回数がCloud SQLの定義する閾値を超えた場合、警告メッセージを生成
- ログには攻撃元のIPアドレスとユーザー名が記録される
- 異常な接続パターンを自動検出
2. ブルートフォース防御(Brute-Force Access Protection)
対象エディション: Cloud SQL Enterprise Plus edition のみ
機能概要:
- ブルートフォース攻撃を検知すると、自動的にログイン試行を遅延させる
- リアルタイムでログインレスポンスに遅延を追加し、スロットリングを実施
- 攻撃の成功を遅延させ、攻撃者が攻撃を継続するコストを増大させる
- 正常なユーザーへの影響を最小限に抑えながら、攻撃を緩和
モニタリング・ログ
メトリクス
Cloud SQLは /database/network/connection_attempt_count メトリクスを使用して接続イベントを追跡します。
このメトリクスには以下のフィールドが含まれます
- login_status: 接続が成功したログインに至ったかどうか
- anomaly_detected: 接続がログイン試行の閾値を超えたブルートフォース攻撃であるかどうか
- anomalous_connection_throttled: ブルートフォース攻撃の接続がスロットリングされたかどうか
ログイベント
異常が検出されると、Cloud SQLは以下をCloud Loggingへ記録します
- 疑わしいIPアドレスからの失敗した試行
- 繰り返し失敗した後の成功したログイン
- リアルタイムで実行されたスロットリングアクション
Cloud Logging上に記録されるログイベントの種類としては、以下があります。
| イベント | 説明 |
|---|---|
| ブルートフォースアクセス試行の検出 | ユーザIPからのアカウントへのログインに失敗しました。この IP からのログイン試行が繰り返し失敗し、異常が検出されました。 |
| ブルートフォースアクセス攻撃を軽減するための自動スロットリング (Enterprise Plus エディションのみ) | ユーザIP からの アカウントへのログイン試行に失敗しました。この IP からのログイン試行が繰り返し失敗しており、異常が検出されました。Cloud SQL は、ブルートフォース攻撃の可能性を軽減するため、レスポンスを抑制しました。 |
| 繰り返しログインに失敗した後に初めてログインに成功したことを検出 | 異常が検出されました。ログイン試行が何度も失敗した後、ユーザIPからアカウントへのログインに成功しました。このアクティビティが予期せぬものである場合は、ユーザーパスワードの変更をお勧めします。 |
| ログイン失敗が繰り返された後の最初のログイン成功を自動的に制限する(Enterprise Plus エディションのみ) | 異常が検出されました。ログイン試行が何度も失敗した後、 ユーザIPからアカウントへのログインに成功しました。Cloud SQL は、ブルートフォース攻撃の可能性を軽減するため、レスポンスを制限しました。このアクティビティが予期しないものである場合は、ユーザーのパスワードを変更してください。 |
Cloud Loggingで "An anomaly was found" を検索することで、ブルートフォース攻撃のインシデントを特定できます。
前提条件と要件
本機能は、サポートしているMySQLのバージョンとエディションによってそれぞれ要件が存在します。
最小バージョン要件
- MySQL バージョン: 5.7 以降
- メンテナンスバージョン: MYSQL_$version.R20250531.01_23 以降
エディション要件
| 機能 | Enterprise | Enterprise Plus |
|---|---|---|
| ブルートフォース検知 | サポートしている | サポートしている |
| ブルートフォース防御 | サポートしていない | サポートしている |
やってみた
前提条件
- Cloud SQL for MySQL インスタンス(メンテナンスバージョンが要件を満たしていること)が作成済み
- MySQLのバージョンは8.4、エディションはEnterprise Plusで構築
- 検証のため、Cloud SQLはPublic IPの付与を行っている
- Cloud SQLへのアクセスはCloud Shellから実施 (Cloud SQLの承認済みネットワークでCloud Shellの外部IPを許可)
- 適切なIAM権限(Cloud SQL管理者またはCloud SQL編集者)を持っている
ステップ1: インスタンスの確認
現在のCloud SQL インスタンスのバージョンとエディションを確認します。
gcloud sql instances describe INSTANCE_NAME \
--format="value(databaseVersion,settings.edition,settings.maintenanceVersion)"
MYSQL_8_4 ENTERPRISE_PLUS
ステップ2: ブルートフォース攻撃のシミュレーション
意図的な失敗したログイン試行
以下のBashスクリプトで50回のログイン失敗を試行します。
#!/bin/bash
INSTANCE_IP="YOUR_INSTANCE_IP"
USERNAME="root"
WRONG_PASSWORD="wrong_password"
CORRECT_PASSWORD="correct_password"
# 複数回のログイン失敗を試行
for i in {1..50}; do
echo "Attempt $i"
time mysql -h $INSTANCE_IP -u $USERNAME -p$WRONG_PASSWORD -e "SELECT 1;" 2>&1 | grep -i "Access denied"
sleep 1
done
# 正しいパスワードでのログイン試行
echo "Attempting with correct password"
time mysql -h $INSTANCE_IP -u $USERNAME -p$CORRECT_PASSWORD -e "SELECT 1;"
実行結果はかなり長くなってしまうので、こちらに記載しておきます。
21回目のログイン失敗からブルートフォース攻撃を検知する閾値を超えたようで、ログイン試行のレスポンススピードが遅くなっていることがわかります。
実行結果
$ chmod +x test_connection.sh
$ ./test_connection.sh
Attempt 1
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.253s
user 0m0.046s
sys 0m0.009s
Attempt 2
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.276s
user 0m0.048s
sys 0m0.009s
Attempt 3
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.268s
user 0m0.047s
sys 0m0.011s
Attempt 4
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.268s
user 0m0.048s
sys 0m0.009s
Attempt 5
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.262s
user 0m0.046s
sys 0m0.010s
Attempt 6
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.271s
user 0m0.047s
sys 0m0.012s
Attempt 7
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.259s
user 0m0.047s
sys 0m0.009s
Attempt 8
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.283s
user 0m0.049s
sys 0m0.007s
Attempt 9
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.268s
user 0m0.048s
sys 0m0.008s
Attempt 10
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.274s
user 0m0.049s
sys 0m0.006s
Attempt 11
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.274s
user 0m0.047s
sys 0m0.008s
Attempt 12
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.259s
user 0m0.046s
sys 0m0.009s
Attempt 13
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.255s
user 0m0.045s
sys 0m0.010s
Attempt 14
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.271s
user 0m0.044s
sys 0m0.012s
Attempt 15
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.286s
user 0m0.046s
sys 0m0.012s
Attempt 16
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.274s
user 0m0.048s
sys 0m0.012s
Attempt 17
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.267s
user 0m0.049s
sys 0m0.007s
Attempt 18
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.258s
user 0m0.045s
sys 0m0.011s
Attempt 19
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.267s
user 0m0.046s
sys 0m0.009s
Attempt 20
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m0.270s
user 0m0.046s
sys 0m0.009s
Attempt 21
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m10.691s
user 0m0.048s
sys 0m0.010s
Attempt 22
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m2.545s
user 0m0.050s
sys 0m0.007s
Attempt 23
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m9.781s
user 0m0.048s
sys 0m0.008s
Attempt 24
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m11.640s
user 0m0.043s
sys 0m0.012s
Attempt 25
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m1.929s
user 0m0.045s
sys 0m0.013s
Attempt 26
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m3.175s
user 0m0.047s
sys 0m0.011s
Attempt 27
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m14.430s
user 0m0.048s
sys 0m0.008s
Attempt 28
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m6.430s
user 0m0.051s
sys 0m0.005s
Attempt 29
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m13.049s
user 0m0.048s
sys 0m0.008s
Attempt 30
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m3.450s
user 0m0.047s
sys 0m0.007s
Attempt 31
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m6.745s
user 0m0.048s
sys 0m0.009s
Attempt 32
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m5.556s
user 0m0.044s
sys 0m0.012s
Attempt 33
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m18.301s
user 0m0.047s
sys 0m0.010s
Attempt 34
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m7.386s
user 0m0.047s
sys 0m0.010s
Attempt 35
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m7.936s
user 0m0.042s
sys 0m0.014s
Attempt 36
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m5.880s
user 0m0.050s
sys 0m0.008s
Attempt 37
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m4.044s
user 0m0.047s
sys 0m0.009s
Attempt 38
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m12.882s
user 0m0.051s
sys 0m0.005s
Attempt 39
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m17.079s
user 0m0.047s
sys 0m0.010s
Attempt 40
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m14.890s
user 0m0.057s
sys 0m0.007s
Attempt 41
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m2.452s
user 0m0.046s
sys 0m0.010s
Attempt 42
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m17.935s
user 0m0.047s
sys 0m0.009s
Attempt 43
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m13.291s
user 0m0.048s
sys 0m0.009s
Attempt 44
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m11.774s
user 0m0.050s
sys 0m0.010s
Attempt 45
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m2.908s
user 0m0.047s
sys 0m0.012s
Attempt 46
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m15.401s
user 0m0.046s
sys 0m0.011s
Attempt 47
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m13.938s
user 0m0.045s
sys 0m0.012s
Attempt 48
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m19.632s
user 0m0.047s
sys 0m0.010s
Attempt 49
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m8.352s
user 0m0.049s
sys 0m0.010s
Attempt 50
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m16.708s
user 0m0.050s
sys 0m0.010s
Attempting with correct password
mysql: [Warning] Using a password on the command line interface can be insecure.
+---+
| 1 |
+---+
| 1 |
+---+
real 0m16.799s
user 0m0.049s
sys 0m0.006s
ステップ3: ブルートフォースアクセス攻撃を軽減するための自動スロットリングの確認
Cloud Loggingでブルートフォースアクセス攻撃を軽減するための自動スロットリングを確認します。
Cloud Loggingのログエクスプローラーに以下のクエリを入力し、実行します。
resource.type="cloudsql_database"
textPayload =~ "An anomaly was found"
すると、以下のログが出力されており、送信元のIPアドレスからのアクセス応答を制限していると記載がありました。
2025-11-12T01:31:45.927862Z 572 [Warning] [MY-000000] [Server] Plugin dbsecurity reported: 'Failed login attempt into the account root from IP xxx.xxx.xxx.xxx. An anomaly was found, repeated failed login attempts from this IP. Cloud SQL throttled the response to mitigate a potential brute force attack. It's recommended to remove this IP from authorized networks if this activity is unexpected.
ちょうどこのログが出たときに、検証結果のログイン失敗時の応答時間も長くなっていることも確認できています。
Attempt 21
ERROR 1045 (28000): Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES)
real 0m10.691s
user 0m0.048s
sys 0m0.010s
ステップ4: ログイン成功時のスロットリングの確認
ログイン失敗が繰り返された後の最初のログイン成功を自動的に制限する(スロットリング)ことができます。
攻撃検知後の初めての成功ログイン試行で、通常よりも遅延が発生する(16s)ことが確認できました。
Attempting with correct password
mysql: [Warning] Using a password on the command line interface can be insecure.
+---+
| 1 |
+---+
| 1 |
+---+
real 0m16.799s
user 0m0.049s
sys 0m0.006s
ブルートフォース攻撃が検知された場合の対応
もしブルートフォース攻撃が検知されてしまった場合は、以下の対応を推奨します。
即座の対応
承認済みネットワークを利用している場合は、Cloud Loggingから不正なログイン試行をしているリクエスト元IPアドレスを特定し、承認済みネットワークからIPアドレスを削除します。
# 疑わしいIPアドレスの特定
gcloud logging read \
"resource.type=cloudsql_database AND
textPayload=~\"An anomaly was found\"" \
--limit 10 \
--format="value(textPayload)"
# 承認済みネットワークからIPアドレスを削除
gcloud sql instances patch INSTANCE_NAME \
--authorized-networks=TRUSTED_IP_RANGE
パスワードの変更
もし成功したログインが検知されてしまった場合は、直ちに該当ユーザのパスワードを変更します。
セキュリティ強化策
以下のような、より安全なCloud SQLの接続方法への移行を検討します。
- Cloud SQL Auth Proxy: IAM認証を使用した安全な接続
- Cloud SQL Language Connectors: アプリケーション統合用のセキュアなコネクタ
- Private IP: パブリックIPを無効化し、VPC内からのみアクセス可能にする
事前対策
ログベースのアラート設定
事前対策として、Cloud Loggingのログベースのアラートポリシーを使用することで、ブルートフォース攻撃を検知した際にアラートを受け取ることができます。
アラートを受け取ることで、早急なアクションにつなげることができるため設定することをお勧めします。
ログイン試行に成功したブルートフォース攻撃は以下のクエリで検出することが可能です。
resource.type="cloudsql_database"
textPayload =~ "An anomaly was found, successful login into the account"
最後に
今回は、2025年11月10日にサポート(GA)されたCloud SQL for MySQLのブルートフォース攻撃に対する防御機能(Brute-Force Protection)についての紹介と検証をしてみました。
この機能により、データベースのセキュリティが向上し、セキュリティインシデントのリスクを低減できると思います。
Cloud SQLのパブリックIPを無効化し、プライベートIPを利用したVPC経由でのアクセスにするだけでもセキュリティリスクはかなり減ると思います。
Cloud SQL Auth ProxyやIAM認証などのセキュアなアクセス方法の利用を検討できるように、セキュアな設計を心がけましょう。
この記事が誰かの助けになれば幸いです。
以上、クラウド事業本部コンサルティング部の渡邉でした!






