SoftEther VPNを使ってVM用のローカルNATを構築する(VPN機能は使わない)

VMをネットワークに見せるのに従来はWindowsのICS(Internet Connection Sharing: いわゆる"インターネット接続の共有")を使っていたが、どうもAnniversary Update以降挙動が変わってしまったらしく、自分でDHCP IPアドレスを発行したホストのみ通信できるような挙動になったように見える。実際にそうなったのかは何とも言えないが不安定になった印象。
というわけで、どこでも動くことに関しては定評のあるSoftEtherを使ってICSを置き換えることにした。SoftEtherDynamic DNSを切る簡単な方法が無いなどいくつかの異常な仕様を除けばネットワークユーティリティとしてかなり便利に使うことができる。
... 書いてから気付いたけどSoftEtherのメイン機能であるところのVPN機能を今回の使用例では一切使っていない! もうちょっと簡単にこの手のネットワークを構築できれば。。クライアント版のWindowsは色々と地味な制限が多く設定も面倒な事が多い。サーバー版だと悩むところも少いんだけど。。

ダウンロードとインストール

商用製品のPacketiXGPL版という性格からかダウンロードが地味にわかりづらいが http://www.softether-download.com/ja.aspx?product=softether から SoftEther VPN Server Manager for Windowsをダウンロードする。
手元の環境だとIPRoutingが動作している状態では仮想NATが正常に動作しなかった。通常のシチュエーションではこれは有効になっていないはずで、ipconfig /allで確認できる。

IPルーティング有効 が "いいえ"になっていることを確認する。

ネットワークの構築と仮想HUBの設定

今回やりたいこと: Windowsホスト上のVirtualBoxで動作するVMに対して仮想LANを提供し、ローカルのLANホストと通信させたい。

項目 Windows標準のICS VirtualBox内蔵NAT SoftEtherの仮想NAT
ホストPCのIPアドレス × 192.168.137.1に強制 ○ 選べる ○ 選べる
ポートフォワーディング ○ 可能 ○ 可能 × 不可
UPnP ○ 一応動作する × 不可 × 不可
挙動 × 最近静的IPで運用すると不審 ○ 普通 画期的(後述)
物理ホストの参加可能性 ○ 普通のI/F × 仮想NICなし ○ 普通のI/F
DHCPサーバ
DNSフォワーディング
ICMP ○(proxy) ○(proxy) ×(代理応答)
  • Windows標準のICS: VirtualBoxのHost Only Networkアダプタをプライベート接続ということにして"ネットワーク接続の共有"する。このネットワークに物理ホストを参加させる必要が有るならば、NICを追加してブリッジすれば良い。
  • VirutalBox内蔵NAT: VirutualBoxのネットワーク設定でNATを選択する。この方法は物理ホストと通信させる良い方法が無いので没になった。
  • SoftEtherの仮想NAT: VirtualBoxのHost Only Networkアダプタを仮想HUBに接続し、接続したHUB上で仮想NATを有効にする。

要するにローカルの物理ホストとVMをNATネットワーク上で混ぜる必要が無ければVirtualBox標準のNAT機能で十分。SoftEtherの仮想NATにはUPnPやポートフォワーディングが無いが、個人的には必要無いのでOK。
SoftEtherの仮想HUBには、VPNクライアントで接続する以外に"ローカルブリッジ"機能を使用してローカルに接続されたNICをHUBに接続することができる。

仮想NATの設定

「SecureNAT (セキュアナット) 」機能は、SoftEther VPN のために独自に開発された、これまでに存在しなかった画期的な機能です。SecureNAT を使用すると、セキュリティ的により安心なネットワークを構築することができます。

  • snip -

SecureNAT 機能は内部で仮想の TCP/IP スタックを持つことによって、一度 TCP/IP スタックによってパケット化した TCP/IP ストリームを再度組み立て、さらにそれをオペレーティングシステムを通じて、TCP/IP パケット化するというような大変高度な処理を行っています。

それ知ってる!Slirp( https://en.wikipedia.org/wiki/Slirp )だよね!
Wikipediaでも言及されているように、意外とこの手のユーザモードTCP/UDP proxyは実装が少い。実際のSoftEtherでは、Slirpのようなユーザモードでのproxyの他に普通のカーネルモードNATも備えている。

SecureNAT は仮想 NAT 機能の利用時に、ホスト OS に接続されたイーサネットインターフェイスと Raw IP ソケットで、 DHCP 要求を送信してみます。この DHCP 要求で IP アドレスを取得できたら、インターネット上の Web サーバーの名前解決が DNS で行えることと、解決された IP アドレスへの HTTP での接続が可能であることを確認します。全てに成功した場合のみ、そのインターフェイスが仮想 NAT の WAN 側として使用されます。

また、仮想 HUB 拡張オプションから、各モードの利用を明示的に禁止することもできます。
カーネルモードを禁止する場合は「DisableKernelModeSecureNAT」を、Raw IP モードを禁止する場合は「DisableRawIpModeSecureNAT」を、ユーザモードを禁止する場合は「DisableUserModeSecureNAT」を、それぞれ「1」に設定して下さい。

"Secure"NATという名前の機能なのにセキュアなところが一つも無いのは画期的だな...なんでこんな重要なことがドキュメントに書いていないんだ... 手元では、SeLow_x64 → NdisGetDataBuffer でBSODしたのでユーザモードNATを使っている。
そもそも、SoftEtherには仮想L3スイッチも有るので、これを使えばWAN側を手で設定できるわけで。。WAN側の自動構成の存在意義がよくわからない。SoftEtherの挙動はこういう謎の秘密機能が多い気がしている。
ちなみに、ドキュメント側の記述は:

仮想 NAT 機能がまるで一台の NAT 機能付きルータとして動作し、仮想 HUB が動作しているコンピュータを経由して、そのコンピュータの既存のネットワークインターフェイスを用いて物理的なネットワーク上のホストに対してアクセスすることができます。

となっていて、通信主体がサーバ側であることは一応記述が有る。