VMware PlayerでNAPT

同じようなタイトルの記事はたくさんあるけれど結構ハマったので。
空気は読めると思うけど正確に言うと、VMwareのネットワークの設定でNATを選択していると、NAPTしてくれるので、その中で(性的|静的)(ポート(変換|フォワーディング)|IPマスカレード)をやりたいと言う事です。

環境

ホスト

  • Windows 7
  • VMware Player 5.0.1
  • IP(LAN): 10.169.153.122
  • IP(VMnet8): 192.168.11.1

ゲスト

ためしにSSH(port:22)が繋がるようにしてみます。

NAPT設定

検索するといっぱい出てくる情報

ググるとすぐに出てくる情報は「vmnetcfg.exe を使って云々」と言う記事ばかり。
なので、色んなサイトを参考にしつつ。
最近のVMware Playerにこれは含まれていないので、「VMware workstation」をダウンロードしてきて、その中からvmnetcfg.exeを引っこ抜くとか、やってみたけど、起動しても無反応です。

行き着いた方法

別にわざわざツールを使用しなくても、NAPTの設定自体は vmnetnat.conf に分かりやすい形式で保存されるっぽい。
場所はここ。

C:\Users\All Users\VMware\vmnetnat.conf

内容こんな感じ。incomingtcp の下に追記。

[incomingtcp]
10022 = 192.168.11.129:22

この場合だと、ホストの10022番ポートを、ゲスト(192.168.11.129)の22番ポートへ。って意味になるらしい。
別に vmnetcfg.exe いらなくない?

で、その後 VMware NAT Service と言うサービスを再起動。

ファイアウォールの設定

よくある事なので忘れないとは思うけど、Windowsの方のファイアウォールの設定は忘れずに。やりました。
「セキュリティが強化された Windows ファイアウォール」と言う大層な名前の画面で「新しい規則」→「ポート」選択、「次へ」→「TCP」「特定のローカルポート」選択、22を入力、「次へ」→「接続を許可する」選択、「次へ」→「プライベート」だけでいいらしい、「次へ」→「名前」はわかる範囲で適当に。「完了」

接続してみる

つながりません

試したこと

  • 他マシン→ホスト(10.169.153.122:10022)に繋がらない。(←これがそもそもの問題)
  • ホスト→ホスト(127.0.0.1:10022)に繋がらない。(←つまりWindowsファイアウォールとか以前の問題)
  • ホスト→ゲスト(192.168.11.129:22)に直接はもちろん繋がる。(←サービスが起動してないとかじゃない)

で、ゲストのアクセス制限周りを疑ってみる。
例えば192.168.11.*しかダメみたいな設定になってるかも。

  • iptables の内容を確認→22は無条件で通してるっぽい
  • 念のため iptables を切ってみる → 繋がらない
  • /etc/hosts.allow, /etc/hosts.denyあたりを確認 → 特に何も書いてない
  • /etc/security/access.conf を確認 → 全部コメント

他に何かあったっけ・・・?って事で途方にくれる。

原因と対処

神が舞い降りた瞬間でした。
あれ? vmnetnat.conf の更新日時が変わってない。
再度開く→書き換えられてる→再度保存する→更新日時変わらない→デスクトップにコピって開いてみる→書き換わってない状態!?→そのまま更新する→更新日時変わった→元あった場所に上書きコピー→更新日時変わった→サービス再起動→おめでとう。

つまりどういう事かと言うと

C:\Users\All Users\VMware と言うパスがミソなのでしょう。
この辺にあるファイルを直接編集する事は出来ないようです(以前何か別の事で同じような現象が発生したのを思い出しました)。
「管理者として実行」とかを駆使すれば編集できたような気もしますが、ハッキリ覚えてません。
いつか別記事にまとめるかも知れないしまとめないかも知れない。

更なる現象(オマケ編)

実は

  • ホスト→ホスト(127.0.0.1:10022)に繋がらない。(←つまりWindowsファイアウォールとか以前の問題)

この問題は解決したけど、未だに

  • 他マシン→ホスト(10.169.153.122:10022)に繋がらない。(←これがそもそもの問題)

この問題は解決していませんでした。

ssh_exchange_identification: Connection closed by remote host

他のホストから接続しようとすると、こんなメッセージが出るんですが、解析の糸口にはなりません。
先述した通り、アクセス制限あたりは既に調べつくしているので。

更なる原因

ゲスト上でパケットキャプチャしてみると、どうやらパケットは受信しているようだったので行き着いたんですが、DefaultGatewayの問題でした。
このゲストには実は使ってないもう1個の eth1 というインタフェースがありまして、なぜかデフォルトがこっちを向いていたのが原因でした。

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.11.2    0.0.0.0         UG    0      0        0 eth1  <- こいつが曲者
link-local      *               255.255.0.0     U     1002   0        0 eth0
192.168.11.0    *               255.255.255.0   U     0      0        0 eth0
更なる対処

なので

# route add default gw 192.168.11.2 dev eth0
# route del default gw 192.168.11.2 dev eth1
# route
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.11.2    0.0.0.0         UG    0      0        0 eth0
link-local      *               255.255.0.0     U     1002   0        0 eth0
192.168.11.0    *               255.255.255.0   U     0      0        0 eth0

と言う事で無事解決。