読者です 読者をやめる 読者になる 読者になる

絶品ゆどうふのタレ

ふと気づいたことを綴るだけのメモ

VirtualBox を利用する際のネットワーク設定の話

virtualbox network tips

VMware ServerがWindows 7上でうまくNATできてくれないので、これを機会にVirtualBoxに乗り換えた。
VirtualBoxはすごくいいねー。簡単だしかなり軽快。これは素敵。


ところで、VirtualBoxを使うときに1つだけちゃんと設定してあげないといけないことがあって、それが何かというとネットワーク周りの設定。*1

これをやったときに、手順的な問題でちょっとだけ間違ったりして(´д`)ホゲェ〜ってなったことがあったので、解説も含めメモっておく。*2
ちなみに、解決方法は簡単。ごたくが長い。想定対象読者はid:wozozo

作りたい構成

仮想マシンをローカルマシン上で使用する場合、大体の人が実現したいネットワークの構成としては、

  • GuestOSは外部ネットワークに対してアクセスできてほしい。
  • GuestOSは基本的に外部ネットワークからは遮断しておきたい。
    • でも、HostOSに限り、外部からアクセスできてほしい。

という構成かな、と勝手に思っていたりする。


で、それを手軽に実現するには、VirtualBoxではNATとHost-Onlyという2つのネットワーク構成を組み合わせて使う、という方法で解決する。
予備知識として、VirtualBoxで扱える仮想化ネットワークの種類が知りたい人は、以下のサイトが分かりやすく図解していてよい。同じ名称でもVMwareとは扱いが違うことがあるので注意。

なお、最後のNAT + Host-Onlyというのは設定項目ではなくテクニックの話。説明するのはこれの件。

(めんどくさい理屈の話をしてるので、ごたくはいいから解決しろ!という人は「解決方法」まで飛ばしちゃって。)


補足として、いろいろな所で「NAT+ポートフォワーディングという方法で解決できる」という話も上がっているが、これはいちいちポートのことを気にしなければならず厄介なので、ウザくてお勧めしない。
正直、ネットワークのレイヤ的にはできるだけ下の方で仮想化/抽象化を済ませておくべきで、レイヤ3ぐらいまでであれば、ほとんどの場合実マシンと同等に扱えるのでそこまでで済ます努力をするべき。TCP/IPさまさま。

VirtualBoxの設定

さて、VirtualBoxでのインストール方法の基本と、NAT + Host-Onlyについては同僚がまとめておいてくれたのがあるのでここではURLのみで割愛。

Macの話だけど、Windでもなんら変わらない。

GuestOS側の注意点と設定

で、話はこれだけでは済まなくて、GuestOS側でも少し気をつけておかなければいけない点がある。

ここまでの話でだいたい分かっていると思うけど、NAT + Host-Onlyって方法は、要するにNICを2枚使用して、片方を内部仮想ネットワーク用、もう片方をHostOSとの直接リンク用に使おう、っていう方法。
それで問題になってくるのが何かというと、GuestOS側のネットワーク設定。

この方法を紹介しているほとんどのところでは「VirualBoxでこれ設定すればおk!」とか言ってるけど、これやるとeth0とeth1両方がDHCP扱いになってしまったりする。*3


それの何がまずいかというと、DHCPでifupされたりすると、勝手にDefault Gateway(以下DGと略)まで設定してしまうこと。
2つのネットワーク設定が両方ともDHCPとして作成してあると、それぞれが別々にルーティングテーブルに対してDGを設定しようとする。
そのため、DGが2つになってしまって、GuestOS側のアプリケーションがどっちのゲートウェイを使えばいいのかわからなくなってしまい、結果としてまともに外に出れなくなる。


正常なルーティングテーブルの場合、

# route
カーネルIP経路テーブル
受信先サイト    ゲートウェイ    ネットマスク   フラグ Metric Ref 使用数 インタフェース
10.0.2.0        *               255.255.255.0   U     0      0        0 eth0
192.168.56.0    *               255.255.255.0   U     0      0        0 eth1
default         10.0.2.2        0.0.0.0         UG    0      0        0 eth0

という感じになっているのだが、これのdefaultという行が2行あったりすると、混乱が発生している状態といえる。

また、それぞれのIPについて簡単に解説をしておくと、(ifconfigを見た方がよりわかりやすいが)このときの10.0.2.x系ネットワークがVirtualBoxがNATとして使っているネットワーク帯域で、192.168.56.xというのが、Host-Onlyのネットワーク。*4
そして、VirtualBoxから外部ネットワークに対してアクセスするために利用するGWは、NAT側の方。


なので、正しく混乱を解消するためには、上記のようにNATのネットワークである10.0.2.x系のDGである10.0.2.2のみが単一のゲートウェイとして存在している状態になっている必要がある。
たとえばダメな例としては、

default         192.168.56.1        0.0.0.0         UG    0      0        0 eth1

みたいな行があると、うまく外に出れない。

解決方法

ここまで理屈を並べておいてなんだが、解決策は簡単に2通りあって、

  • Host-Onlyで使っているNIC(この場合はeth1に割り当てられているNIC)のIP設定を、DHCPを使わずにstaticに取得するようにし、gatewayの指定を行わなない。
  • 起動時にダメな方のDG設定を自動的に削除するようにする。

という方法がある。


前者はほぼそのまま。debian系なら/etc/network/interfacesの設定を、Redhat系なら/etc/sysconfig/network-scriptsの該当ethの設定を書き換えてやればよい。
Host-Onlyの方でgatewayを設定しなければ、DHCPで取得するNAT側だけがDGを設定するので、結果理想的な状態になる。もしNATのIPも静的に設定する場合は、そちらにだけgatewayの設定を記述すればよい。

後者は、例えばdebianなら、/etc/network/interfacesの「削除したい側」の最後に

up route del default gw 192.168.56.1

みたいな行を追加しておくことで実現できる。*5

Redhat系は微妙に忘れてるんだけど、/etc/sysconfig/network-scripts/の中にたぶんこういうのを書いておくのに適切なshellスクリプト用ファイルがあるはず。

どちらにしても、最悪/etc/rc.localに

route del default gw 192.168.56.1

って書いちゃえばおk。


これをきちんとやっておけば、NAT + Host-Onlyで複雑な混乱に陥ることなく、HostOSからのみSSHとかHTTPとか通って、GuestOSも外部に気楽にアクセスできる素敵な環境が作れる。


あ、なんかVirtualBoxがどうとかいう話とはだいぶずれた気がする。

*1:や、だいたいの場合VirtualBoxに限らないんだけど

*2:簡単な話なんだけど、何にも考えずにうまく行っちゃう人も多いみたいで情報がなかったんで書いとこうかなと。

*3:もしくは設定がなかったりする。

*4:どちらもデフォルトはこの帯域を使う。

*5:debianのinterfacesファイルにはup から始まる行を書いておくと、ifupするときのみ実行する内容を指定できる。