VirtualBox でホストからゲストにファイアウォールをかける

スポンサーリンク

VirtualBox で,ゲスト (仮想マシン) をホストと同じネットワークに参加させたい場合,ブリッジ接続を用いる。その際,セキュリティ上の理由から,ホストからゲストに対してファイアウォールを設けたいことがある。しかし,ブリッジ接続では,ゲストは下図のようにホストと並列につながっている状態になるため,そのままではゲストの通信を制限することができない。

これを解決するために,Ubuntu 10.10 において仮想ブリッジと仮想 NIC を用いることにより,VirtualBox のホストからゲストに対してファイアウォールをかける方法を見つけたのでメモしておく。

というか Xen は最初からこのような構成になっているようだ。

スポンサーリンク

準備

まず,仮想ブリッジと仮想 NIC を使用するために,bridge-utils と uml-utilities をインストールする。

$ sudo apt-get install -y bridge-utils uml-utilities

モジュールをロードする。

$ sudo modprobe bridge tun

ホストを再起動した際,これらのモジュールが自動的にロードされるように,設定ファイル (/etc/modules) に以下を追記する。

$ sudo vi /etc/modules
  :
bridge
tun

仮想 NIC と仮想ブリッジの設定

仮想 NIC (tap0) と仮想ブリッジ (br0) を作成し,eth0 と tap0 を接続する。実際には,あとで起動時に自動で実行するように設定するので,この手順は必須ではない (実行しても,再起動したら元に戻る)。

$ sudo brctl addif br0 eth0  # eth0 と br0 を接続
$ sudo tunctl -t tap0        # tap0 という名前の仮想 NIC を作成
$ sudo brctl addif br0 tap0  # tap0 と br0 を接続

仮想ブリッジの状態を確認する。

$ sudo brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.************       no              eth0
                                                        tap0

ネットワークの設定を編集する。起動時に自動で tap0 を作成するようにしている。

$ sudo vi /etc/network/interfaces
auto lo
iface lo inet loopback

auto br0
iface br0 inet static
    address <ホストの IP アドレス>
    netmask <サブネットマスク>
    gateway <デフォルトゲートウェイ>
    pre-up tunctl -t tap0 # tap0 を作成
    pre-up ifconfig tap0 0.0.0.0 promisc up  # tap0 を設定
    pre-up ifconfig eth0 0.0.0.0 promisc up  # eth0 を設定
    bridge_ports eth0 tap0  # eth0 と tap0 を接続

iface eth0 inet manual

ネットワーク設定を再読込する。

$ sudo /etc/init.d/networking restart

VirtualBox を起動し,ゲストのネットワーク設定で「名前」を「tap0」に変更する。

以上により,ゲストは下図のような状態で接続されるようになった。

ファイアウォールの設定

iptables を用いて,ゲストにファイアウォールをかけるために,次のようなシェルスクリプトを作成して実行する。

#!/bin/sh

# ルールを初期化
iptables -F
iptables -X

# br0 ⇔ tap0 間の通信をデフォルトで遮断
iptables -P FORWARD DROP

# 新しいチェインを作成
iptables -N vboxin
iptables -N vboxout
iptables -F vboxin
iptables -F vboxout

# 作成したチェインを通るように
iptables -A FORWARD -m physdev --physdev-out tap0 -j vboxin
iptables -A FORWARD -m physdev --physdev-in  tap0 -j vboxout

# 入力: ゲストの要求に対する外部からの応答は許可
iptables -A vboxin -m state --state ESTABLISHED,RELATED -j ACCEPT

# 入力: well-known ポート以外は許可
iptables -A vboxin -p tcp --dport 1024:65535 -j ACCEPT
iptables -A vboxin -p udp --dport 1024:65535 -j ACCEPT

# 入力: dhcp は許可
iptables -A vboxin -p udp --dport 67:68 --sport 67:68 -j ACCEPT

# 入力: HTTP, HTTPS, SMTPS, IMAPS, POP3S は許可
iptables -A vboxin -p tcp -m multiport --dports 80,443,465,993,995 -j ACCEPT

# 出力: すべて許可
iptables -A vboxout -j ACCEPT

# 変更を保存
iptables-save > /etc/iptables.up.rules

以上により,ホストからゲストの通信を制限できるようになった。

それぞれのゲストに対して個別に制限を設けたい場合は,仮想 NIC を tap1, tap2, … のように複数作成し,ゲスト毎に割り当てる必要がある。

参考ページ

コメント

タイトルとURLをコピーしました