セキュリティグループ/ファイアーウォール併用パターン#

本構成はFJcloud-O 従来リージョン向けとなります。
東日本/西日本リージョン3ではファイアーウォールの設定手順が異なります。

要求事項#

  • セキュリティを高めるための基本の設定である セキュリティグループ に加え、ファイアーウォールを使用することでシステムのセキュリティをさらに高めたい

対応するデザインパターン概要#

本パターンでは、ファイアウォールを使用し不正アクセスなどの不要な通信を明示的に拒否する例を紹介します。

1. FJcloud-Oで提供されるセキュリティを高めるための2つの機能#

FJcloud-Oでは、セキュリティを高める機能として セキュリティグループ と ファイアーウォールが用意されています。

セキュリティグループは、アクセス制御ルールをあらかじめグルーピングし、そのグループ名を使用することで、IPアドレスを意識せずアクセス制御設定を行うことができる機能です。
セキュリティグループ活用 に記載したとおり、 仮想サーバやロードバランサーを作成する時に、グルーピングしたアクセス制御設定(=セキュリティグループ)を指定するだけで、仮想サーバやロードバランサーの作成と同時にアクセス制御ができるようになります。
オートスケールで増設される仮想サーバに自動的にセキュリティグループを設定するといった使い方も可能です。

これに対して FJcloud-Oが提供するファイアーウォールでは、 セキュリティグループにはない機能として、アクセス元やアクセス先等を明示して拒否する機能があります。
不正アクセスやサービス不能攻撃などに対しIPアドレス・ポートを使用して明示的に拒否したい場合には、ファイアーウォールを設定することで特定の通信を拒否できるようになります。

2. セキュリティグループとファイアーウォールの指定方法の違いと使い分け#

FJcloud-Oのセキュリティグループとファイアーウォールのルール指定方法の違いを以下に記載します。
その他の設定項目は機能説明書を参照してください。

項目 セキュリティグループ ファイアーウォール
設定する対象                                                                                         仮想サーバやロードバランサー、仮想サーバに付けられたポート
(仮想サーバに付けられたポートといった文脈の場合は、ポートは、OpenStack用語でいわゆるネットワークインターフェースを指す)
仮想ルータ
通信方向の指定                                   セキュリティグループを適用するサーバ等に対する受信(ingress)、送信(egress)
通信相手の指定                                         通信相手のIP/CIDR、相手のセキュリティグループ名 送信元IP/CIDR、送信先IP/CIDR
プロトコル、ポート番号 セキュリティグループを適用するサーバ等がオープンするポート番号 送信元ポート番号、送信先ポート番号
アクション 許可のみ 許可、拒否
判定 どれか1つでもルールにマッチした通信は許可 優先順位にしたがってルールを判定し、最初にマッチしたルールで許可、拒否

Note

上記の違いにより、FJcloud-Oでセキュリティを高めるそれぞれの機能は、

1. 仮想サーバやロードバランサーのアクセス制御など、まず基本としてセキュリティグループを使用
2. 不正アクセスやサービス不能攻撃などで特定ポート・通信先を拒否する場合などにファイアーウォールを使用

という使い分けを推奨します。

3. 推奨するセキュリティグループとファイアーウォールの併用パターン#

そこで実装サンプルでは、使い分けの例として、セキュリティグループとファイアーウォールを併用した設定例を記載します。

  • 仮想ルータにファイアーウォールを設定

    • 特定のIPアドレスからの通信をすべて拒否
    • すべてのアクセス元からロードバランサーに対して http (80/tcp) のアクセスを許可
    • その他すべて拒否
  • ロードバランサー用のセキュリティグループ "SG_LB" で、 すべてのアクセス元から http (80/tcp) の受信を許可/ロードバランサーからWebサーバへの送信を許可

  • Webサーバ用のセキュリティグループ "SG_Web" で、 アクセス元 "SG_LB" からのhttp (81/tcp) の受信を許可

Note

  • 本パターンでは、ロードバランサーやWebサーバに必要な通信についてのみ記載しています。実際の設定上は、仮想サーバの起動時に必要な情報であるメタデータを取得するための設定等が必要になります。メタデータ取得のための設定については、インターネット接続パターン をご覧ください。
  • Webサーバで待ち受けするポート番号は、後述する アクセス制御の多重化 の観点で、ロードバランサーが待ち受けするポート番号とは別のポート番号にすることを推奨します。
  • 構造 (イメージ図)#

    image

    実装サンプル#

    1. セキュリティグループとファイアーウォールの設定内容#

    (1) セキュリティグループ#

    以下の内容で設定します。
    セキュリティグループの設定方法については、インターネット接続パターン に記載の手順を参照してください。

    • セキュリティグループ "SG_LB"
      http (80/tcp) の受信をすべて許可/セキュリティグループ "SG_Web"の http (81/tcp) への送信を許可
    ルール 方向 オープンポート ポート 接続先 セキュリティグループまたは CIDR IPバージョン
    カスタムTCPルール 受信 ポート 80 CIDR 0.0.0.0/0 IPv4
    カスタムTCPルール 送信 ポート 81 セキュリティグループ SG_Web IPv4
    • セキュリティグループ "SG_Web"
      セキュリティグループ "SG_LB" から http (81/tcp) への受信を許可
    ルール 方向 オープンポート ポート 接続先 セキュリティグループまたは CIDR IPバージョン
    カスタムTCPルール 受信 ポート 81 セキュリティグループ SG_LB IPv4

    (2) ファイアーウォール#

    以下の内容で設定します。
    ロードバランサーや仮想サーバを配備した内部ネットワークのセグメントは "192.168.1.0/24" とします。

    (A) 設定内容#
    no 名前 プロトコル IP種別 アクション Srcアドレス Srcポート Destアドレス Destポート
    1 http_ng tcp 4 deny xx.1.2.3/32 null null null
    2 http_ok tcp 4 allow null null 192.168.1.0/24 80
    3 all_ng null 4 deny null null null null
    • no.1 特定の通信を拒否
      例として、特定のIPアドレス "xx.1.2.3/32" からの通信をすべて拒否します。
      本パターンでは、後からこのルールを追加する手順例を記載します。

    • no.2 インターネットに公開するサーバとポートを許可
      すべてのアクセス元から、ロードバランサーが存在するセグメントに対して、http (80/tcp) のアクセスを許可します。
      インターネットに公開する (グローバルIPアドレスを付与された) 仮想サーバに対してアクセス制御する場合は、仮想サーバのプライベートIPアドレスを指定します。

    • no.3 その他すべて拒否
      ファイアーウォールでは、ポリシー内で自動的に「DENY ALL」ルールが最後尾に追加されます。
      これにより、許可ルールの定義されないトラフィックはデフォルトで遮断されます(ホワイトリスト方式)。
      本パターンでは説明上 "all_ng" ルールを追加していますが、"all_ng" のルールの内容は明示的に指定しなくてもファイアーウォールに適用されます。

    (B) 設定内容について#

    FJcloud-Oの仮想ルータで NATで付与したグローバルIPアドレスへのアクセス制限は、グローバルIPアドレスに対する元のプライベートIPアドレスの方に対して設定します。

    上記の 構造 (イメージ図) の例の場合、ロードバランサーをインターネットに公開しているため、ロードバランサーにグローバルIPアドレスが付与されていますが、ファイアーウォールでアクセス制御を行う場合は、ロードバランサーのプライベートIPアドレスを使用します。

    なおロードバランサーのIPアドレスは、無停止保守により、配備されたセグメントの範囲内で変わることがあります。(その場合、ロードバランサーのグローバルIPアドレスも変わります。)
    そのため、ロードバランサーに対してファイアーウォールでアクセス制御する場合は、上記表の "http_ok" で定義した Dest アドレスのように、ロードバランサーを配備した内部ネットワークのセグメント "192.168.1.0/24" への送信に対して設定するようにします。

    (C) アクセス制御の多重化について#

    ロードバランサーに対してファイアーウォールでアクセス制御を行う場合は、上記のとおり、ロードバランサーを設置するセグメントに対してアクセス制御を行います。

    また、ロードバランサーは、Webサーバと同一のセグメントに配置する必要があります。
    そのため、ロードバランサーの待ち受けポート番号とWebサーバの待ち受けポート番号を同一にしている場合で、ファイアーウォールでロードバランサーの待ち受けポート番号を許可と設定すると、ファイアーウォール上ではWebサーバの待ち受けポート番号が許可された状態になってしまいます。

    Webサーバの待ち受けポート番号はセキュリティグループでアクセス制御されていますが、Webサーバの待ち受けポート番号をロードバランサーと別にしておくことで、より安全性の高い状態になります。
    このように、アクセス制御を多重化するという観点で、Webサーバの待ち受けポート番号は、ロードバランサーの待ち受けポート番号とは別のポート番号とすることを推奨します。

    2. ファイアーウォールのルール設定手順#

    初めに基本的な設定をした後、特定通信を拒否するルールを追加する手順を記載します。

    (1) ファイアーウォールルールの作成#

    以下のAPIに、設定項目(json)を設定し、それぞれ実行してください。

    (A) "http_ok" ルールの作成#
    • 設定項目(json)
    項目 設定値例 内容
    $NAME "http_ok" 任意の名称
    $AC "allow" アクセス許可(allow)/拒否(deny)
    $DESTINATION_PORT "80" 送信先ポート番号
    $PROTOCOL "tcp" tcp/udp/icmp
    $AVAILABILITY_ZONE "jp-east-1a" アベイラビリティゾーン名
    • 実行API

      curl -X POST -s $NETWORK/v2.0/fw/firewall_rules -H "X-Auth-Token: $OS_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"firewall_rule": { "name": "'$NAME'" ,"action": "'$AC'", "destination_port": "'$DESTINATION_PORT'", "protocol": "'$PROTOCOL'", "availability_zone": "'$AVAILABILITY_ZONE'" }}' | jq .
      

    • 確認API

      curl -s $NETWORK/v2.0/fw/firewall_rules -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" | jq .
      

    (B) "all_ng" ルールの作成#
    • 設定項目(json)
    項目 設定値例 内容
    $NAME "all_ng" 任意の名称
    $AC "deny" アクセス許可(allow)/拒否(deny)
    $AVAILABILITY_ZONE "jp-east-1a" アベイラビリティゾーン名
    • 実行API

      curl -X POST -s $NETWORK/v2.0/fw/firewall_rules -H "X-Auth-Token: $OS_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"firewall_rule": { "name": "'$NAME'" ,"action": "'$AC'", "availability_zone": "'$AVAILABILITY_ZONE'" }}' | jq .
      

    • 確認API

      curl -s $NETWORK/v2.0/fw/firewall_rules -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" | jq .
      

    (2) ファイアーウォールポリシーの作成#

    作成したルールをもとに、ファイアーウォールポリシーを作成します。 設定した順に優先順位がつけられます。

    • 設定項目(json)
    項目 設定値例 内容
    $NAME "testfwp" 任意の名称
    $FWR1 (生成されたID) (a)のルール作成時に生成されたID
    $FWR2 (生成されたID) (b)のルール作成時に生成されたID
    $AVAILABILITY_ZONE "jp-east-1a" アベイラビリティゾーン名
    • 実行API

      curl -X POST -s $NETWORK/v2.0/fw/firewall_policies -H "X-Auth-Token: $OS_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"firewall_policy":{"firewall_rules": [ "'$FWR1'", "'$FWR2'" ], "name": "'$NAME'", "availability_zone": "'$AVAILABILITY_ZONE'"}}' | jq .
      

    • 確認API

      curl -s $NETWORK/v2.0/fw/firewall_policies -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" | jq .
      

    (3) ファイアーウォールポリシーを仮想ルータに適用#

    作成しファイアーウォールポリシーを仮想ルータに適用します。

    • 設定項目(json)
    項目 設定値例 内容
    $NAME "testfw" 任意の名称
    $FWP (生成されたID) ファイアーウォールポリシー作成時に生成されたID
    $ROUTER_ID (生成されたID) ファイアーウォールポリシーを割り当てる仮想ルータのID
    $AVAILABILITY_ZONE "jp-east-1a" アベイラビリティゾーン名
    • 実行API

      curl -X POST -s $NETWORK/v2.0/fw/firewalls -H "X-Auth-Token: $OS_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"firewall": {"name": "'$NAME'","firewall_policy_id": "'$FWP'", "router_id": "'$ROUTER_ID'", "availability_zone": "'$AVAILABILITY_ZONE'"}}' | jq .
      

    • 確認API

      curl -s $NETWORK/v2.0/fw/firewalls -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" | jq .
      

    (4) 追加するルールを作成#

    特定IPアドレスからの接続を拒否する "http_ng" ルールを作成します。

    • 設定項目(json)
    項目 設定値例 内容
    $NAME "http_ng" 任意の名称
    $AC "deny" アクセス許可(allow)/拒否(deny)
    $SOURCE_IP "xx.1.2.3/32" 送信元IPアドレス
    $PROTOCOL "tcp" tcp/udp/icmp
    $AVAILABILITY_ZONE "jp-east-1a" アベイラビリティゾーン名
    • 実行API

      curl -X POST -s $NETWORK/v2.0/fw/firewall_rules -H "X-Auth-Token: $OS_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"firewall_rule": { "name": "'$NAME'" ,"action": "'$AC'", "source_ip_address":"'$SOURCE_IP'" , "protocol": "'$PROTOCOL'", "availability_zone": "'$AVAILABILITY_ZONE'" }}' | jq .
      

    • 確認API

      curl -s $NETWORK/v2.0/fw/firewall_rules -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" | jq .
      

    (5) "http_ng" ルールをファイアーウォールポリシーに挿入#

    特定IPアドレスからの接続を拒否する "http_ng" ルールをファイアーウォールポリシーに挿入します。

    • 設定項目(json)
    項目 設定値例 内容
    $FWP_ID (生成されたID) 挿入対象のファイアーウォールポリシーのID
    $FWR_ID (生成されたID) 作成した "http_ng" ルールのID
    $INSERT_AFTER *1 (生成されたID) 後ろに挿入したい場合のルールID
    本例の場合、設定なし
    $INSERT_BEFORE *1 (生成されたID) 前に挿入したい場合のルールID
    本例の場合、"http_ok" ルールのIDを設定

    *1 INSERT_AFTERまたはINSERT_BEFOREは片方のみ指定で構いません。
     どちらも空白の場合、最上位(一番上)に挿入されます。
     どちらも指定された場合、INSERT_BEFOREが有効になりますが、仕様が明確ではないため、確実に順序を指定したい場合、片方のみご指定ください。

    • 実行API

      curl -X PUT -s $NETWORK/v2.0/fw/firewall_policies/$FWP_ID/insert_rule -H "X-Auth-Token: $OS_AUTH_TOKEN" -H "Content-Type: application/json" -d '{"firewall_rule_id": "'$FWR_ID'" ,"insert_after": "'$INSERT_AFTER'", "insert_before": "'$INSERT_BEFORE'" }' | jq . 
      

    • 確認API

      curl -s $NETWORK/v2.0/fw/firewall_policies/$FWP_ID -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" | jq .
      

    メリット・効果#

    本パターンを利用して、セキュリティグループとファイアーウォールを併用した場合のメリット・効果は以下の通りです。

    • ファイアーウォールで不正アクセス元等の特定通信を拒否する設定が可能となり、 セキュリティグループのみの状態からセキュリティをさらに高めることが可能

    注意事項#

    • 本パターンは2017年6月時点のFJcloud-O 従来リージョンで動作検証しています。

    • ロードバランサのIPアドレスは変更されることがあるため、セキュリティグループでアクセス制御することを推奨します。 ファイアーウォールのみでアクセス制御することは推奨しません。

    • セキュリティグループやファイアーウォールのルールの変更時、既に張られているセッションはルールを変更後もセッションが残ります。

      • DoS攻撃などで特定IPアドレスからの通信を拒否したい場合も、セッションが残っている間は新たなルールが適用されません。 通信が許可されている状態です。
      • ルール変更後に張られた新規セッションは正常に拒否されます。
      • ファイアーウォールのルール適用時の全セッション強制切断機能は提供済です。
    • ファイアーウォール/ファイアーウォールポリシー/ファイアーウォールルールのIDは、サンプル等から絶対にコピーペーストしないでください。

    • 自プロジェクト以外のポリシーのID、またはルールのIDが設定されると、作成されたファイアーウォールは異常な状態となります。その状態になった場合、利用者での削除ができなくなり、サポート窓口での削除対応が必要になります。

    • 本パターンでは、ロードバランサーやWebサーバに必要な通信についてのみ記載しています。 実際の設定上は、仮想サーバの起動時に必要な情報であるメタデータを取得するための設定等が必要になります。メタデータ取得のための設定については、インターネット接続パターン をご覧ください。

    その他#

    ファイアーウォール機能、セキュリティグループ機能の機能配置イメージ#

    FJcloud-O で提供する OpenStack ベースのファイアーウォール機能 や セキュリティグループ機能 は、物理環境での構成と比較すると、仮想環境では以下のような機能配置のイメージになります。

    image