SoftEtherのコマンドを使って接続先のVPNサーバを自動で切り替える方法(By VBA)

SoftEtherというツールがある。たしか、2000年代の前半に登さん・・・当時、筑波大の大学院生だったかな・・・が開発したと記憶している。SoftEtherの目玉の一つは、コマンドラインベースで実行できることだ。VPN関連ツールはいくつか触れたことがあるが、全てGUIであり、他のツールから利用するのは難しかった。(SoftEtherのコマンドについてはページ下部にリンク貼っています)

前置きはここまで。この記事では、VBAでSoftEtherを制御し、接続先のVPNサーバを自動で切り替える方法をざっくりと説明する。前提として、SoftEther Clientがインストール済みでGUIツールの使用経験があることとする。GUIツールを使ったことがないと以下の説明はおそらく理解できないはず。

処理の大雑把な流れ

まず、あらかじめSoftEther Clientの接続設定をしておく。
そして、プログラムの処理フローは以下のようになる。
 ① 接続設定に記載されているIP(VPNサーバのIP)を取得
 ② 接続設定の現在のステータスを取得し、VPNサーバ接続中の場合は切断する。
 ③ ①で取得したVPNサーバと異なるサーバ情報を取得
 ④ ①の接続設定を③で取得したサーバ情報で上書き
 ⑤ 新しく設定された接続設定によりVPNサーバーに接続

VPNサーバを切り替えるには、まず現在の接続先を把握し、それと異なるサーバに接続するという流れだ。

SoftEther Clientの設定

まず、あらかじめSoftEther Clientで新しい接続設定を作成しておく。ここでは “vpntest” という名前にする。

作成する際は、赤枠のように設定する。
 接続設定名:任意(この記事ではvpntest)
 ホスト名 :任意
 仮想HUB名:VPNGATE(固定値)
 使用する仮想LANカード:リストから選択(なければ自分で作って)
 ユーザー名:vpn
 パスワード:vpn

① 接続設定に記載されているIP(VPNサーバのIP)を取得

SoftEtherのAccountGetコマンドを使えば、指定された接続設定の内容を取得できる。VBAから実行する場合のサンプルコードを以下に示す。

ret = obj.Run("vpncmd localhost /client /out:""" & ThisWorkbook.path & "\vpncon.log"" /cmd AccountGet " & conname, 1, True)

このコードの実行によりファイルvpncon.logが作成され、接続設定情報が出力される(図①)。変数connameには接続設定名(当記事の場合は”vpntest”)を指定する。図①の赤線部分に現在の接続設定に設定されているVPNサーバのIPが記載されているので、これを取得する。

図① AccountGet コマンドの出力結果

※ VBAで処理する場合は、出力ファイルの文字コードがUTF8なので、SJISに変換する必要がある。
※ サンプルコードでは、WSHのRunによりSoftEtherコマンドを実行している。

② VPNサーバ接続中の場合は切断する

SoftEtherのAccountStatusGetコマンドを使えば、指定された接続設定の現在の接続状態を取得できる。VBAから実行する場合のサンプルコードを以下に示す。

ret = obj.Run("vpncmd localhost /client /out:""" & ThisWorkbook.path & "\vpncon.log"" /cmd AccountStatusGet " & conname, 1, True)

このコードの実行によりファイルvpncon.logが作成され、現在の接続状態の情報が出力される(図②)。図②の赤線部分に接続状態が記載されているので、これを取得して判断する。

図② AccountStatusGet コマンドの出力結果

接続状態が「接続完了」または「接続開始中」「再試行中」などの場合には、切断する。AccountDisconnectコマンドを使えば、指定された接続設定の現在の接続状態を取得できる。VBAから実行する場合のサンプルコードを以下に示す。

ret = obj.Run("vpncmd localhost /client /cmd AccountDisconnect " & conname, 1, True)

③ ①で取得したVPNサーバと異なるサーバ情報を取得

https://www.vpngate.net/ja/
こちらのサイトに利用できるVPNサーバがリストされている。ここから切り替え先のサーバを取得する。

サイトには「独自の VPN Gate アプリを開発する場合、以下の HTML テーブルをパースする代わりに、[CSV リスト][1] を使用することができます。」と記されているが、このCSVにはTCPポート番号が載っていないため、接続設定を上書きするための情報が不足しており、使えない。(私がわからないだけで、もしかしたら使えるかもしれないが。)

仕方ないので、HTMLテーブルを解析してサーバ情報を取得する。VBAなら先日紹介した方法で取得しても良いし、ブラウザを操作して取得しても良い。ポイントは、①で取得したIPと異なるサーバ情報を取得することだ。具体的なコードの掲載は長くなるので、割愛する。

①の接続設定を③で取得したサーバ情報で上書き

AccountSetコマンドを使えば、指定された接続設定を変更できる。③で取得した切り替え先のVPNサーバのIPとTCPポート番号を設定する。VBAから実行する場合のサンプルコードを以下に示す。

ret = obj.Run("vpncmd localhost /client /cmd AccountSet " & conname & " /SERVER:" & vpnHostT.ip & ":" & vpnHostT.tcp & " /HUB:VPNGATE", 1, True)

新しく設定された接続設定によりVPNサーバーに接続

AccountConnectコマンドを使って、指定された接続設定を使用してVPNサーバへの接続を開始する。開始してもすぐに接続完了するわけではないので、繰り返し②のAccountStatusGetコマンドを使って接続状態をチェックするのが良い。VBAから実行する場合のサンプルコードを以下に示す。

ret = obj.Run("vpncmd localhost /client /cmd AccountConnect " & conname, 1, True)

終わりに

これらのプログラムの実行中は、何度かコマンドプロンプトやポップアップが出現するが、自動で消えるので無視しても良い。また、今回のサンプルでは取得した情報をファイルに出力したが、プログラムのバッファ内で扱えるのであればそれでも良い。適当にいじってもらえれば良いかと。

参考ページ

https://ja.softether.org/4-docs/1-manual/6 (SoftEtherのコマンド)
https://www.vpngate.net/ja/ (VPN Gate)