goo blog サービス終了のお知らせ 

ttt

getttyent

VirtualBox 2.0.0のFreeBSDに、NATとport forwardingを設定して

2008-09-08 00:00:00 | デジタル・インターネット

前々回、前回の

からの続きです。

前回は、VirtualBox 2.0.0の仮想マシンに、FreeBSD 7.0-STABLEをインストールする話でした。仮想マシンを設定するまでの話は、前々回を参照してください。

今回は、ネットワーク関係の環境整備で、以下の2本立て。

  • VirtualBoxのNATを使った場合で、port forwardingを設定することで、仮想マシンのFreeBSDへ、sshでログインできるようにする
  • 仮想マシンのFreeBSDをNFSクライアントとして、別のNFSサーバのファイルシステムと、NFSマウントする・・・(ただし、少々厳しいかもしれない制限つき)

いくつかあるVirtualBoxのネットワーク機能の中で、NATを使った場合についてのみ、試しています。ブリッジ接続については、まだ試していませんが、たぶん、sshログインやNFSマウントするのなら、ブリッジのほうが簡単そうな気がします。

あの、そもそもネットワークが使えないんすけど…?

最初、FreeBSDでは、ネットワークデバイスは、「pcn0」として認識されていました。

Virtualboxnet89

NATを使う場合は、VirtualBoxが、DHCPサーバやルータとして機能するはずなので、仮想マシン側では、DHCPを使えば、簡単にネットワークの設定が完了するはずです。

というわけで、「dhclient pcn0」というコマンドを実行してみたところ

Virtualboxnet98

DHCPサーバから応答がなく、撃沈。

なぜかよくわかりませんが、いろいろ試行錯誤してみた結果、仮想マシンのネットワークアダプタの種類を、「Intel PRO/1000 MT Desktop (82540EM)」に変更してみたところ、正常に動くようになりました。

ネットワークアダプタを変更する方法は、前々回に書いておきましたが、もう一度、簡単に。

VirtualBoxのウインドウで、左側では仮想マシンを選択し、左側の「詳細」タブで青い太い文字の「ネットワーク」をクリックするか、もしくは、「設定」ボタンをクリックしてから「ネットワーク」を選択。

Virtualboxnet1

「Adapter Type」にて、「Intel PRO/1000 MT Desktop (82540EM)」を選びます。

Virtualbox99

こうすると、ゲストOSであるFreeBSDでは、ネットワークインターフェイスが、em0になります。

このように設定変更してから、もう一度、FreeBSDにて、「dhclient em0」を実行してみると

Virtualboxnet100

今度はうまくネットワークが設定されました。

こんな感じになりました。

ネットワークアダプタの設定

% ifconfig em0
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 08:00:27:7e:43:56
        inet 10.0.2.15 netmask 0xffffff00 broadcast 10.0.2.255
        media: Ethernet autoselect (1000baseTX <full-duplex>)
        status: active

ルーティングの設定

% netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            10.0.2.2           UGS         0       33    em0
10.0.2.0/24        link#1             UC          0        0    em0
10.0.2.2           52:54:00:12:35:02  UHLW        2        0    em0   1192
10.0.2.3           52:54:00:12:35:03  UHLW        1       16    em0    655
127.0.0.1          127.0.0.1          UH          0        8    lo0

Internet6:
Destination                       Gateway                       Flags      Netif Expire
::1                               ::1                           UHL         lo0
fe80::%lo0/64                     fe80::1%lo0                   U           lo0
fe80::1%lo0                       link#2                        UHL         lo0
ff01:2::/32                       fe80::1%lo0                   UC          lo0
ff02::%lo0/32                     fe80::1%lo0                   UC          lo0
> ifconfig -a

DNSの設定

% cat /etc/resolv.conf
nameserver 10.0.2.3

ところで、pingコマンドについては、注意したほうがいいかもしれません。

ネットワークが通じるかどうか試験するために、pingコマンドをしばしば使います

VirtualBoxのマニュアルを眺めていたら、NATの場合の制限事項として、「ICMP protocol is very limited」と書いてありました。ICMPはNATを超えて通すのが難しい、ってことらしいです。

pingはICMPを利用します。そのため、pingが通らないことがあるようです。というか実際に、仮想マシン側から外の世界へpingをしたら、通りませんでした。それでも、ネットワークは正常に利用できていて、仮想マシンから外のホストにたいして、sshログインはできました。

今回やりたいことと、/etc/rc.confの設定

やりたいのは、次の2つ。

  1. sshで、ホストOS側から、ゲストOSのFreeBSDにログインできるようにしたり、別のマシンからもsshでログインできるようにしたい。
  2. ゲストOSのFreeBSDをNFSクライアントとして、別ファイルサーバをNFSマウントしたい。

この2つができれば、いろいろなことをやって遊べそうです。いや、かなり実用的なことにも使えそうな見込みもしてきます。

以上のために、/etc/rc.confを次のようにしてみました。ホスト名を設定し忘れていたので、ついでにvirtualbox.localという名前で追加しておきました。なにかと便利なので、amdも有効にしてあります。

keymap="jp.106"
ifconfig_em0="DHCP"
nfs_client_enable="YES"
sshd_enable="YES"
hostname="virtualbox.local"
rpcbind_enable="YES"
amd_enable="YES"

/etc/rc.confを書き換えたら、

# /etc/rc.d/netif start
# /etc/rc.d/sshd start
# /etc/rc.d/nfsclent start

なんていうコマンドを実行すれば、リブートすることなく即座にデーモンを実行できますが、自信がない場合は、一回、リブートしたほうがよいでしょう。

Virtualboxnet112

Virtualboxnet113_2

NATのport forwardingを設定する

NATで仮想マシンはネットワークに接続していますので、ネットワークで接続された他の機器から、仮想マシンの中のゲストOSにネットワークでアクセスできるようにするには、NATのport forwardingを設定する必要があります。

VirtualBoxにて、NATのport forwardingを設定する方法は、ちょっとわかりにくいです・・・

VirtualBoxマニュアルの「6.4.1 Configuring port forwarding with NAT」というところに、さらっと、書いてありました。

port forwardingを設定するには、VBoxManageというコマンドで行うそうでして、GUIの設定ユーティリティのようなものは、無いみたいです。

VBoxManageって何だろう?と思ったら、VirtualBoxのインストール先フォルダにありました。VBoxManage.exeは、Windowsの「コマンドプロンプト」で実行するコマンドなのでした。

C:\>cd "C:\Program Files\Sun\xVM VirtualBox"

C:\Program Files\Sun\xVM VirtualBox>dir vboxmanage*
ドライブ C のボリューム ラベルがありません。
ボリューム シリアル番号は ●●●●-●●●● です

C:\Program Files\Sun\xVM VirtualBox のディレクトリ

2008/09/03  21:07           526,864 VBoxManage.exe
               1 個のファイル             526,864 バイト
               0 個のディレクトリ  11,693,506,560 バイトの空き領域

ははぁ、コマンドライン版のツールなんですね。
FreeBSDでコマンドラインインターフェイス(CLI)ってのはぜんぜんOKなんですが、Windowsの場合は、ちょっと・・・ねぇ。でも、それは私がWindowsのことをよく知らないだけのことで、実は、Windowsでも、超便利なシェルがあるって言いますよね。・・・まぁ、別にいいや、めったに使わないから。

マニュアルには、やりたいこととほぼ同じ、ゲストOSのLinuxにsshでログインするときのコマンドの例がのってます。

それを参考にしてやってみたところ、以下のような3つのコマンドを実行することで、設定できるみたいです。これは、ホストOSのポート2222番にアクセスすると、ゲストOSのポート22番に接続する、という設定です。

VBoxManage setextradata "FreeBSD7" "VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/Protocol" TCP
VBoxManage setextradata "FreeBSD7" "VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/GuestPort" 22
VBoxManage setextradata "FreeBSD7" "VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/HostPort" 2222

  • "FreeBSD7"は、仮想マシンの名前です。
  • guestsshは、任意の名前でいい、とマニュアルに記載されています。
  • ネットワークアダプタを、PCnetからIntelへ変更しているため、「pcnet」の部分が「e1000」になるところがミソかもしれません。
  • 「0」と「LUN#0」はよくわかりません。
    勝手な想像ですが、アダプタは4個まで接続できるらしいので、最初の0は、それかな?
    そして、1個のアダプタで複数のポートを持っている場合に、LUN#がそれぞれに対応する、とか?

コマンドを実行しているときの様子

C:\Program Files\Sun\xVM VirtualBox>VBoxManage setextradata "FreeBSD7" "VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/Protocol" TCP
VirtualBox Command Line Management Interface Version 2.0.0
(C) 2005-2008 Sun Microsystems, Inc.
All rights reserved.
(以下省略)

「vboxmanage getextradata FreeBSD7 enumerate」というコマンドで、設定内容を表示できるみたいです。
最終的に、次のようになりました。

C:\Program Files\Sun\xVM VirtualBox>vboxmanage getextradata FreeBSD7 enumerate
VirtualBox Command Line Management Interface Version 2.0.0
(C) 2005-2008 Sun Microsystems, Inc.
All rights reserved.

Key: GUI/SaveMountedAtRuntime, Value: yes
Key: GUI/LastWindowPostion, Value: 305,460,720,441
Key: GUI/Fullscreen, Value: off
Key: GUI/Seamless, Value: off
Key: GUI/AutoresizeGuest, Value: on
Key: GUI/LastCloseAction, Value: powerOff
Key: VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/Protocol, Value: TCP
Key: VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/GuestPort, Value: 22
Key: VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/HostPort, Value: 2222

このport forwardingを指定するユーザーインターフェイスは、もっと使いやすくなるように、早く改善されるといいですね。

ところで、VBoxManageには、NATの設定以外にも、いろんなことができる機能があるようです。興味があれば、一度マニュアルに目を通しておくといいかもしれません。

port forwardingの設定を反映させるためには、一度、VirtualBoxを終了させる必要があるみたいです。もしかすると、該当する仮想マシンだけ、電源を入れなおせばよいのかもしれません。

仮想マシンを立ち上げ直したあと、おそらくポート番号2222をopenしようとしたとき、Windowsファイアウォールのウインドウが表示されました。

Virtualboxnet106

ここは「ブロックを解除する」ボタンをクリックします。

そのあとで、コントロールパネルの「Windowsファイアウォール」を選び、「例外」タブを確認してみたら、VirtualBoxが登録されていました。

Virtualboxnet3

ポート番号でファイアウォールに穴を開けたのではなくて、プログラム単位で開けたんですね。まぁ、いいか。

Virtualboxnet4

「netstat -an」を実行すれば、ポート番号2222をlistenしている様子が確認できます。

C:\Program Files\Sun\xVM VirtualBox>netstat -an

Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:2222           0.0.0.0:0              LISTENING
(以下略)

「UTF-8 TeraTerm Pro」を使って、sshで仮想マシンにログインする

Windowsで「UTF-8 TeraTerm Pro」を使って、仮想マシンのFreeBSDでログインしてみます。

TeraTermを実行して、「新しい接続」ダイアログボックスにて、以下のように指定します。

Virtualboxnet114

  • 「ホスト」は、VirtualBoxを実行しているパソコンのIPアドレスやホスト名を指定
  • 「サービス」はSSH
  • 「TCPポート#」は、port forwardingのときに指定した、2222

初回接続時は、TeraTermはホスト鍵を知りませんから、「セキュリティ警告」が表示されます。できるだけ、「サーバ側のホスト鍵指紋」が正しいか確認してから、「続行」ボタンをクリックします。

Virtualboxnet115

実は、上の方の、sshdを起動したときの画面イメージに、key fingerprintとして表示されています(3つあって紛らわしいですが、うち1つが、確かに一致しています)。また、ssh-keygenコマンドで、fingerprintを表示できます。

% ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub
1024 57:46:71:c5:27:b3:8e:ae:9e:2f:66:0e:9f:47:ac:e0 /etc/ssh/ssh_host_dsa_key.pub

次に、「SSH認証」というダイアログが表示されます。まだSSHの鍵を作っていないので、公開鍵を使ってログインはできないので、普通のパスワード認証を用います。

Virtualboxnet116

  • 「ユーザ名」に、FreeBSDのユーザー名を入力します。
  • 「チャレンジレスポンス認証を使う(キーボードインタラクティブ)」を選択します。sshdの設定によっていろいろ異なりますが、現行バージョンのFreeBSDでデフォルト設定のままの場合、これが必要です。

「SSH認証チャレンジ」というダイアログボックスが表示されるので、FreeBSDのパスワードを入力します。

Virtualboxnet117

これでログインできるはずです。

Virtualboxnet5

仮想マシンをNFSクライアントにして、NFSマウントしてみる

仮想マシンのFreeBSDから、外の世界のNFSサーバをマウントする場合は、NATの内側から、外側への通信になるため、NATのport forwardingは不要です。

FreeBSD上で、root権限で、mountコマンドを実行。

virtualbox# mount -t nfs NFSサーバ:/home /mnt
[udp] NFSサーバ:/home: RPCPROG_MNT: RPC: Authentication error; why = Client credential too weak

あらら、失敗しました。

NFSサーバのログファイル/var/log/messagesを確認してみたら

Sep  6 09:17:26 NFSサーバ mountd[535]: mount request from 192.168.0.28 from unprivileged port

と記録されていて、ようするに、NFSクライアントが使っているポート番号が、特権ポート(privileged port。1024未満のポート番号のこと。Unixでは、root権限がないと特権ポートを開くことができない)を使っていないので、NFSサーバが拒否しているのでした。

ちなみに、ここで使ったNFSサーバは、FreeBSD 7.0-RELEASEです。

NFSサーバ上でtcpdumpを使って確認すれば、一目瞭然。ポート番号2165、2167、2168などを使っていて、だめっぽいです。

NFSサーバ# tcpdump not port 22 and host Windowsクライアント
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on fxp0, link-type EN10MB (Ethernet), capture size 96 bytes
09:18:36.074844 IP Windowsクライアント.2165 > NFSサーバ.sunrpc: UDP, length 56
09:18:36.075358 IP NFSサーバ.sunrpc > Windowsクライアント.2165: UDP, length 28
09:18:36.077705 IP Windowsクライアント.1221044791 > NFSサーバ.nfs: 40 null
09:18:36.077832 IP NFSサーバ.nfs > Windowsクライアント.1221044791: reply ok 24 null
09:18:36.080492 IP Windowsクライアント.2167 > NFSサーバ.sunrpc: UDP, length 56
09:18:36.080897 IP NFSサーバ.sunrpc > Windowsクライアント.2167: UDP, length 28
09:18:36.081804 IP Windowsクライアント.2168 > NFSサーバ.736: UDP, length 100
09:18:36.082355 IP NFSサーバ.736 > Windowsクライアント.2168: UDP, length 20

仕方ないので、NFSサーバ側で小細工をします。

man mountdして、-nオプションの説明を見ると、そのものズバリなことが書いてあるはずです。

-n      Allow non-root mount requests to be served.  This should only be
        specified if there are clients such as PC's, that require it.  It
        will automatically clear the vfs.nfsrv.nfs_privport sysctl flag,
        which controls if the kernel will accept NFS requests from
        reserved ports only.

mountdに-nオプションをつければ、特権ポート以外からでも、NFSアクセスが許可されるようになります。

ところで、マニュアルにはvfs.nfsrv.nfs_privportというsysctlの変数が出てますが、確認してみると、もともと、

# sysctl -a | grep nfs_priv
vfs.nfsrv.nfs_privport: 0

になってました。

この変数についてのドキュメントも見当たりません。

# sysctl -d -a | grep nfs_priv
vfs.nfsrv.nfs_privport:

0がどういう意味なのか、よくわかりませんね。

とにかく、/etc/rc.confに、

mountd_flags="-r -n"

と書いて(実は、これはあまりよくないらしい。詳細は後述)、/etc/rc.d/mountdを実行すればいいと思ったのですが、なぜか、mountdが再起動している気配がない・・・

# ps axww|grep mountd
  535  ??  Is     0:00.02 /usr/sbin/mountd -r

stopさせても

# /etc/rc.d/mountd stop
# ps axww | grep mountd
  535  ??  Is     0:00.02 /usr/sbin/mountd -r

止まらない・・・からkillしちゃえ。テスト用のNFSサーバなので、こういう無茶も許されるのです(笑)

# kill 535
# ps axww | grep mountd

そしてstartさせても

# /etc/rc.d/mountd start
# ps axww | grep mountd

mountdは起動しない。何これ?たぶん、私が何か勘違いしてる予感。

しょうがないから、手でコマンドを入力して実行。

# /usr/sbin/mountd -r -n
# ps axww | grep mountd
1248  ??  Ss     0:00.01 /usr/sbin/mountd -r -n

動きました。

さっき気になったのでsysctlを確認。

# sysctl -a | grep nfs_priv
vfs.nfsrv.nfs_privport: 0

別に変化なし。

これで、仮想マシンのFreeBSDから、上記と同じコマンドを実行して、NFSマウントできるようになりました。

ちなみに、あとで/etc/rc.d/mountdを眺めていて判明したのですが、/etc/defaults/rc.confに以下のような記述があります。

weak_mountd_authentication="NO"   # Allow non-root mount requests to be served.

というわけで、/etc/rc.confには、以下の1行を書けばよいらしいです。

weak_mountd_authentication="YES"

なお、Virtual BoxのNATの機能制限の1つとして、1024未満のポートを使うことができないことは、VirtualBoxのマニュアルの「6.4.3 NAT limitations」に記載されています。

sshやNFSが使えるようになったので、仮想マシンのFreeBSDの環境構築がやりやすくなると思います。

そして、NATのport forwardinを活用すれば、VirtualBoxの仮想マシンなFreeBSDを、いろんなサーバーとして使っていけるんじゃないかな、と考えています。


コメントを投稿

サービス終了に伴い、10月1日にコメント投稿機能を終了させていただく予定です。
ブログ作成者から承認されるまでコメントは反映されません。