ちょっと話題の記事

[新サービス] VPC 向け AWS マネージドファイアウォールサービス「AWS Network Firewall」がリリースされました

さようならプロキシサーバ
2020.11.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

re:Invent が近づくにつれて続々とアップデートが続いていますね。(追いかけるのが大変です、、)

本日も新たなサービスとして 「AWS Network Firewall」 がリリースされました!

AWS Network Firewall とは

AWS Network Firewall は VPC 向けのステートフルなマネージドネットワークファイアウォールのサービスです。インターネットゲートウェイ、NAT ゲートウェイ、VPC、DirectConnect など VPC の境界でトラフィックをフィルタリングすることができます。

(似たようなサービス名で AWS Firewall Manager がありますが、あちらは AWS WAF をアカウントで管理するためのサービスです)

AWS Network Firewall のメリット

ステートフルで高度なフィルタリング

ステートフルなルールといえばセキュリティグループがありますが、セキュリティグループはホワイトリスト形式であるため「特定のターゲットをブロックしたい」といった利用はできません。一方、ネットワーク ACL はブラックリスト形式であるため「特定のターゲットをブロックする」といったことは出来ますがステートレスなルールであるためリクエストに対する戻りのルール設定も必要になりますので複雑になりがちです。

また、いずれの方法もドメインリストを指定することは出来ないため、特定のドメインに対してブロックを掛けたい(または、特定ドメインだけを許可したい)場合は EC2 でユーザーマネージドなプロキシサーバを準備する必要がありました。

AWS Network Firewall は IP アドレス、プロトコルなどの 5-tuple ルールに加え、ドメインリストやオープンソースの IPS 「Suricata」 互換のルールをサポートし、ステートフルなフィルタリングが可能になります。

可用性、スケーラビリティ

EC2 によるプロキシサーバの課題は可用性やスケーラビリティです。基本的に保護したいすべての通信が通過するわけですから障害や、トラフィック増加によるサチュレーションはシステムダウンへと繋がりますので非常に運用負担が大きい部分であったかと思います。

また、プロキシサーバ自身の OS、ミドルのメンテナンス、脆弱性対応などの運用コストも掛かってきます。

AWS Network Firewall は AWS マネージドサービスとして可用性、スケーラビリティを提供しており SLA は 99.99% となっています。ユーザーはルール設定やアラート管理など、本来の機能だけに集中することが出来ます。

仕組みの理解

Network Firewall は図のように VPC の境界にエンドポイントを配置し VPC ルートテーブルでトラフィックを Network Firewall エンドポイントに向けるだけで利用できます。

(引用元:Multi zone architecture with an internet gateway

より詳細な仕組みとデプロイパターンについては公式ブログがまとまっていますので、こちらを参照ください。

価格

リソースタイプ 価格
Network Firewall エンドポイント $ 0.395/h
Network Firewall トラフィック処理 $ 0.065/GB
NAT ゲートウェイ料金 起動料金、データ処理料金ともに Network Firewall が起動している間は無料

24時間x30日で換算すると月あたりのエンドポイント起動料金は $284.4 です。NAT ゲートウェイの料金は Network Firewall がプロビジョニングされている間は無料で利用できるようです。(詳細は公式の価格ページを参照ください)

「まぁ、そんなもんか…」と思いきや

You install the firewall endpoints on a per-Availability Zone basis in your VPC

(引用元:Firewall components in AWS Network Firewall

Network Firewall エンドポイントは AZ 単位で課金されます。やや構成が複雑にはなりますが AWS TransitGateway を利用し、Network Firewall は共通基盤環境として利用するほうがお財布にはやさしいかもしれませんね。

対応リージョン

執筆時点でサポートされているリージョンは以下の 3 リージョンのみ。
東京リージョンではまだ利用できません。

  • バージニア北部
  • オレゴン
  • アイルランド

注意点

  • (大事なことなので念押し) Network Firewall エンドポイント は AZ 単位で課金されます
  • ファイアウォールサブネットは Network Firewall 専用に予約します
    • ファイアウォールサブネットへのトラフィックをフィルタリングできないため
  • 以下の構成は AWS Network Firewall でサポートされません
    • VPC ピアリング
    • 単一 VPC 内で、NAT ゲートウェイと保護サブネットの間に Network Firewall を配置すること
      • 必ず以下のように、Netowork Firewall と保護サブネットの間に NAT ゲートウェイを配置する必要があります

(引用元:Architecture with an internet gateway and a NAT gateway

ネットワークトラフィックのログ

Network Firewall ではフローログとアラートログが記録できます。

  • フローログ: 標準のネットワークトラフィックフローlog
  • アラートログ: アラートアクションを持つステートフルルールに一致したトラフィックを報告

ログは以下の宛先に配信できます。

  • S3
  • CloudWatch Logs
  • Kinesis Data Firehose

やってみる

まだ東京リージョンでは利用できませんので、今回はバージニア北部で検証しました。

ネットワークファイアウォールの作成

ネットワークファイアウォールは VPC 管理コンソールから作成します。(Firewallでサービス名を検索して表示されるのは AWS Firewall Manager ですのでお間違えないように。紛らわしいですね)

[AWS ネットワークファイアウォール] - [ファイアウォール] を開き、ファイアウォールを作成 をクリックします。

ネットワークファイアウォールを構成するコンポーネントは以下の 3 つです。

任意のファイアウォール名を入力、ファイアウォールを作成する VPC およびファイアウォールサブネットを選択します。ファイアウォールサブネットはその他の AWS リソースが属さない専用サブネットを選択します。(ファイアウォールサブネットのトラフィックはフィルタリングされないため)

ファイアウォールポリシーの関連付けは一旦、空のファイアウォールポリシーを作成して関連付ける を選択し、ファイアウォールを作成 をクリックします。

しばらく待つとファイアウォールのステータスが 準備完了 になります。

ファイアウォールの作成完了後、VPC エンドポイントを確認してみると GatewayLoadBalancer のエンドポイントが作成されていることから、先日リリースされた AWS Gateway Load Balancer が内部的に使われてることが判ります。

ファイアウォールポリシーの設定

[AWS ネットワークファイアウォール] - [ファイアウォールポリシー] を開き、先程作成した空のファイアウォールポリシーをクリックします。

まだルールグループが設定されていませんので、ルールグループを追加します。ルールグループには ステートレスルールグループステートフルルールグループ の 2 タイプが存在します。

ステートレスルールグループ

ステートレスルールグループはトラフィックの方向やその他の関連パケットなどのコンテキストを考慮しません。つまり、リクエストと戻りのトラフィックはそれぞれ個別にフィルタリングされます。

ステートレスルールグループは 5-tuple ルールになりますので以下の項目でフィルタします。感覚的にはネットワーク ACL と同じと思っておいて良いでしょう。

  • 送信元アドレス
  • 宛先アドレス
  • 送信元ポート番号
  • 宛先ポート番号
  • プロトコル

ステートレスルールエンジンはファイアウォールログを取得できません。

ステートフルルールグループ

ステートフルルールグループはトラフィック方向などのコンテキストを考慮し、より複雑なルールとファイアウォールログの取得が可能です。

ステートレスルールグループ同様の 5-tuple を含み、以下 3 つのルールタイプが利用可能です。

  • 5-tuple ルール
  • ドメインリストルール
  • Suricata 互換 IPS ルール

高度なフィルタリング、ログの取得などメリットがある一方、ステートフルルールエンジンは検査のためにパケットをグループ化するため、パケット配信が遅延する可能性がある点は理解しておく必要がありそうです。

ステートフルルールグループの追加

今回はせっかくですのでドメインリストでのフィルタを試したいと思います。ステートレスルールグループは作成せず、ステートフルルールグループの [ルールグループを追加] プルダウンメニューから 新しいステートフルルールグループの作成と追加 をクリックします。

任意の名前を入力し、[ステートフルルールグループのオプション] は Domain list を選択します。このルールグループに許可される最大処理キャパシティーは一旦 10 に設定しました。キャパシティーは条件の組み合わせ数です。例えば 30 のプロトコルを指定し、3 つのソース、5 つの宛先のルールを作成する必要がある場合、キャパシティーは 30 x 3 x 5 = 450 になります。

リージョンごとのアカウントあたりのクォーターがあり、ステートレスルールグループはファイアウォールポリシーあたり 10,000、ステートフルルールグループはファイアウォールポリシーあたり 30,000 となっています。無用に大きなキャパシティは設定しないほうが良いですが、作成したルールグループのキャパシティは変更できないため、再作成が必要になります。

あってはならないことですが今回は dev.classmethod.jp への HTTP/HTTPS をブロックするようにルールを指定し、作成と追加 をクリックします。

ルートテーブルの編集

ファイアウォールエンドポイントをインターネットゲートウェイと保護対象のサブネットの間に挿入するようにルートテーブルを編集します。構成は冒頭の Multi zone architecture with an internet gateway と同じです。

インターネットゲートウェイ用

VPC Ingress Routing でインターネットゲートウェイにルートテーブルを設定します。対象のルートテーブルを選択、右クリックメニューから Edit edge associations を開く

対象の VPC を選択し、Save をクリックします。

ルートテーブルは以下のように us-east-1aus-east-1b でそれぞれに作成された Gateway Load Balancer エンドポイントを指定しました。(冒頭のルートテーブル図を見ると fgw-xxx を指定しているようですが、コンソールからファイアウォールゲートウェイ ID のようなものは見つけることが出来ませんでした)

ファイアウォールサブネット用

ファイアウォールサブネットのルートテーブルに 0.0.0.0/0 をインターネットゲートウェイへのルートに設定しています。

保護サブネット用

保護されるサブネットのルートテーブルは AZ ごとに分け、それぞれ 0.0.0.0/0 を各 AZ の Gatway Load Balancer に設定しています。

ログ設定

対象のネットワークファイアウォールを開き、[ログ記録] の 編集 をクリックします。

今回は Aleart タイプのみを CloudWatch log group に配信するようにしました。

試してみる

それではバージニア北部の保護サブネット内からアクセスしてみます。まずは正常にアクセスできる classmethod.jp にリクエストを送ります。

$ curl -I https://classmethod.jp/
HTTP/2 200 
content-type: text/html
content-length: 55548
date: Wed, 18 Nov 2020 06:03:25 GMT
last-modified: Wed, 18 Nov 2020 01:02:56 GMT
x-amz-version-id: GbS72RhTg.eMO2Hkw1IT_ElJwbjavXvg
etag: "e21acbb99ee0bac09a27f7d6e6fcbed2"
server: AmazonS3
vary: Accept-Encoding
x-cache: Miss from cloudfront
via: 1.1 6d6f74bf59f17799db24ddb1f9f74166.cloudfront.net (CloudFront)
x-amz-cf-pop: IAD66-C1
x-amz-cf-id: 4VIUoxzNTUW07JSTf1UhDKVqx8nTVTiCHU__4K8_OlQcqmCuM0wwSQ==

問題ないですね。次にドメインリストでフィルタ登録した dev.classmethod.jp へアクセスしてみます。

$ curl -I https://dev.classmethod.jp/
curl: (28) Operation timed out after 300184 milliseconds with 0 out of 0 bytes received

おぉ!ドメインリストによるフィルターが効いています!!アラートログ設定した CloudWatch log を確認してみると以下のようなログが出力されていました。

{
    "firewall_name": "fwtest",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1605679412",
    "event": {
        "timestamp": "2020-11-18T06:03:32.201199+0000",
        "flow_id": 660680746476527,
        "event_type": "alert",
        "src_ip": "10.0.0.39",
        "src_port": 57980,
        "dest_ip": "13.248.222.227",
        "dest_port": 443,
        "proto": "TCP",
        "tx_id": 0,
        "alert": {
            "action": "blocked",
            "signature_id": 2,
            "rev": 1,
            "signature": "matching TLS denylisted FQDNs",
            "category": "",
            "severity": 1
        },
        "tls": {
            "sni": "dev.classmethod.jp",
            "version": "UNDETERMINED",
            "ja3": {},
            "ja3s": {}
        },
        "app_proto": "tls"
    }
}

検証は以上です!

さいごに

ドメインリストによるアクセス先の制御はよくご相談いただく内容で、「すみません、AWS マネージドサービスでは提供されていないのでユーザー側でプロキシサーバ作ってください」という回答を何度したことか。

エンドポイント起動料金だけで AZ ごとに月額 $300 ほど掛かりますが EC2 プロキシサーバの可用性、スケーラビリティ、OS/ミドルのパッチ...etc などの運用コストを考慮して検討されるのが良いでしょう。AWS Transit Gateway などを活用し、共通基盤として利用することができればプロキシサーバ管理から解放される日も遠くなさそうですね。(東京リージョンはまだですが、、)

今回はドメインリストでの単純なルールのみでしたが、Suricata 互換 IPS ルールなども今後試してみたいと思います。

以上!大阪オフィスの丸毛(@marumo1981)でした!