Linux Install Memo

サーバー管理者によるLinux関連ソフトのインストールメモ

Home » □KVMでゲストOSのネットワーク分離(隔離)化

□KVMでゲストOSのネットワーク分離(隔離)化

http://libvirt.org/formatnwfilter.html

ホストもゲストも自分で管理しているのならいいけれど、ゲストOSを人に
使わせるとなった場合には、ヒューマンエラーを含めて変なIPアドレスを
設定されかねないので、元々のIP以外のパケットの場合はゲストOSからの
通信を制限したいよね、と言うことです。

まー簡単にできるだろうと思ったら、確かに「IPv4が1つ」だけにならOK
なのだけど、IPv4アドレスを複数とか、IPv6も、となるとちと面倒です。

●その一、IPv4アドレス一つだけの場合。

IPv4だけなら、ゲストOSのXML設定ファイルのインターフェースに、通過
させたいIPを

<filterref filter=’clean-traffic’>
  <parameter name=’IP’ value=’192.168.0.200’/>
</filterref>

のように書くだけ。

ちなみにlibvirtのバージョンが0.9.8以上なら、という条件がつくが、
複数IPを通過させたい場合には

<filterref filter=’clean-traffic’>
  <parameter name=’IP’ value=’192.168.0.202’/>
  <parameter name=’IP’ value=’192.168.0.203’/>
</filterref>

とするだけでもOKらしい。(CentOS6.2は0.9.4、2012.06現在)

あとはゲストOSのXML設定ファイルのインターフェースのところに

>     <interface type=’bridge’>
>       <mac address=’52:54:00:30:fc:2d’/>
>       <source bridge=’br0’/>
>       <model type=’virtio’/>
>       <address type=’pci’ domain=’0x0000′ bus=’0x00′ slot=’0x03′ function=’0x0’/>
>       <filterref filter=’clean-traffic’>
>         <parameter name=’IP’ value=’192.168.0.200’/>
>       </filterref>
>     </interface>

という感じで書けばOK。

●その二、IPv4をセグメントでとかIPv6も、とかの場合。

IPv6やセグメント指定をする場合には、ルールを別途作らないといけない。
例えばIPv4もIPv6も、と言う場合には、まぁIPv4の設定を拡張してあげれば
よい。

cat > /etc/libvirt/nwfilter/allow-incoming-ipv6.xml

<filter name=’allow-incoming-ipv6′ chain=’ipv6′>
  <rule direction=’in’ action=’accept’/>
</filter>

cat > /etc/libvirt/nwfilter/no-ipv6-spoofing.xml

<filter name=’no-ipv6-spoofing’ chain=’ipv6′>
    <!– drop if srcipaddr is not the IPv6 address of the guest –>
    <rule action=’drop’ direction=’out’>
        <ipv6 match=’no’ srcipaddr=’$IPV6′ />
    </rule>
</filter>

として、IPv6用のフィルタを作って、「clean-traffic」フィルターにこの
二つのフィルターを追記してあげる。

emacs /etc/libvirt/nwfilter/clean-traffic.xml

>    <!– preventing IP spoofing on outgoing, allow all IPv4 in incoming –>
>    <filterref filter=’no-ip-spoofing’/>
>    <filterref filter=’allow-incoming-ipv4’/>
>
>    <!– preventing IP spoofing on outgoing, allow all IPv6 in incoming –>
>    <filterref filter=’no-ipv6-spoofing’/>
>    <filterref filter=’allow-incoming-ipv6’/>
>

あとは、ゲストOSのXML設定ファイルのインターフェースのところに

<filterref filter=’ip-address-filter’>
  <parameter name=’IP’ value=’192.168.0.203’/>
  <parameter name=’IPV6′ value=’fe80::203’/>
</filterref>
のように記述して、ルール定義ファイルを追加したらlibvirtdを再起動
しないといけない。事前にゲストOSは全て止めておいた方がよい。

/etc/init.d/libvirtd restart

とすると再起動してくれる。(autostartしていればゲストOSも連れて起動)

ここで、外部とゲストOSとやり取りできればOK。

意図的にゲストOSのIPアドレスを変えたりして、外部やゲストOS同士でも
通信できないことを確認して、ちゃんとフィルターが効いているか確認を
すること。

※セグメント指定の場合には、参考URLのマニュアル読めばわかるでしょ。
いやー、IPv6もとなるとちょっと苦労した。難しく考えて、あれこれ悩ん
じゃったけど、結局こんな感じで追加してフィルターできるようになった
ので一安心したけど。

でさ、つまるところ、デフォルトではIPv6についてのフィルターってのは
ちゃんとできないんだよね。ネット上にも情報がほとんどない。

rootのchainにIPv6関連を設定するとか言うのもあるけど、うまく動かな
かったんだよなー。みんなどうしているんだろう?

まさか、

性善説に基づいて他人のIPなんて設定しないだろう

 

なんていう運用はしていないよね?世の中のVPS屋さんは。
IPv4については少なくともフィルターしているよねぇ?

と言うことは、この情報は意外と飯の種的な価値があったのかな?

★補足、libvirtd-0.9.10の場合

新しいlibvirtdの場合、MACアドレスとかIPv6とか複数のIPアドレスの
フィルター設定も出来るのでちょっとフィルター設定の中身が変わって
いるので補足します。

IPv6のフィルター設定をしたい場合は以下のようにclean-traffic.xmlに
追加します。(IPv4の下にでも追記)

emacs /etc/libvirt/nwfilter/clean-traffic.xml

>    <!– preventing IP spoofing on outgoing, allow all IPv6 in incoming –>
>    <filterref filter=’no-ipv6-spoofing’/>
>
>    <rule direction=’out’ action=’accept’ priority=’-650′>
>       <mac protocolid=’ipv6’/>
>    </rule>
>
>    <filterref filter=’allow-incoming-ipv6’/>
>

・さらにno-ipv6-spoofing.xmlも修正

emacs /etc/libvirt/nwfilter/no-ipv6-spoofing.xml

<filter name=’no-ip-spoofing’ chain=’ipv6-ip’ priority=’-710′>
  <!– allow UDP sent from 0::0 (DHCP); filter more exact later –>
  <rule action=’return’ direction=’out’ priority=’100′>
    <ip srcipaddr=’0::0′ protocol=’udp’/>
  </rule>

  <!– allow all known IPv6 addresses –>
  <rule direction=’out’ action=’return’ priority=’500′>
    <ip srcipaddr=’$IPV6’/>
  </rule>

  <!– drop everything else –>
  <rule direction=’out’ action=’drop’ priority=’1000’/>
</filter>

と、IPv4のno-ip-spoofing.xmlを参考に修正。
(DHCPの設定についてはよく判ってないので間違っていると思う…笑)

・allow-incoming-ipv6.xmlは変更がありません。

で、上記のように修正したら

    <interface type=’bridge’>
      <filterref filter=’clean-traffic‘>
        <parameter name=’MAC’ value=’00:16:3e:7b:05:e1’/>
        <parameter name=’IP’ value=’192.168.73.201’/>
        <parameter name=’IPV6′ value=’fe80:192:168:73:0:0:0:201’/>
      </filterref>
      <mac address=’00:16:3e:7b:05:e1’/>
      <source bridge=’br0’/>
      <address type=’pci’ domain=’0x0000′ bus=’0x00′ slot=’0x03′ function=’0x0’/>
    </interface>

とか書いてあげると、IPv4もIPv6もMACアドレスでもフィルターできる。

 

Name of author

Name: admin

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です