はじめに
Cloudflare で gRPC を通すテスト、第2回です。
- プロキシ + Full TLS 化
- ファイアウォール <<====
- レートリミット
- ロードバランシング
ファイアウォール
ファイアウォールを併用し、条件に応じた gRPC リクエストだけ、オリジンに届けようと思います。
gRPC サービスに対するアクセス(質と量
)を具体的に把握し、サービスの安定稼働
と健全なセキュリティライフサイクルの継続
に役立てることを目指します。
もちろん、簡単
に。
守るべきものを知る、セキュリティイベント (Security events) としてリクエストを可視化
HTTP ログが全リクエストを対象にするのと違い、セキュリティのイベントは設定したルールにマッチしないと可視化されません。
HTTP ログにもログ対象をフィルタするオプションは出てます。(執筆時点 Beta)
まずは、gRPC サーバ宛のすべての HTTP リクエストをセキュリティのイベントにするため Firewall rules でルールを作成します。(全部許可)
今回利用するツールは host ヘッダにポートを入れてきます。ルール作成で Hostname
フィールドの equals マッチさせる場合、:443 は除いてホスト名だけ定義します。 (Analytics 系のフィルタで Host
の equals マッチする場合は host ヘッダ通り :443 を入れます)
セキュリティイベント を開くと、ファイアウォールで処理をされた gRPC サーバ宛リクエストの概況が見えてきます。
簡単です。
ここから、いろいろな視点でリクエストの質と量
を把握していきます。
悪質なものや想定外のものが把握されたら、ブロックし、サービスを健全に保ちたいところです。
デフォルトではファイアウォールのアクション
をキーにした分析表示となります。(グラフの線が1本だけなので、発生したアクションは1つだけで、それは許可、ということがわかります。)
同じデータを視点を変えて見てみます。国
をクリックします。
リクエストの送信元を国別で表示することができました。
縦軸のイベント数がアクション別に比べ3分の1に減っているのがわかります。
同じデータを違う視点から簡単に分析
できるのが、状況把握のスピードアップ
に効きますね。
とくに、攻撃の徴候があったり、トラブルシュートの際は、こういう簡便さが重要だと思います。
スクロールダウンすると、グラフの元データ(統計とソースログの抜粋)が表示されています。
閲覧している各項目は、ファイアウォールルール作成のフィールド、値としてそのまま反映できます。Read した要素で設定に Write できる、直感的でわかりやすいです。
gRPC のリクエストに接続条件を設定する
Australia からの通信は想定外なので、拒否したい
と仮定して、ファイアウォールの設定を変更します。
gRPC ホストに対して Australia のみ Block するルールを定義していきます。
-
ルール作成の画面に飛びますが、指定したフィルタで
ルールの雛形が自動作成
されています。ルール名(必須)を追加し、アクションが Block であることを確認のうえ、保存します (下書き
またはデプロイ
)。
-
作成された Block のルールを Allow の上に移動します。
ルールは上から順に評価されます。
ファイアウォールルールを作成
から飛ぶとある程度自動作成してくれますが、直接のほうがやりやすい場合もありますので、場合に応じて使い分けます。
たとえば、セキュリティイベント側の表示フィルタ条件では :443
付きで指定しており、自動作成されたルールにもそのまま入力されていました。ただ、ファイアウォールルール設定のホスト名
で equals マッチさせるには :443
を削る必要がありました。
ファイアウォールの効果
デプロイ保存したので、動作に即反映されました。
gRPC クライアントの表示は Australia では下記のようになりました。
403 Forbidden
と ファイアウォールで Block されていることがわかります。
2023/01/31 10:30:29 Greeting: Hello australia
2023/01/31 10:30:32 Greeting: Hello australia
2023/01/31 10:30:35 Greeting: Hello australia
2023/01/31 10:30:38 Greeting: Hello australia
2023/01/31 10:30:41 could not greet: rpc error: code = PermissionDenied desc = unexpected HTTP status code received from server: 403 (Forbidden); transport: received unexpected content-type "text/plain; charset=UTF-8"
exit status 1
2023/01/31 10:30:44 could not greet: rpc error: code = PermissionDenied desc = unexpected HTTP status code received from server: 403 (Forbidden); transport: received unexpected content-type "text/plain; charset=UTF-8"
exit status 1
一方 gRPC サーバでは Austraria からのメッセージが消えました。
2023/01/31 10:30:34 Received: brazil
2023/01/31 10:30:35 Received: australia
2023/01/31 10:30:35 Received: japan
2023/01/31 10:30:37 Received: brazil
2023/01/31 10:30:38 Received: australia
2023/01/31 10:30:38 Received: japan
2023/01/31 10:30:40 Received: brazil
2023/01/31 10:30:41 Received: japan
2023/01/31 10:30:43 Received: brazil
2023/01/31 10:30:43 Received: japan
2023/01/31 10:30:46 Received: brazil
2023/01/31 10:30:46 Received: japan
有効化からグローバルのエッジでの動作反映までは数秒
という点も魅力です。速さのチカラですね。
オブザバビリティ
Security events
イベントのグラフを見てみます。
アクション視点でみると、 Block が増えています。
Block でフィルタを掛け、ドリルダウンします。
ドリルダウンしたものを国でみると、Australia がソースであることがわかります。
結果の把握も簡単にできました。
見ながらる、やりながら見る、動作テストにも最適です。
セキュリティイベントはサンプリングデータを元にすることがあり、必ずしも生のイベント数を反映はしませんので、ご注意ください。
ログ
イベントのログはすでに解説しましたが、HTTP ログの方も確認してみます。前回同様 Instant Logs でサクッと行きます。
ClientCountry au
(Australia) という情報の他にも、リクエストの詳細が記載されています。
まとめ
以上、 gRPC にファイアウォールを適用し、不要なトラフィックを除く目的を達成、また、そのトラフィックの詳細情報を確認することもできました。
サービスに対する外部からのアクセス(質と量)を具体的に把握し、サービスの安定稼働と健全なセキュリティライフサイクルの継続に役立てることができます。
第3回はレートリミットでオリジンへのリクエスト流入をコントロールしたいと思います。