
Google Cloud環境のWebアプリに、WAFを導入する方法とは?
はじめに

Google Cloud Platform環境でWebアプリケーションを開発・運用している皆様の中には、アプリケーションやWebサイトのセキュリティ対策をどのように取り組んでいけばよいかお悩みの方も多くいらっしゃるのではないのでしょうか。
そこで今回は、Google Cloud PlatformのGoogle Cloud Armor (以下、Cloud Armor)のご紹介と、Cloud Armorを導入する2つのメリットを解説します!
記事前半ではCloud Armorの概要を、後半ではCloud Armorの設定方法と攻撃の検知例をお伝えしますので、ぜひご覧ください。
Webサイトとアプリを保護!Google Cloud Armorとは

Google Cloud Armorは、GCPが提供する分散型のWebアプリケーションおよびAPIセキュリティサービスです。主にDDoS攻撃や悪意のあるトラフィックから、システムを保護するために利用されます。
Cloud ArmorはGoogleのグローバルインフラストラクチャを活用し、大規模な攻撃にも耐えうる堅牢な防御を提供できるのが特徴です。ルールベースのポリシーを定義して、アクセス制御やトラフィックの許可・拒否を柔軟に設定できる柔軟性を備えています。
Googleのサービスと統合されており、GKE(Google Kubernetes Engine)やCloud Load Balancingなどと組み合わせることで、包括的なセキュリティ対策を実現できるサービスです。
主な機能として以下のものが挙げられます。
・機械学習を使用したDDoS対策
・IP制限(ブラックリスト、ホワイトリスト)
・事前構成されているWAFルール
参考サイト
・ Google Cloud Armor の概要
Cloud Armorを導入する2つのメリット

Cloud Armorを導入することで得られるメリットは多岐にわたりますが、今回ピックアップするのは以下の2点です。
導入が簡単
Google Cloud Armorは、簡単かつ迅速に導入できる点が大きな魅力です。GCP上で運用されるアプリケーションに対して、数ステップの設定でセキュリティポリシーを適用できます。
事前に定義されたルールセットやテンプレートを活用すれば、セキュリティの専門知識がなくても適切な保護を実現可能です。またCloud Load Balancingと統合されているため、負荷分散と同時にセキュリティ対策を一元的に管理でき、運用効率も向上します。
Google Cloudの組織単位でセキュリティ管理が可能
Google Cloud Armorでは、GCPの組織単位を活用して、全社的なセキュリティポリシーを一元管理できます。これにより、個別のプロジェクトやアプリケーションごとに異なる設定を行う必要がなく、セキュリティ運用を効率化可能です。
さらに、ポリシーの変更はすべての対象リソースに即時反映されます。セキュリティルールは組織のニーズに応じて細かくカスタマイズでき、特定のIPアドレス範囲や地域からのアクセスを制限することも簡単です。
WAFについて
WAF(Web Application Firewall)は、Webアプリケーションを脅威から守るためのセキュリティソリューションです。主にSQLインジェクションやクロスサイトスクリプティング(XSS)といった、Webアプリケーションの脆弱性を狙う攻撃を防ぎます。
通信データを監視し、不正なリクエストを検知・遮断することで、システムやデータの安全性を確保します。また、従来のネットワークファイアウォールとは異なり、アプリケーション層での防御を提供する点が特徴です。
WAF導入が必要な理由
Webアプリケーションは、一般的にクラウドやAPIを活用して動的に動作するため、複雑で攻撃の対象になりやすい問題を抱えています。
WAFは、こうした脅威からアプリケーションを保護し、ビジネスの継続性を確保する上で重要な手段です。特にDDoS攻撃やゼロデイ脆弱性への迅速な対応が求められる場合、WAFは不可欠の防御手段となります。規制の遵守や顧客データを保護する上でも、重要なセキュリティ基盤となります。
実際にCloud ArmorでWAFを導入してみる
では実際にCloud ArmorのWAF機能を利用し、攻撃からアプリケーションを保護する方法をご紹介します。
事前準備
先述したように、Cloud Armorの保護対象とするのはGoogle Cloud Platform環境でCloud Load Balancing経由で公開されているWebサイトとなります。そのため、検証用にWebアプリケーションとロードバランサを用意します。
Webアプリケーション
本検証では攻撃としてXSS (クロスサイトスクリプティング) とSQLインジェクションを例にするため、後述するサイトを参考に3つのページを用意します。環境は以下の通りです。
Google Cloudサービス | Google Computer Engine |
OS | CentOS Stream 8 |
Apache | 2.4.37 |
PHP | 7.2.24 |
MariaDB | 10.3.28 |
XSS検証用Webページ
入力された値をそのままページに表示します。そのため、悪質なサイトに誘導するようなスクリプトが入力される危険性があります。
# /var/www/html/xss.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS確認</title>
</head>
<body>
<form action="" method="get" accept-charset="utf-8">
<label class="label" for="name">入力値:</label>
<input type="text" size="70" name="xss_text" value="">
<p><input type="submit" value="送信"></p>
</form>
入力値はこちら: <?php echo $_GET['xss_text']; ?>
</body>
</html>
試しに以下のような入力をしてみましょう。

すると、表示された部分がリンクとなっており、クリックすると意図しないポップアップが表示されます。

上記では単純なポップアップ表示のみに止めましたが、実際にはアプリケーション側が意図しない、悪意ある別のサイトへのリンクが埋め込まれる可能性があり、脆弱性がある状態です。
SQLインジェクション検証用Webページ
データベースには以下のようなデータを用意します。
MariaDB [testdb]> select * from users;
+----+-----------------+
| id | name |
+----+-----------------+
| 1 | 田中太郎 |
| 2 | 山田花子 |
| 3 | 鈴木一郎 |
| 4 | 佐藤亜美 |
| 5 | 高橋浩史 |
| 6 | 山本真衣 |
| 7 | 吉田大輔 |
| 8 | 中村さくら |
+----+-----------------+
上記のデータベースから、ユーザIDを1つ指定して名前を取得するWebページを用意します。
データ入力ページ
# /var/www/html/sqli.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>インジェクションテスト</title>
<!-- jQueryの読み込み -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<!-- フォーム作成 -->
<form method="get" action="result.php">
<p><label>ID:<br>
<input type="text" maxlength="255" name="id">
</label></p>
<p><input type="submit" value="送信"></p>
</form>
</body>
</html>
結果出力ページ
実行するSQL文「$sql = ‘SELECT * FROM users WHERE id = ‘. $id. ‘;’;」は、入力された値とSQL文の一部をそのまま結合して作成しており、意図しないSQL文が実行される可能性が高いです。
# /var/www/html/result.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>インジェクションテスト結果確認</title>
</head>
<body>
<table border="1">
<tr>
<th>id</th><th>ユーザ名</th>
</tr>
<!-- DBに接続しデータ取得 -->
<?php
// リクエストした値を取得
$id = $_GET['id'];
// DB接続用データ
$host = 'localhost';
$dbname = 'testdb';
$dbuser = '〓任意のデータベースユーザ〓';
$dbpass = '〓dbuserのパスワード〓';
// データベース接続クラスPDOのインスタンス作成
try {
$dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);
// PDOExceptionクラスのインスタンス$eからエラーメッセージを取得
} catch (PDOException $e) {
var_dump($e->getMessage());
exit;
}
// SQL実行
$sql = 'SELECT * FROM users WHERE id = '. $id. ';';
$stmt = $dbh->prepare($sql);
$stmt->execute();
?>
<!-- 結果表示 -->
<?php while($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?>
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['name']; ?></td>
</tr>
<?php endwhile; ?>
</table>
</body>
想定する挙動は以下のような形です。

しかし、以下の値を入力してみると、

なんと本来1ユーザのみの情報が表示されるはずが、全てのユーザの情報が表示されています。
上記では全レコードが表示されるだけに止めましたが、実際にはレコードを全件削除するなどの操作も可能となっており、こちらも脆弱性がある状態です。
ロードバランサ
Cloud Load Balancingサービスから、バックエンドの構成を持つHTTP(S)負荷分散ロードバランサを用意します。


WAFポリシー設定
それではここから、Cloud ArmorにてWAFを設定していきます。サイドバーから「ネットワークセキュリティ」 >> 「Cloud Armor」を選択します。

新しいポリシーを作成します。

「ポリシーの設定」項目にて、任意のポリシー名を入力、ポリシータイプを「バックエンドセキュリティポリシー」、「デフォルトのルールアクションを「拒否」、拒否ステータスを403にしたら、「次のステップ」をクリックします。

「ルールの追加」項目にて、新しいルールを2つ追加します。
1つ目は、攻撃を拒否するルールです。詳細モードを選択し、「一致」の欄に以下のルール条件を設定、アクションを「拒否」とし、優先度を「1000」とします。
evaluatePreconfiguredExpr(‘xss-canary’) || evaluatePreconfiguredExpr(‘sqli-canary’)
ここで「一致」の欄に入力した条件は、XSSとSQLインジェクション のどちらかの攻撃が発生した場合、そのアクセスを403エラーで拒否するという内容となります。

2つ目は、正常なアクセスを許可するルールです。
ポリシーを作成すると、すべてのIPアドレスのアクセスを拒否するというデフォルトのルールが設定されています。そのため、このデフォルトルールを上書きする形でIPアドレスによるアクセス許可のルールを作成する必要があります。
基本モードを選択し、「一致」の欄に「*」を入力、アクションを「許可」とし、優先度を「1001」とします。ここでは優先度を「1001」としていますが、1つ目のルールの優先度の値とデフォルトルールの値の間、つまり今回でいえば1001~ 2,147,483,646 の間の値であれば、どの値でも問題ありません。

2つのルールを作成後、「ターゲットへのポリシーの適用」項目と「高度な設定 (Adaptive Protection)」項目はスキップし「ポリシーを作成」をクリックします。

次に作成したポリシーをロードバランサのバックエンドサービスに紐づけます。 サイドバーから「ネットワークサービス」 >> 「Cloud Load Balancing」を選択します。

「バックエンド」タブを選択し、事前に用意したロードバランサに紐づくバックエンドサービスを編集します。

編集画面内「Cloud Armor セキュリティポリシー」にて、作成したポリシーを選択し、「保存」をクリックします。

再度Cloud Armorの画面から対象ポリシーの詳細画面に遷移、「ターゲット」タブをクリックし、用意したロードバランサとバックエンドサービスにポリシーが適用されていることを確認します。

これで設定完了です!
攻撃からの保護検証、確認
それでは、WAF機能を設定した状態で、準備工程で入力した値を再度入力し攻撃がブロックされるか確認してみましょう。
1)XSS
設定どおり、403エラーが発生し、不正な操作が拒否されています。

またロードバランサのログからも、設定したポリシーでアクセスが拒否されていることが確認できます。

2)SQLインジェクション
こちらも同様に、403エラーが発生し、攻撃がブロックされていることが確認できます。

結果として、脆弱性を狙う攻撃からWebアプリケーションを保護するセキュリティ構成を実現することができました。
参考サイト
RHEL 8にApache、MySQL、MariaDB、およびPHPをインストールする方法
SQLインジェクションとその対策(PHP + PDO) – 実際に起こしてみる
HTTP Load Balancer with Cloud Armor
Cloud Console と gcloud ツールを使用してセキュリティ ポリシーを作成する
Google Cloud Armor WAF ルールのチューニング
まとめ

今回は、Cloud Armorを利用したGoogle Cloud Platform環境のWebアプリケーションに対するWAFの導入方法をご紹介しました。標準で用意されているルールを使用することで、脆弱性を狙う攻撃に対するセキュリティを簡単に実現することができました。
本記事では省略しましたが、Cloud Loggingサービスにて設定したポリシーで拒否したアクセスのログに対するアラートを設定することで、いつどんな攻撃を受けていたかなどの検知内容を自動的に認知することも可能です。
皆様もお使いのGoogle Cloud Platform環境にCloud Armorの導入を検討してみてはいかがでしょうか?