Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

17.14. ネットワークフィルターの適用

本セクションは、libvirt のネットワークフィルターと、その目的、概念、および XML 形式の概要を説明します。

17.14.1. 導入部分

ネットワークフィルタリングの目的は、仮想システムの管理者が、仮想マシンでネットワークトラフィックフィルタリングルールを設定および適用し、仮想マシンが送受信できるネットワークトラフィックのパラメーターを管理できるようにすることです。ネットワークトラフィックフィルタリングルールは、仮想マシンの起動時にホストの物理マシンに適用されます。フィルタリングルールは仮想マシン内からは回避できないため、仮想マシンユーザーの視点からは必須となります。
ゲスト仮想マシンの視点からは、ネットワークフィルタリングシステムにより、各仮想マシンのネットワークトラフィックフィルタリングルールをインターフェイスごとに個別に設定できます。このルールは、仮想マシンの起動時にホストの物理マシンに適用され、仮想マシンの実行中に変更できます。後者は、ネットワークフィルターの XML 記述を変更することで実現できます。
複数の仮想マシンが、同じ汎用ネットワークフィルターを使用できます。このフィルターを変更すると、このフィルターを参照する実行中の仮想マシンのネットワークトラフィックフィルタリングルールがすべて更新されます。起動時に、実行していないマシンが更新されます。
前述のように、ネットワークトラフィックフィルタリングルールを適用する場合は、特定のタイプのネットワーク設定に設定された個別のネットワークインターフェイスを使用できます。対応しているネットワークタイプは、次のとおりです。
  • network
  • ethernet -- bridging モードで使用する必要があります。
  • bridge

例17.1 ネットワークフィルタリングの例

インターフェイス XML は、トップレベルフィルターを参照するために使用されます。以下の例では、インターフェイスの説明は、フィルターの clean-traffic を参照します。
   <devices>
    <interface type='bridge'>
      <mac address='00:16:3e:5d:c7:9e'/>
      <filterref filter='clean-traffic'/>
    </interface>
  </devices>
ネットワークフィルターは XML で記述されており、他のフィルターへの参照、トラフィックフィルタリングのルール、または両方の組み合わせを含むことができます。上記の参照フィルターの clean-traffic は、他のフィルターへの参照のみが含まれ、実際のフィルタールールがないフィルターです。他のフィルターへの参照も使用できるため、フィルターツリーを構築できます。clean-traffic フィルターは、# virsh nwfilter-dumpxml clean-traffic コマンドを使用して表示できます。
前述のように、1 つのネットワークフィルターを、複数の仮想マシンで参照できます。インターフェイスは通常、各トラフィックフィルタリングルールに関連付けられた個々のパラメーターを持つため、フィルターの XML で説明されているルールは、変数を使用して一般化できます。この場合、フィルター XML では変数名が使用され、フィルターが参照される場所に名前と値が提供されます。

例17.2 説明の拡張

以下の例では、インターフェイスの説明が、パラメーター IP と、ドット付き IP アドレスを値として拡張されています。
  <devices>
    <interface type='bridge'>
      <mac address='00:16:3e:5d:c7:9e'/>
      <filterref filter='clean-traffic'>
        <parameter name='IP' value='10.0.0.1'/>
      </filterref>
    </interface>
  </devices>
この例では、clean-traffic ネットワークトラフィックフィルターは IP アドレスパラメーター 10.0.0.1 で表されます。ルールでは、このインターフェイスからのすべてのトラフィックが常にソース IP アドレスとして 10.0.0.1 を使用することを規定しており、これはこの特定のフィルターの目的の 1 つになります。

17.14.2. チェーンのフィルター

フィルタリングルールはフィルターチェーンで編成されています。このようなチェーンは、パケットフィルタリングルールを持つツリー構造を、個々のチェーン (分岐) のエントリーとして持つと考えることができます。
パケットは root チェーンでフィルター評価を開始し、他のチェーンで評価を継続し、これらのチェーンから root チェーンに戻るか、トラバースされたチェーンの 1 つでフィルタールールによりドロップまたは許可されます。
libvirt のネットワークフィルタリングシステムは、ユーザーがトラフィックフィルタリングのアクティブ化を選択する仮想マシンのネットワークインターフェイスごとに、個々の root チェーンを自動的に作成します。ユーザーは、root チェーンで直接インスタンス化されるフィルタリングルールを作成するか、プロトコル固有のルールを効率的に評価するためにプロトコル固有のフィルタリングチェーンを作成できます。
以下のチェーンが存在します。
  • root
  • mac
  • stp (スパニングツリープロトコル)
  • vlan
  • arp と rarp
  • ipv4
  • ipv6
mac、stp、vlan、arp、rarp、ipv4、または ipv6 のプロトコルを評価する複数のチェーンは、プロトコル名をチェーン名の接頭辞としてのみ使用して作成できます。

例17.3 ARP トラフィックフィルタリング

この例では、名前が arp-xyz または arp-test のチェーンを指定し、そのチェーンで ARP プロトコルパケットが評価されるようにします。
以下のフィルター XML は、arp チェーンでの ARP トラフィックのフィルタリング例を示しています。
<filter name='no-arp-spoofing' chain='arp' priority='-500'>
  <uuid>f88f1932-debf-4aa1-9fbe-f10d3aa4bc95</uuid>
  <rule action='drop' direction='out' priority='300'>
    <mac match='no' srcmacaddr='$MAC'/>
  </rule>
  <rule action='drop' direction='out' priority='350'>
    <arp match='no' arpsrcmacaddr='$MAC'/>
  </rule>
  <rule action='drop' direction='out' priority='400'>
    <arp match='no' arpsrcipaddr='$IP'/>
  </rule>
  <rule action='drop' direction='in' priority='450'>
    <arp opcode='Reply'/>
    <arp match='no' arpdstmacaddr='$MAC'/>
  </rule>
  <rule action='drop' direction='in' priority='500'>
    <arp match='no' arpdstipaddr='$IP'/>
  </rule>
  <rule action='accept' direction='inout' priority='600'>
    <arp opcode='Request'/>
  </rule>
  <rule action='accept' direction='inout' priority='650'>
    <arp opcode='Reply'/>
  </rule>
  <rule action='drop' direction='inout' priority='1000'/>
</filter>
root チェーンなどではなく、ARP 固有のルールを arp チェーンに配置すると、ARP 以外のパケットプロトコルは ARP プロトコル固有のルールで評価される必要がなくなります。これにより、トラフィックフィルタリングの効率が向上します。ただし、その他のルールは評価されないため、指定したプロトコルのフィルタリングルールのみをチェーンに組み込むことに注意する必要があります。たとえば、IPv4 プロトコルパケットは ARP チェーンを通過しないため、IPv4 ルールは ARP チェーンで評価されません。

17.14.3. チェーンの優先度のフィルタリング

前述のように、フィルタールールを作成すると、すべてのチェーンが root チェーンに接続されます。これらのチェーンへのアクセス順序は、チェーンの優先度の影響を受けます。優先度を割り当てることができるチェーンと、そのデフォルトの優先度を以下の表に示します。

表17.1 チェーンのデフォルトの優先度の値のフィルタリング

チェーン (接頭辞) デフォルトの優先度
stp -810
mac -800
vlan -750
ipv4 -700
ipv6 -600
arp -500
rarp -400
注記
優先度が低いチェーンは、優先度が高いチェーンの前にアクセスされます。
表17.1「チェーンのデフォルトの優先度の値のフィルタリング」 に記載されているチェーンは、[-1000 から 1000] の範囲の値をフィルターノードの priority (XML) 属性に書き込むことで、カスタム優先度を割り当てることもできます。「チェーンのフィルター」 フィルターは、arp チェーンのデフォルト優先度 -500 を表示します。以下に例を示します。

17.14.4. フィルターにおける変数の使用

ネットワークトラフィックフィルターサブシステム (MAC と IP) で使用するために予約されている変数には、次の 2 つがあります。
MAC は、ネットワークインターフェイスの MAC アドレスに指定されます。この変数を参照するフィルタリングルールは、自動的にインターフェイスの MAC アドレスに置き換えられます。これは、MAC パラメーターを明示的に指定する必要なく機能します。上記の IP パラメーターに似た MAC パラメーターを指定できる場合でも、libvirt は、インターフェイスが使用する MAC アドレスを認識しているため、推奨できません。
パラメーターIP は、仮想マシン内のオペレーティングシステムが、指定のインターフェイスで使用する IP アドレスを表します。パラメーターが明示的に指定されずに参照されている場合に、インターフェイスで使用されている IP アドレス (つまり IP パラメーターの値) を libvirt デーモンが判断しようとする限り、IP パラメーターは特別なものとなります。現在の IP アドレス検出の制限は、この機能の使用方法と、その使用時に想定される制限に関する「制限」を参照してください。「チェーンのフィルター」 に示す XML ファイルには、フィルターno-arp-spoofingが含まれています。これは、ネットワークフィルター XML を使用して MAC 変数および IP 変数を参照する例です。
参照変数の前には、常に $ という文字が付くことに注意してください。変数の値の形式は、XML で識別されるフィルター属性で期待されるタイプである必要があります。上記の例では、IP パラメーターは、標準形式の正しい IP アドレスを保持する必要があります。正しい構造を指定しないと、フィルター変数が値に置き換わりません。また、ホットプラグの使用時に、仮想マシンの起動が妨げられたり、インターフェイスの接続が妨げられたりします。各 XML 属性で期待されるタイプの一部を、サンプル例17.4「サンプルの変数の種類」に示します。

例17.4 サンプルの変数の種類

変数には要素のリストが含まれる場合があります (変数 IP には、特定のインターフェイスで有効な 複数 IP アドレスを指定できるなど)。IP 変数に複数の要素を指定する表記は以下のようになります。
  <devices>
    <interface type='bridge'>
      <mac address='00:16:3e:5d:c7:9e'/>
      <filterref filter='clean-traffic'>
        <parameter name='IP' value='10.0.0.1'/>
        <parameter name='IP' value='10.0.0.2'/>
        <parameter name='IP' value='10.0.0.3'/>
      </filterref>
    </interface>
  </devices>
この XML ファイルは、インターフェイスごとに複数の IP アドレスを有効にするフィルターを作成します。各 IP アドレスは、個別のフィルタリングルールになります。そのため、上記の XML および以下のルールを使用して、3 つの個別のフィルタリングルール (各 IP アドレスに 1 つ) が作成されます。
  <rule action='accept' direction='in' priority='500'>
    <tcp srpipaddr='$IP'/>
  </rule>
要素のリストを含む変数の個々の要素にアクセスできるように、以下のようなフィルタリングルールは、変数DSTPORTS の 2 番目の要素にアクセスします。
  <rule action='accept' direction='in' priority='500'>
    <udp dstportstart='$DSTPORTS[1]'/>
  </rule>

例17.5 さまざまな変数の使用

そのため、$VARIABLE[@<iterator id="x">] という表記を使用して、別のリストから許可されるルールをすべて表すフィルタールールールを作成できます。以下の規則では、仮想マシンが、DSTPORTS で指定された一連のポートで、SRCIPADDRESSES で指定された送信元 IP アドレスのセットからトラフィックを受信できるようにします。この規則では、2 つの独立したイテレーターを使用して、変数 DSTPORTS の要素と SRCIPADDRESSES の要素の組み合わせをすべて生成します。
  <rule action='accept' direction='in' priority='500'>
    <ip srcipaddr='$SRCIPADDRESSES[@1]' dstportstart='$DSTPORTS[@2]'/>
  </rule>
以下のように、SRCIPADDRESSES および DSTPORTS に具体的な値を割り当てます。
  SRCIPADDRESSES = [ 10.0.0.1, 11.1.2.3 ]
  DSTPORTS = [ 80, 8080 ]
$SRCIPADDRESSES[@1] および $DSTPORTS[@2] を使用して変数に値を割り当てると、次に示すように、アドレスおよびポートのバリアントがすべて作成されます。
  • 10.0.0.1, 80
  • 10.0.0.1, 8080
  • 11.1.2.3, 80
  • 11.1.2.3, 8080
表記法 $SRCIPADDRESSES[@1]$DSTPORTS[@1] を使用するなど、1 つのイテレーターを使用して同じ変数にアクセスすると、両方のリストにパラレルアクセスが行われ、結果が以下のようになります。
  • 10.0.0.1, 80
  • 11.1.2.3, 8080
注記
$VARIABLE は、$VARIABLE[@0] の省略形です。以前の表記法は、このセクションの上部にある最初の段落に示されているように、iterator id="0" が追加されたイテレーターのロールを常に想定しています。

17.14.5. 自動 IP アドレス検出と DHCP スヌーピング

本セクションでは、自動 IP アドレス検出および DHCP スヌーピングに関する情報を提供します。

17.14.5.1. 導入部分

仮想マシンのインターフェイスで使用される IP アドレスの検出は、変数 IP が参照されているにもかかわらず、その変数に値が割り当てられていない場合に、自動的にアクティブになります。変数 CTRL_IP_LEARNING を使用して、使用する IP アドレス学習方法を指定できます。有効な値は、anydhcp、または none です。
any 値は、仮想マシンが使用しているアドレスを判断するために、libvirt にパケットを使用するように指示します。これは、変数 CTRL_IP_LEARNING が設定されていない場合のデフォルト設定です。この方法では、インターフェイスごとに 1 つの IP アドレスのみが検出されます。ゲスト仮想マシンの IP アドレスが検出されると、IP アドレススプーフィングがフィルターのいずれかで阻止された場合などに、そのアドレスへの IP ネットワークトラフィックがロックされます。この場合、仮想マシンのユーザーはゲスト仮想マシン内のインターフェイスで IP アドレスを変更できません。このインターフェイスは、IP アドレスのスプーフィングと見なされます。ゲスト仮想マシンが別のホスト物理マシンに移行されるか、サスペンド操作後に再開されると、ゲスト仮想マシンによって送信される最初のパケットによって、ゲスト仮想マシンが特定のインターフェイスで使用できる IP アドレスが再度決定されます。
dhcp の値は、有効なリースを持つ DHCP サーバーが割り当てられたアドレスのみを有効にするように libvirt に指示します。この方法は、インターフェイスごとに複数の IP アドレスの検出と使用をサポートします。一時停止の操作後にゲスト仮想マシンが再開すると、有効な IP アドレスリースがそのフィルターに適用されます。これを行わないと、ゲスト仮想マシンは DHCP を使用して新しい IP アドレスを取得することが期待されます。ゲスト仮想マシンを別の物理ホストの物理マシンに移行する場合は、ゲスト仮想マシンが DHCP プロトコルを再実行する必要があります。
CTRL_IP_LEARNING を none に設定すると、libvirt は、明示的な値を割り当てずに IP アドレスの学習および参照を行いません。これはエラーになります。

17.14.5.2. DHCP スヌーピング

CTRL_IP_LEARNING=dhcp (DHCP スヌーピング) では、追加のスプーフィング対策セキュリティーが提供されます。これは、信頼できる DHCP サーバーのみが IP アドレスを割り当てることができるフィルターと併用できます。これを有効にするには、変数 DHCPSERVER を、有効な DHCP サーバーの IP アドレスに設定し、この変数を使用して着信 DHCP 応答をフィルタリングするフィルターを提供します。
DHCP スヌーピングが有効で、DHCP リースが期限切れになると、ゲスト仮想マシンは、DHCP サーバーから新しい有効なリースを取得するまで IP アドレスを使用できなくなります。ゲスト仮想マシンを移行する場合は、(仮想マシンインターフェイスをダウンして再度起動するなどして) IP アドレスを使用するために、新しい有効な DHCP リースを取得する必要があります。
注記
自動 DHCP 検出は、ゲスト仮想マシンがインフラストラクチャーの DHCP サーバーと交換する DHCP トラフィックをリッスンします。libvirt に対するサービス拒否攻撃を回避するために、これらのパケットの評価の速度が制限されます。つまり、インターフェイスで 1 秒あたりに過剰な数の DHCP パケットを送信するゲスト仮想マシンでは、これらのパケットがすべて評価されないため、フィルターが調整されない可能性があります。通常の DHCP クライアントの動作は、1 秒あたりの DHCP パケット数が少ないことが想定されます。さらに、インフラストラクチャー内のすべてのゲスト仮想マシンに適切なフィルターを設定して、DHCP パケットを送信できないようにすることが重要です。したがって、ゲスト仮想マシンがポート 67 からポート 68 への UDP および TCP のトラフィックを送信しないようにするか、DHCPSERVER 変数をすべてのゲスト仮想マシンで使用して、DHCP サーバーのメッセージが信頼された DHCP サーバーからの送信のみを許可するように制限する必要があります。同時に、サブネット内のすべてのゲスト仮想マシンで スプーフィング対策を有効にする必要があります。

例17.6 DHCP スヌーピングに対する IP のアクティブ化

以下の XML は、DHCP スヌーピング方法を使用した IP アドレス学習のアクティベーションの例を示しています。
    <interface type='bridge'>
      <source bridge='virbr0'/>
      <filterref filter='clean-traffic'>
        <parameter name='CTRL_IP_LEARNING' value='dhcp'/>
      </filterref>
    </interface>

17.14.6. 予約されている変数

表17.2「予約変数」 は、予約済みと見なされ、libvirt が使用する変数を示しています。

表17.2 予約変数

変数名 定義
MAC インターフェイスの MAC アドレス
IP インターフェイスで使用されている IP アドレスのリスト
IPV6 現在実装されていません。インターフェイスで使用中の IPV6 アドレスのリストを表示します。
DHCPSERVER 信頼できる DHCP サーバーの IP アドレスのリスト
DHCPSERVERV6 現在実装されていない: 信頼できる DHCP サーバーの IPv6 アドレスのリスト
CTRL_IP_LEARNING IP アドレス検出モードの選択

17.14.7. 要素と属性の概要

すべてのネットワークフィルターに必要な root 要素には、2 つの属性を持つ <filter> という名前が付けられています。name 属性は、指定されたフィルターの一意の名前を提供します。chain 属性は任意ですが、基本となるホスト物理マシンのファイアウォールサブシステムを使用すると、効率的に処理するために、特定のフィルターをより適切に編成できます。現在、システムがサポートしているのは、rootipv4ipv6arp、および rarp のチェーンのみです。

17.14.8. その他のフィルターの参照

任意のフィルターは、他のフィルターへの参照を保持できます。各フィルターは、フィルターツリーで複数回参照できますが、フィルター間の参照ではループが発生しません。

例17.7 クリーンなトラフィックフィルターの例

以下は、その他のいくつかのフィルターを参照するクリーントラフィックネットワークフィルターの XML を示しています。
<filter name='clean-traffic'>
  <uuid>6ef53069-ba34-94a0-d33d-17751b9b8cb1</uuid>
  <filterref filter='no-mac-spoofing'/>
  <filterref filter='no-ip-spoofing'/>
  <filterref filter='allow-incoming-ipv4'/>
  <filterref filter='no-arp-spoofing'/>
  <filterref filter='no-other-l2-traffic'/>
  <filterref filter='qemu-announce-self'/>
</filter>
別のフィルターを参照するには、フィルターノード内に XML ノード <filterref> を提供する必要があります。このノードには、参照するフィルターの名前が含まれる属性フィルターが必要です。
新しいネットワークフィルターはいつでも定義でき、libvirt には知られていないネットワークフィルターへの参照を含むことができます。ただし、仮想マシンを起動するか、フィルターを参照しているネットワークインターフェイスをホットプラグすると、フィルターツリーの全ネットワークフィルターが利用可能になります。そうしないと、仮想マシンが起動しなくなり、ネットワークインターフェイスが接続できなくなります。

17.14.9. フィルタールール

次の XML は、発信 IP パケットの IP アドレス (変数 IP の値によって提供される) が予期されたものではない場合に、トラフィックをドロップするルールを実装するネットワークトラフィックフィルターの簡単な例を示しています。これにより、VM による IP アドレスのスプーフィングを防ぎます。

例17.8 ネットワークトラフィックフィルタリングの例

<filter name='no-ip-spoofing' chain='ipv4'>
  <uuid>fce8ae33-e69e-83bf-262e-30786c1f8072</uuid>
  <rule action='drop' direction='out' priority='500'>
    <ip match='no' srcipaddr='$IP'/>
  </rule>
</filter>
トラフィックフィルタリングルールは、ルールノードで開始します。このノードには、次の属性のうち最大 3 つを含むことができます。
  • action は必須で、次の値を指定できます。
    • drop (ルールに一致すると、分析は行われずにパケットが静かに破棄されます)
    • reject (ルールを一致させると、分析は行われずに ICMP 拒否メッセージが生成されます)
    • accept (ルールを一致させるとパケットを受け付けますが、これ以上分析は行いません)
    • return (ルールを一致させるとこのフィルターが渡されますが、制御を呼び出しフィルターに戻して詳細な分析を行います)
    • continue (ルールの一致は次のルールに進み、詳細な分析が行われます)
  • direction は必須で、次の値を指定できます。
    • 着信トラフィックには in
    • 送信トラフィックには out
    • 着信および送信トラフィックには inout
  • priority は任意です。ルールの優先度は、他のルールに関連してルールがインスタンス化される順序を制御します。値が低いルールは、値が大きいルールの前にインスタンス化されます。有効な値の範囲は、-1000 から 1000 です。この属性を指定しないと、優先度 500 がデフォルトで割り当てられます。root チェーンのフィルタリングルールは、優先順位に従って、root チェーンに接続されたフィルターでソートルールが分類されることに注意してください。これにより、フィルタリングルールとフィルターチェーンへのアクセスをインターリーブできます。詳細は、「チェーンの優先度のフィルタリング」を参照してください。
  • statematch はオプションです。設定可能な値は 0 または false で、基本的な接続状態の一致を無効にします。デフォルトの設定は true または 1 です。
詳細は、「高度なフィルター設定のトピック」 を参照してください。
上記の例の例17.7「クリーンなトラフィックフィルターの例」は、type ip のトラフィックがチェーンipv4に関連付けられ、ルールが priority=500 であることを示しています。たとえば、別のフィルターが参照されており、そのトラフィックの type ip がチェーンipv4 にも関連付けられている場合は、そのフィルターのルールが、示されているルールの priority=500 を基準にして順序付けされます。
ルールには、トラフィックをフィルタリングするためのルールを 1 つだけ含めることができます。上記の例は、タイプ ip のトラフィックがフィルタリングされることを示しています。

17.14.10. サポートされているプロトコル

以下のセクションでは、ネットワークフィルターサブシステムが対応しているプロトコルをリスト表示し、詳細を示します。このタイプのトラフィックルールは、ルールノードでネストされたノードとして提供されます。ルールがフィルタリングするトラフィックタイプに応じて、属性は異なります。上記の例は、ip トラフィックフィルタリングノード内で有効な単一の属性 srcipaddr を示しています。以下のセクションでは、どの属性が有効で、どのタイプのデータが期待されるかを示します。使用可能なデータ型は以下のとおりです。
  • UINT8 : 8 ビット整数。範囲 0〜255
  • UINT16 : 16 ビット整数。範囲 0〜65535
  • MAC_ADDR: ドット付き 10 進数形式の MAC アドレス (例: 00:11:22:33:44:55)
  • MAC_MASK: MAC アドレス形式の MAC アドレスマスク (例: FF:FF:FF:FC:00:00)
  • IP_ADDR: ドット付き 10 進形式の IP アドレス (10.1.2.3 など)
  • P_MASK: ドット付き 10 進数形式 (255.255.248.0) または CIDR マスク (0-32) の IP アドレスマスク
  • IPV6_ADDR: 数値形式の IPv6 アドレス (例: FFFF::1)
  • IPV6_MASK: 数値形式の IPv6 マスク (FFFF:FFFF:FC00::) または CIDR マスク (0-128)
  • STRING: 文字列
  • BOOLEAN - 'true'、'yes'、'1'、または 'false'、'no'、'0'
  • IPSETFLAGS: ipset の送信元フラグおよび宛先フラグで、パケットヘッダーの送信元部分または宛先部分から機能を選択する最大 6 つの 'src' 要素または 'dst' 要素 (例: src、src、dst) で記述されます。ここで提供する 'selectors' の数は、参照される ipset のタイプによって異なります。
IP_MASK 型または IPV6_MASK 型の属性を除くすべての属性は、value no の match 属性を使用して否定できます。複数の否定属性をまとめてグループ化できます。以下の XML フラグメントは、抽象属性を使用したこのような例を示しています。
[...]
  <rule action='drop' direction='in'>
    <protocol match='no' attribute1='value1' attribute2='value2'/>
    <protocol attribute3='value3'/>
  </rule>
[...]
ルールの動作は、ルールを評価するとともに、指定のプロトコル属性の境界内で論理的に調べます。したがって、1 つの属性の値が、ルールで指定された値と一致しない場合は、評価プロセス中にルール全体がスキップされます。したがって、上記の例では、protocol プロパティーのattribute1value1 と protocol プロパティーのattribute2value2 と一致せず、protocol プロパティーのattribute3value3 と一致する場合にのみ、着信トラフィックが破棄されます。

17.14.10.1. MAC(イーサネット)

プロトコル ID: mac
このタイプのルールは、root チェーンに置く必要があります。

表17.3 MAC プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信元の MAC アドレスに適用されるマスク
dstmacaddr MAC_ADDR 宛先の MAC アドレス
dstmacmask MAC_MASK 宛先の MAC アドレスに適用されるマスク
protocolid UINT16 (0x600-0xffff), STRING レイヤー 3 プロトコル ID。有効な文字列は、[arp, rarp, ipv4, ipv6] などです。
comment STRING 最大 256 文字のテキスト文字列
このフィルターは以下のように記述できます。
[...]
<mac match='no' srcmacaddr='$MAC'/>
[...]

17.14.10.2. VLAN (802.1Q)

プロトコル ID: vlan
このタイプのルールは、root チェーンまたは vlan チェーンに置く必要があります。

表17.4 VLAN プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信元の MAC アドレスに適用されるマスク
dstmacaddr MAC_ADDR 宛先の MAC アドレス
dstmacmask MAC_MASK 宛先の MAC アドレスに適用されるマスク
vlan-id UINT16 (0x0-0xfff, 0 - 4095) VLAN ID
encap-protocol UINT16 (0x03c-0xfff), String カプセル化レイヤー 3 プロトコル ID で、有効な文字列は arp、ipv4、ipv6 です。
comment STRING 最大 256 文字のテキスト文字列

17.14.10.3. STP (スパニングツリープロトコル)

プロトコル ID: stp
このタイプのルールは、root チェーンまたは stp チェーンのいずれかに置く必要があります。

表17.5 STP プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信元の MAC アドレスに適用されるマスク
type UINT8 BPDU (Bridge Protocol Data Unit) のタイプ
flags UINT8 BPDU flagdstmacmask
root-priority UINT16 root 優先度の範囲の開始
root-priority-hi UINT16 (0x0-0xfff, 0 - 4095) root 優先度の範囲の終了
root-address MAC _ADDRESS root の MAC アドレス
root-address-mask MAC _MASK root の MAC アドレスマスク
roor-cost UINT32 root パスコスト (範囲開始)
root-cost-hi UINT32 root パスコスト範囲の終了
sender-priority-hi UINT16 送信者優先度の範囲の終了
sender-address MAC_ADDRESS BPDU 送信側 MAC アドレス
sender-address-mask MAC_MASK BPDU 送信側 MAC アドレスマスク
port UINT16 ポート識別子 (範囲開始)
port_hi UINT16 ポート識別子の範囲の終了
msg-age UINT16 メッセージエージタイマー (範囲開始)
msg-age-hi UINT16 メッセージエージタイマーの範囲の終了
max-age-hi UINT16 最大エージタイマーの範囲の終了
hello-time UINT16 Hello time タイマー (範囲開始)
hello-time-hi UINT16 Hello time タイマーの範囲の終了
forward-delay UINT16 転送遅延 (範囲開始)
forward-delay-hi UINT16 転送遅延の範囲の終了
comment STRING 最大 256 文字のテキスト文字列

17.14.10.4. ARP/RARP

プロトコル ID: arp または rarp
このタイプのルールは、root チェーンまたは arp/rarp チェーンのいずれかに置く必要があります。

表17.6 ARP プロトコルタイプおよび RARP プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信元の MAC アドレスに適用されるマスク
dstmacaddr MAC_ADDR 宛先の MAC アドレス
dstmacmask MAC_MASK 宛先の MAC アドレスに適用されるマスク
hwtype UINT16 ハードウェアの種類
protocoltype UINT16 プロトコルタイプ
opcode UINT16, STRING Opcode の有効な文字列は、Request、Reply、Request_Reverse、Reply_Reverse、DRARP_Request、DRARP_Reply、DRARP_Error、InARP_Request、ARP_NAK です。
arpsrcmacaddr MAC_ADDR ARP/RARP パケットのソース MAC アドレス
arpdstmacaddr MAC _ADDR ARP/RARP パケットの宛先 MAC アドレス
arpsrcipaddr IP_ADDR ARP/RARP パケットのソース IP アドレス
arpdstipaddr IP_ADDR ARP/RARP パケットの宛先 IP アドレス
gratuitous BOOLEAN Gratuitous ARP パケットを確認するかどうかを示すブール値
comment STRING 最大 256 文字のテキスト文字列

17.14.10.5. IPv4

プロトコル ID: ip
このタイプのルールは、root チェーンまたは ipv4 チェーンに存在する必要があります。

表17.7 IPv4 プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信元の MAC アドレスに適用されるマスク
dstmacaddr MAC_ADDR 宛先の MAC アドレス
dstmacmask MAC_MASK 宛先の MAC アドレスに適用されるマスク
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
protocol UINT8, STRING レイヤー 4 プロトコル識別子。protocol に有効な文字列は、tcp、udp、udplite、esp、ah、icmp、igmp、sctp などです。
srcportstart UINT16 有効なソースポートの範囲の開始。プロトコルが必要です。
srcportend UINT16 有効なソースポートの範囲の終了。プロトコルが必要です。
dstportstart UNIT16 有効な宛先ポートの範囲の開始。プロトコルが必要です。
dstportend UNIT16 有効な宛先ポートの範囲の終了。プロトコルが必要です。
comment STRING 最大 256 文字のテキスト文字列

17.14.10.6. IPv6

プロトコル ID: ipv6
このタイプのルールは、root チェーンまたは ipv6 チェーンに存在する必要があります。

表17.8 IPv6 プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信元の MAC アドレスに適用されるマスク
dstmacaddr MAC_ADDR 宛先の MAC アドレス
dstmacmask MAC_MASK 宛先の MAC アドレスに適用されるマスク
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
protocol UINT8, STRING レイヤー 4 プロトコル識別子。protocol に有効な文字列は、tcp、udp、udplite、esp、ah、icmpv6、sctp などです。
scrportstart UNIT16 有効なソースポートの範囲の開始。プロトコルが必要です。
srcportend UINT16 有効なソースポートの範囲の終了。プロトコルが必要です。
dstportstart UNIT16 有効な宛先ポートの範囲の開始。プロトコルが必要です。
dstportend UNIT16 有効な宛先ポートの範囲の終了。プロトコルが必要です。
comment STRING 最大 256 文字のテキスト文字列

17.14.10.7. TCP/UDP/SCTP

プロトコル ID: tcp、udp、sctp
chain パラメーターはこのタイプのトラフィックでは無視されるため、省略するか、root に設定してください。

表17.9 TCP/UDP/SCTP プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
scripto IP_ADDR ソース IP アドレスの範囲の開始
srcipfrom IP_ADDR ソース IP アドレスの範囲の終了
dstipfrom IP_ADDR 宛先 IP アドレスの範囲の開始
dstipto IP_ADDR 宛先 IP アドレスの範囲の終了
scrportstart UNIT16 有効なソースポートの範囲の開始。プロトコルが必要です。
srcportend UINT16 有効なソースポートの範囲の終了。プロトコルが必要です。
dstportstart UNIT16 有効な宛先ポートの範囲の開始。プロトコルが必要です。
dstportend UNIT16 有効な宛先ポートの範囲の終了。プロトコルが必要です。
comment STRING 最大 256 文字のテキスト文字列
state STRING NEW、ESTABLISHED、RELATED、INVALID、または NONE のコンマ区切りのリスト
flags STRING TCP のみ - mask/flags の形式で、mask と flags の各々が、SYN、ACK、URG、PSH、FIN、RST、NONE、ALL のコンマで区切りリストになります。
ipset STRING libvirt の外部で管理される IPSet の名前
ipsetflags IPSETFLAGS IPSet のフラグ。ipset 属性が必要です。

17.14.10.8. ICMP

プロトコル ID: icmp
注記: chain パラメーターはこのタイプのトラフィックでは無視されるため、省略するか、root に設定してください。

表17.10 ICMP プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信側の MAC アドレスに適用されるマスク
dstmacaddr MAD_ADDR 宛先の MAC アドレス
dstmacmask MAC_MASK 宛先の MAC アドレスに適用されるマスク
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
srcipfrom IP_ADDR ソース IP アドレスの範囲の開始
scripto IP_ADDR ソース IP アドレスの範囲の終了
dstipfrom IP_ADDR 宛先 IP アドレスの範囲の開始
dstipto IP_ADDR 宛先 IP アドレスの範囲の終了
type UNIT16 ICMP のタイプ
code UNIT16 ICMP コード
comment STRING 最大 256 文字のテキスト文字列
state STRING NEW、ESTABLISHED、RELATED、INVALID、または NONE のコンマ区切りのリスト
ipset STRING libvirt の外部で管理される IPSet の名前
ipsetflags IPSETFLAGS IPSet のフラグ。ipset 属性が必要です。

17.14.10.9. IGMP、ESP、AH、UDPLITE、'ALL'

プロトコル ID - igmp、esp、ah、udplite、all
chain パラメーターはこのタイプのトラフィックでは無視されるため、省略するか、root に設定してください。

表17.11 IGMP、ESP、AH、UDPLITE、'ALL'

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcmacmask MAC_MASK 送信側の MAC アドレスに適用されるマスク
dstmacaddr MAD_ADDR 宛先の MAC アドレス
dstmacmask MAC_MASK 宛先の MAC アドレスに適用されるマスク
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
srcipfrom IP_ADDR ソース IP アドレスの範囲の開始
scripto IP_ADDR ソース IP アドレスの範囲の終了
dstipfrom IP_ADDR 宛先 IP アドレスの範囲の開始
dstipto IP_ADDR 宛先 IP アドレスの範囲の終了
comment STRING 最大 256 文字のテキスト文字列
state STRING NEW、ESTABLISHED、RELATED、INVALID、または NONE のコンマ区切りのリスト
ipset STRING libvirt の外部で管理される IPSet の名前
ipsetflags IPSETFLAGS IPSet のフラグ。ipset 属性が必要です。

17.14.10.10. IPV6 経由の TCP/UDP/SCTP

プロトコル ID: tcp-ipv6、udp-ipv6、sctp-ipv6
chain パラメーターはこのタイプのトラフィックでは無視されるため、省略するか、root に設定してください。

表17.12 IPv6 のプロトコルタイプ経由の TCP、UDP、SCTP

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
srcipfrom IP_ADDR ソース IP アドレスの範囲の開始
scripto IP_ADDR ソース IP アドレスの範囲の終了
dstipfrom IP_ADDR 宛先 IP アドレスの範囲の開始
dstipto IP_ADDR 宛先 IP アドレスの範囲の終了
srcportstart UINT16 有効なソースポートの範囲の開始
srcportend UINT16 有効なソースポートの範囲の終了
dstportstart UINT16 有効な宛先ポートの範囲の開始
dstportend UINT16 有効な宛先ポートの範囲の終了
comment STRING 最大 256 文字のテキスト文字列
state STRING NEW、ESTABLISHED、RELATED、INVALID、または NONE のコンマ区切りのリスト
ipset STRING libvirt の外部で管理される IPSet の名前
ipsetflags IPSETFLAGS IPSet のフラグ。ipset 属性が必要です。

17.14.10.11. ICMPv6

プロトコル ID: icmpv6
chain パラメーターはこのタイプのトラフィックでは無視されるため、省略するか、root に設定してください。

表17.13 ICMPv6 プロトコルタイプ

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
srcipfrom IP_ADDR ソース IP アドレスの範囲の開始
scripto IP_ADDR ソース IP アドレスの範囲の終了
dstipfrom IP_ADDR 宛先 IP アドレスの範囲の開始
dstipto IP_ADDR 宛先 IP アドレスの範囲の終了
type UINT16 ICMPv6 のタイプ
code UINT16 ICMPv6 コード
comment STRING 最大 256 文字のテキスト文字列
state STRING NEW、ESTABLISHED、RELATED、INVALID、または NONE のコンマ区切りのリスト
ipset STRING libvirt の外部で管理される IPSet の名前
ipsetflags IPSETFLAGS IPSet のフラグ。ipset 属性が必要です。

17.14.10.12. IPv6 経由の IGMP, ESP, AH, UDPLITE, 'ALL'

プロトコル ID - igmp-ipv6、esp-ipv6、ah-ipv6、udplite-ipv6、all-ipv6
chain パラメーターはこのタイプのトラフィックでは無視されるため、省略するか、root に設定してください。

表17.14 IPv6 プロトコルタイプ経由の IGMP、ESP、AH、UDPLITE、'ALL'

属性名 データタイプ 定義
srcmacaddr MAC_ADDR 送信側の MAC アドレス
srcipaddr IP_ADDR ソース IP アドレス
srcipmask IP_MASK マスクがソース IP アドレスに適用されました。
dstipaddr IP_ADDR 宛先 IP アドレス
dstipmask IP_MASK 宛先 IP アドレスに適用されるマスク
srcipfrom IP_ADDR ソース IP アドレスの範囲の開始
scripto IP_ADDR ソース IP アドレスの範囲の終了
dstipfrom IP_ADDR 宛先 IP アドレスの範囲の開始
dstipto IP_ADDR 宛先 IP アドレスの範囲の終了
comment STRING 最大 256 文字のテキスト文字列
state STRING NEW、ESTABLISHED、RELATED、INVALID、または NONE のコンマ区切りのリスト
ipset STRING libvirt の外部で管理される IPSet の名前
ipsetflags IPSETFLAGS IPSet のフラグ。ipset 属性が必要です。

17.14.11. 高度なフィルター設定のトピック

次のセクションでは、高度なフィルター設定のトピックについて説明します。

17.14.11.1. 接続追跡

ネットワークフィルターサブシステム (Linux の場合) は、IP テーブルの接続追跡サポートを利用します。これにより、ネットワークトラフィックの方向を強制 (状態の一致) したり、ゲスト仮想マシンへの同時接続数をカウントして制限したりできます。たとえば、ゲスト仮想マシンで TCP ポート 8080 がサーバーとして開いていると、クライアントはポート 8080 でゲスト仮想マシンに接続できます。接続の追跡と方向の強制により、ゲスト仮想マシンが (TCP クライアント) ポート 8080 からホスト物理マシンへの接続を開始して、リモートホスト物理マシンに戻らないようにします。さらに重要なのは、トラッキングにより、リモートの攻撃者がゲスト仮想マシンへの接続を確立できないようにすることです。たとえば、ゲスト仮想マシン内のユーザーが攻撃者サイトのポート 80 への接続を確立すると、攻撃者は TCP ポート 80 からゲスト仮想マシンへの接続を開始できなくなります。デフォルトでは、接続追跡を有効にした後にトラフィックの方向を強制する接続状態一致が有効になります。

例17.9 TCP ポートへの接続を無効にするなどの XML

以下は、TCP ポート 12345 への着信接続でこの機能が無効になっている XML フラグメントの例を示しています。
   [...]
    <rule direction='in' action='accept' statematch='false'>
      <cp dstportstart='12345'/>
    </rule>
   [...]
これにより、TCP ポート 12345 への着信トラフィックが許可されるようになりましたが、仮想マシン内の (クライアント) TCP ポート 12345 からの開始も有効になります。これは望ましい場合とそうでない場合があります。

17.14.11.2. 接続数の制限

ゲスト仮想マシンが確立できる接続の数を制限するには、特定タイプのトラフィックの接続の制限を設定するルールを提供する必要があります。たとえば、仮想マシンが、一度に 1 つの IP アドレスに対してのみ ping を実行できるようにし、同時に 1 つの ssh 受信接続のみをアクティブにする必要がある場合など。

例17.10 接続に制限を設定する XML サンプルファイル

以下の XML フラグメントを使用して、接続を制限できます。
  [...]
  <rule action='drop' direction='in' priority='400'>
    <tcp connlimit-above='1'/>
  </rule>
  <rule action='accept' direction='in' priority='500'>
    <tcp dstportstart='22'/>
  </rule>
  <rule action='drop' direction='out' priority='400'>
    <icmp connlimit-above='1'/>
  </rule>
  <rule action='accept' direction='out' priority='500'>
    <icmp/>
  </rule>
  <rule action='accept' direction='out' priority='500'>
    <udp dstportstart='53'/>
  </rule>
  <rule action='drop' direction='inout' priority='1000'>
    <all/>
  </rule>
  [...]
注記
制限ルールは、トラフィックを許可するルールに先立ち、XML に記載する必要があります。例17.10「接続に制限を設定する XML サンプルファイル」 の XML ファイルに従い、ポート 22 に送信された DNS トラフィックがゲスト仮想マシンから送信されることを許可するための追加ルールが追加され、ssh デーモンによる DNS ルックアップの失敗に関連する理由で ssh セッションが確立されないことを回避します。このルールを適用しないと、接続しようとしているときに ssh クライアントが予想外にハングする可能性があります。トラフィックの追跡に関連するタイムアウトを処理する際には、注意が必要です。ゲスト仮想マシン内でユーザーが終了した ICMP ping は、ホスト物理マシンの接続追跡システムでタイムアウトが長くなる可能性があるため、別の ICMP ping を実行できません。
最善の解決策は、# echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout で、ホスト物理マシンの sysfs のタイムアウトを調整することです。このコマンドは、ICMP 接続トラッキングのタイムアウトを 3 秒に設定します。これは、ある ping が終了すると、別の ping が 3 秒後に開始できることになります。
なんらかの理由でゲスト仮想マシンが TCP 接続を適切に閉じていないと、特にホストの物理マシンで TCP タイムアウト値が大量に設定されている場合に、接続が長期間開かれたままになります。また、アイドル状態の接続では、パケットが交換されると再度アクティブにできる接続追跡システムのタイムアウトが発生する場合があります。
ただし、この制限を低く設定しすぎると、新しく開始した接続により、アイドル状態の接続が強制的に TCP バックオフになる場合があります。したがって、接続の制限は、新しい TCP 接続の変動によって、アイドル状態の接続に関連して奇妙なトラフィック動作が発生しないように、かなり高く設定する必要があります。

17.14.11.3. コマンドラインツール

virsh は、ネットワークフィルターのライフサイクルサポートにより拡張されました。ネットワークフィルターサブシステムに関連するすべてのコマンドは、nwfilter という接頭辞で始まります。以下のコマンドを使用できます。
  • nwfilter-list - UUID と、すべてのネットワークフィルターの名前のリストを表示します。
  • nwfilter-define - 新しいネットワークフィルターを定義するか、既存のフィルターを更新します (名前を指定する必要があります)。
  • nwfilter-undefine - 指定したネットワークフィルターを削除します (名前を指定する必要があります)。現在使用しているネットワークフィルターを削除しないでください。
  • nwfilter-dumpxml - 指定したネットワークフィルターを表示します (名前を指定する必要があります)。
  • nwfilter-edit - 指定したネットワークフィルターを編集します (名前を指定する必要があります)。

17.14.11.4. 既存のネットワークフィルター

以下は、libvirt で自動的にインストールされるネットワークフィルターの例です。

表17.15 ICMPv6 プロトコルタイプ

プロトコル名 説明
allow-arp ゲスト仮想マシンへのすべての送受信アドレス解決プロトコル (ARP) トラフィックを許可します。
no-arp-spoofingno-arp-mac-spoofingand no-arp-ip-spoofing これらのフィルターは、ゲスト仮想マシンが ARP トラフィックをスプーフィングするのを防ぎます。また、ARP の要求メッセージおよび応答メッセージのみを許可し、これらのパケットには次の内容が含まれることを強制します。
  • no-arp-spoofing - ゲストの MAC アドレスおよび IP アドレス
  • no-arp-mac-spoofing - ゲストの MAC アドレス
  • no-arp-ip-spoofing - ゲストの IP アドレス
low-dhcp ゲスト仮想マシンが DHCP 経由で (任意の DHCP サーバーから) IP アドレスを要求できるようにします。
low-dhcp-server ゲスト仮想マシンが、指定した DHCP サーバーから IP アドレスを要求できるようにします。DHCP サーバーの、ドットで区切られた 10 進数の IP アドレスは、このフィルターを参照する必要があります。変数の名前は DHCPSERVER でなければなりません。
low-ipv4 仮想マシンへのすべての送受信 IPv4 トラフィックを許可します。
low-incoming-ipv4 仮想マシンへの着信 IPv4 トラフィックのみを受け入れます。このフィルターは clean-traffic フィルターの一部です。
no-ip-spoofing ゲスト仮想マシンが、パケット内の送信元 IP アドレスとは異なる IP パケットを送信しないようにします。このフィルターは clean-traffic フィルターの一部です。
no-ip-multicast ゲスト仮想マシンが IP マルチキャストパケットを送信しないようにします。
no-mac-broadcast 指定された MAC アドレスへの送信 IPv4 トラフィックを防ぎます。このフィルターは clean-traffic フィルターの一部です。
no-other-l2-traffic ネットワークが使用するその他のフィルターで指定したトラフィックを除き、すべてのレイヤー 2 ネットワークトラフィックを防ぎます。このフィルターは clean-traffic フィルターの一部です。
no-other-rarp-trafficqemu-announce-selfqemu-announce-self-rarp このフィルターは、QEMU のセルフアナウンスの RARP (Reverse Address Resolution Protocol) パケットを許可しますが、その他の RARP トラフィックは阻止します。これらのすべては、clean-traffic フィルターにも含まれます。
clean-traffic MAC、IP、および ARP のスプーフィングを防ぎます。このフィルターは、他のいくつかのフィルターをビルディングブロックとして参照します。
これらのフィルターはビルディングブロックにすぎず、便利なネットワークトラフィックフィルターを提供するために、他のフィルターとの組み合わせが必要です。上記で最も使用されているのが clean-traffic フィルターです。たとえば、このフィルター自体を no-ip-multicast フィルターと組み合わせて、仮想マシンが IP マルチキャストトラフィックを送信しないようにし、パケットスプーフィングを防ぐことができます。

17.14.11.5. 独自のフィルターの作成

libvirt はネットワークフィルターの例をいくつか提供しているだけなので、独自のフィルターを作成することを検討してください。これを計画する際に、ネットワークフィルターサブシステムと、それが内部でどのように機能するかについて知っておく必要があります。フィルターをかけるプロトコルを必ず熟知して理解しておく必要があります。それにより、通過するトラフィック以上のトラフィックがなくなり、実際に許可するトラフィックが通過するようになります。
ネットワークフィルターサブシステムは、現在 Linux ホストの物理マシンでのみ利用でき、QEMU および KVM タイプの仮想マシンでのみ機能します。Linux では、ebtable、iptables、および ip6tables に対応し、その機能を利用します。「サポートされているプロトコル」 に記載されているリストを考慮し、ebtable を使用して以下のプロトコルを実装できます。
  • mac
  • stp (スパニングツリープロトコル)
  • vlan (802.1Q)
  • arp, rarp
  • ipv4
  • ipv6
IPv4 で実行するプロトコルはすべて iptables を使用してサポートされ、IPv6 で実行するプロトコルは ip6tables を使用して実装されます。
Linux ホストの物理マシンを使用して、libvirt のネットワークフィルタリングサブシステムが作成したすべてのトラフィックフィルタリングルールは、最初に ebtables が実装したフィルタリングサポートを通過し、その後で iptables フィルターまたは ip6tables フィルターを通過します。フィルターツリーに、mac、stp、vlan arp、rarp、ipv4、または ipv6 などのプロトコルを持つルールがある場合は、リスト表示されている ebtable ルールと値が自動的に使用されます。
同じプロトコルに複数のチェーンを作成できます。チェーンの名前は、以前に列挙されたプロトコルのいずれかの接頭辞を持つ必要があります。ARP トラフィックを処理するための追加のチェーンを作成する場合は、たとえば、名前が arp-test のチェーンを指定できます。
たとえば、ip プロトコルフィルターを使用し、受け入れる UDP パケットのソース、宛先 IP、およびポートの属性を指定して、送信元および宛先のポートで UDP トラフィックでフィルタリングできます。これにより、ebtables を使用した UDP トラフィックの早期フィルタリングが可能になります。ただし、UDP パケットなどの IP または IPv6 パケットが ebtables レイヤーを通過し、iptables ルールまたは ip6tables ルールをインスタンス化するフィルターツリーに少なくとも 1 つのルールがある場合、UDP パケットの通過を許可するルールもこれらのフィルターレイヤーに指定する必要があります。これは、適切な udp トラフィックフィルターノードまたは udp-ipv6 トラフィックフィルターノードを含むルールで実行できます。

例17.11 カスタムフィルターの作成

以下の要件のリストを満たすためにフィルターが必要であるとします。
  • 仮想マシンのインターフェイスによる MAC、IP、および ARP のスプーフィングの阻止
  • 仮想マシンのインターフェイスの TCP ポート 22 および 80 のみを開く
  • 仮想マシンがインターフェイスから ping トラフィックを送信できるようにしますが、インターフェイスで仮想マシンの ping を行わないようにします。
  • 仮想マシンが DNS ルックアップ (ポート 53 への UDP) を実行できるようにします。
スプーフィングを防ぐための要件は、すでに存在する clean-traffic ネットワークフィルターにより満たされています。そのため、これを行う方法は、カスタムフィルターから参照することです。
TCP ポート 22 および 80 のトラフィックを有効にするには、このタイプのトラフィックを有効にするために 2 つのルールが追加されました。ゲスト仮想マシンが ping トラフィックを送信できるようにするため、ICMP トラフィックにルールが追加されました。簡単にするために、一般的な ICMP トラフィックはゲスト仮想マシンから開始することが許可され、ICMP エコー要求および応答メッセージには指定されません。その他のトラフィックはすべて、ゲスト仮想マシンに到達しないか、ゲスト仮想マシンにより開始されます。これを行うには、その他のトラフィックをすべて破棄するルールが追加されます。ゲスト仮想マシンが test と呼ばれ、フィルターを関連付けるインターフェイスが eth0 と呼ばれていると、フィルターの名前は test-eth0 となります。
この考慮事項の結果、ネットワークフィルターの XML が次のようになります。
<filter name='test-eth0'>
  <!- - This rule references the clean traffic filter to prevent MAC, IP and ARP spoofing. By not providing an IP address parameter, libvirt will detect the IP address the guest virtual machine is using. - ->
  <filterref filter='clean-traffic'/>

  <!- - This rule enables TCP ports 22 (ssh) and 80 (http) to be reachable - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='22'/>
  </rule>

  <rule action='accept' direction='in'>
    <tcp dstportstart='80'/>
  </rule>

  <!- - This rule enables general ICMP traffic to be initiated by the guest virtual machine including ping traffic - ->
  <rule action='accept' direction='out'>
    <icmp/>
  </rule>>

  <!- - This rule enables outgoing DNS lookups using UDP - ->
  <rule action='accept' direction='out'>
    <udp dstportstart='53'/>
  </rule>

  <!- - This rule drops all other traffic - ->
  <rule action='drop' direction='inout'>
    <all/>
  </rule>

</filter>

17.14.11.6. サンプルのカスタムフィルター

上記の XML のルールのいずれかに、送信元アドレスまたは宛先アドレスとしてゲスト仮想マシンの IP アドレスが含まれていますが、トラフィックのフィルタリングは正しく機能します。理由は、ルールの評価はインターフェイスごとに内部的に行われるのに対し、ルールは、送信元または宛先の IP アドレスではなく、パケットを送信または受信する (タップ) インターフェイスに基づいて追加で評価されるためです。

例17.12 ネットワークインターフェイスの説明のサンプル XML

テストゲスト仮想マシンのドメイン XML 内にある可能性のあるネットワークインターフェイスの説明の XML フラグメントは、以下のようになります。
   [...]
    <interface type='bridge'>
      <source bridge='mybridge'/>
      <filterref filter='test-eth0'/>
    </interface>
   [...]
ICMP トラフィックをより厳格に制御し、ゲスト仮想マシンから送信できるのは ICMP エコー要求のみで、ゲスト仮想マシンが受信できるのは ICMP エコー応答のみとなるようにするため、上記の ICMP ルールを、以下の 2 つのルールに置き換えることができます。
  <!- - enable outgoing ICMP echo requests- ->
  <rule action='accept' direction='out'>
    <icmp type='8'/>
  </rule>
  <!- - enable incoming ICMP echo replies- ->
  <rule action='accept' direction='in'>
    <icmp type='0'/>
  </rule>

例17.13 2 番目の例のカスタムフィルター

この例は、上記の例と同様のフィルターを作成する方法を示していますが、ゲスト仮想マシン内にある ftp サーバーを使用して要件のリストを拡張しています。このフィルターの要件は以下のとおりです。
  • ゲスト仮想マシンのインターフェイスの MAC、IP、および ARP スプーフィングを防ぎます。
  • ゲスト仮想マシンのインターフェイスで TCP ポート 22 および 80 のみを開きます。
  • ゲスト仮想マシンがインターフェイスから ping トラフィックを送信できるようにしますが、インターフェイスでゲスト仮想マシンへの ping は許可しません。
  • ゲスト仮想マシンが DNS ルックアップ (ポート 53 への UDP) を実行できるようにします。
  • ftp サーバーを有効にし (アクティブモード)、ゲスト仮想マシン内で実行できるようにします。
FTP サーバーをゲスト仮想マシン内で実行できるようにするという追加の要件は、ポート 21 が FTP 制御トラフィックに到達できるようにするという要件と、ゲスト仮想マシンが、ゲスト仮想マシンの TCP ポート 20 からの発信 TCP 接続を FTP クライアント (FTP アクティブモード) に確立できるようにする要件にマッピングします。このフィルターを作成する方法はいくつかあります。この例では、2 つの解決策を説明します。
最初のソリューションは、TCP プロトコルの state 属性を使用します。この属性は、Linux ホストの物理マシンの接続追跡フレームワークにフックを提供します。ゲスト仮想マシンが開始する FTP データ接続 (FTP アクティブモード) の場合は、RELATED 状態を使用して、ゲスト仮想マシンが開始する FTP データ接続が既存の FTP 制御接続の結果である (または関連している) ことを検出できるようにします。これにより、ファイアウォールを介して、パケットを渡すことができます。ただし、RELATED 状態は、FTP データパスの送信 TCP 接続の最初のパケットに対してのみ有効です。その後、この状態は ESTABLISHED になり、着信方向および発信方向にも同様に適用されます。これはすべて、ゲスト仮想マシンの TCP ポート 20 から発信される FTP データトラフィックに関連します。これにより、以下のソリューションが得られます。
<filter name='test-eth0'>
  <!- - This filter (eth0) references the clean traffic filter to prevent MAC, IP, and ARP spoofing. By not providing an IP address parameter, libvirt will detect the IP address the guest virtual machine is using. - ->
  <filterref filter='clean-traffic'/>

  <!- - This rule enables TCP port 21 (FTP-control) to be reachable - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='21'/>
  </rule>

  <!- - This rule enables TCP port 20 for guest virtual machine-initiated FTP data connection related to an existing FTP control connection - ->
  <rule action='accept' direction='out'>
    <tcp srcportstart='20' state='RELATED,ESTABLISHED'/>
  </rule>

  <!- - This rule accepts all packets from a client on the FTP data connection - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='20' state='ESTABLISHED'/>
  </rule>

  <!- - This rule enables TCP port 22 (SSH) to be reachable - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='22'/>
  </rule>

  <!- -This rule enables TCP port 80 (HTTP) to be reachable - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='80'/>
  </rule>

  <!- - This rule enables general ICMP traffic to be initiated by the guest virtual machine, including ping traffic - ->
  <rule action='accept' direction='out'>
    <icmp/>
  </rule>

  <!- - This rule enables outgoing DNS lookups using UDP - ->
  <rule action='accept' direction='out'>
    <udp dstportstart='53'/>
  </rule>

  <!- - This rule drops all other traffic - ->
  <rule action='drop' direction='inout'>
    <all/>
  </rule>

</filter>
RELATED 状態を使用してフィルターを試す前に、適切な接続追跡モジュールがホスト物理マシンのカーネルに読み込まれていることを確認する必要があります。カーネルのバージョンによっては、ゲスト仮想マシンと FTP 接続を確立する前に、次の 2 つのコマンドのいずれかを実行する必要があります。
  • modprobe nf_conntrack_ftp (利用可能な場合)
  • modprobe ip_conntrack_ftp (上記が利用可能でない場合)
FTP 以外のプロトコルを RELATED 状態と併用する場合は、対応するモジュールを読み込む必要があります。モジュールは、ftp、tftp、irc、sip、sctp、および amanda のプロトコルで利用できます。
2 番目のソリューションでは、以前のソリューションよりも多くの接続の状態フラグを使用します。このソリューションでは、トラフィックフローの最初のパケットが検出されると、接続の NEW 状態が有効であるという事実を利用します。その後、フローの最初のパケットが受け入れられると、フローは接続になるため、ESTABLISHED 状態になります。したがって、ESTABLISHED 接続のパケットをゲスト仮想マシンに到達できるようにしたり、ゲスト仮想マシンによって送信されるように、一般的なルールを記述することができます。これは、NEW 状態で識別される最も最初のパケットに特定のルールを書き込み、データが許容可能なポートを指定します。明示的に許可されていないポート向けのパケットはすべて破棄されるため、ESTABLISHED 状態に到達しません。そのポートから送信される後続のパケットもすべて破棄されます。
<filter name='test-eth0'>
  <!- - This filter references the clean traffic filter to prevent MAC, IP and ARP spoofing. By not providing and IP address parameter, libvirt will detect the IP address the VM is using. - ->
  <filterref filter='clean-traffic'/>

  <!- - This rule allows the packets of all previously accepted connections to reach the guest virtual machine - ->
  <rule action='accept' direction='in'>
    <all state='ESTABLISHED'/>
  </rule>

  <!- - This rule allows the packets of all previously accepted and related connections be sent from the guest virtual machine - ->
  <rule action='accept' direction='out'>
    <all state='ESTABLISHED,RELATED'/>
  </rule>

  <!- - This rule enables traffic towards port 21 (FTP) and port 22 (SSH)- ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='21' dstportend='22' state='NEW'/>
  </rule>

  <!- - This rule enables traffic towards port 80 (HTTP) - ->
  <rule action='accept' direction='in'>
    <tcp dstportstart='80' state='NEW'/>
  </rule>

  <!- - This rule enables general ICMP traffic to be initiated by the guest virtual machine, including ping traffic - ->
  <rule action='accept' direction='out'>
    <icmp state='NEW'/>
  </rule>

  <!- - This rule enables outgoing DNS lookups using UDP - ->
  <rule action='accept' direction='out'>
    <udp dstportstart='53' state='NEW'/>
  </rule>

  <!- - This rule drops all other traffic - ->
  <rule action='drop' direction='inout'>
    <all/>
  </rule>

</filter>

17.14.12. 制限

以下は、ネットワークフィルターサブシステムにおける現在知られている制限のリストです。
  • 仮想マシンの移行は、ゲスト仮想マシンのトップレベルフィルターが参照するフィルターツリー全体が、ターゲットホストの物理マシンで利用可能な場合にのみ対応します。たとえば、ネットワークフィルターの clean-traffic は、すべての libvirt インストールで利用可能である必要があり、このフィルターを参照するゲスト仮想マシンの移行を有効にする必要があります。バージョンの互換性が問題ではないことを確認するには、パッケージを定期的に更新して、最新バージョンの libvirt を使用していることを確認してください。
  • インターフェイスに関連付けられたネットワークトラフィックフィルターを失わないように、バージョン 0.8.1 以降の libvirt インストール間で移行を行う必要があります。
  • ゲスト仮想マシンが VLAN (802.1Q) パケットを送信しても、プロトコル ID の arp、rarp、ipv4、ipv6 のルールでフィルターをかけることはできません。これらは、プロトコル ID、MAC、および VLAN でのみフィルターにかけることができます。そのため、フィルターの clean-traffic の例 例17.1「ネットワークフィルタリングの例」 は予想通りに機能しません。