2008年9月8日月曜日

VirtualBox 2.0.0のFreeBSDに、NATとport forwardingを設定してsshでログインできるようにしてみたり、ネットワーク周りの環境整備

前々回、前回の





からの続きです。



前回は、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を、いろんなサーバーとして使っていけるんじゃないかな、と考えています。





0 件のコメント:

コメントを投稿