AndroidのOpenVPN:接続を切断せずにWiFiデータとモバイルデータを透過的に切り替える

こんにちは、私の経験を共有させてください。



通信の切断に不可欠なアプリケーションがありますが、再接続は苦痛であり、常にそうとは限りません。 接続が一定で、TCP接続が切断されないように、ジャンプルートと物理接続を透過的にする目標を設定しました。





そして、古くて良いopenvpnチューブがこれを助けます。 しかし、インストールと構成は長年の話題であり、ここで触れることは計画されていません。



必要なもの:






さあ始めましょう


「openvpn-settings」を編集することから始めましょう。 一番下の行は、ネットワーク構成が変更されると、 SIGUSR1コマンドがopenvpnネイティブデーモンに送信され、それにより強制的に切断および再接続されます。 私たちの目的にとって、これは有害ですが、ネットワーク構成を変更するときに何らかのアクションを実行できることが望ましいです。



誰かが言うでしょうが、 persist-tunがあります。 私の答えは、それは私が望むようには機能しないということです。openvpnは、 SIGUSR1が到着するたびに起動スクリプトを引き出します。 そして原則として、利用可能な変数によって、トリックなしで再起動を開始と区別することはほとんど不可能です。 これは事業全体を台無しにしますが、私はそれを簡単かつ確実にしたいです。



したがって、 SIGUSR1の送信をシェルスクリプト呼び出しに置き換えます。



ソースチームをダウンロードする

hg clone code.google.com/p/android-openvpn-settings





ファイルを開く

\ src \ de \ schaeuffelhut \ android \ openvpn \ service \ ManagementThread.java

関数public void sendSignal(int s)を見つけて編集します。

SIGUSR1の送信についてコメントし、ルート権限でスクリプトへの呼び出しを挿入します。

スクリプトファイルには、接続ファイルと同じ名前が付けられますが、sh拡張子が追加されます。



次のようになります。

 case SIGUSR1: //sendCommand( new SimpleCommand( "signal SIGUSR1" ) ); new Shell( "OpenVPN-Settings-ip-route", String.format( "/system/bin/sh %s.sh", Util.shellEscape(mDaemonMonitor.mConfigFile.getAbsolutePath()) ), Shell.SU ).run(); break;
      
      







すべて、収集、署名、インストールできます。 インストールする前に、システムから古い「openvpn-setting」を必ずアンインストールしてください。



次に、openvpn接続構成を確認します。



サーバー


物理接続とIPを変更するため、サーバーにfloatディレクティブを導入する必要があります。 また、サーバーはクライアントの内部アドレスを外部ネットワークに変換する必要があります。 これを構成するには、 upおよびdownディレクティブを使用する方が便利です。



up "/ bin / sh / etc / openvpn / androidupdown"

「/ bin / sh / etc / openvpn / androidupdown」



スクリプトは次のようになります。

 NATGW="1.2.3.4" # ip      NATDEV="eth0" #          NATNET="10.9.8.0/24" # vpn ,       sysctl -w net.ipv4.ip_forward=1 ACT="A" [ "down" = "$script_type" ] && ACT="D" iptables -t nat -$ACT POSTROUTING -s $NATNET -o $NATDEV -j SNAT --to-source $NATGW
      
      







お客様


最初に、もしあれば、 リダイレクトゲートウェイディレクティブを削除する必要があります。 ただし、ルートを構成するスクリプトを使用セットアップおよびダウンします。 覚えている場合は、shを追加してファイル名に構成名を繰り返すことに同意しました。 はい、デーモンとモニターの両方から同じスクリプトを呼び出します。



構成の名前が「testconfig.ovpn」の場合、次のようにします。



up "/ system / bin / sh /sdcard/openvpn/testconfig.ovpn.sh"

「/システム/ビン/ sh /sdcard/openvpn/testconfig.ovpn.sh」



スクリプト

 #   export ANDROID_PROPERTY_WORKSPACE=12,66560 #     export PATH=/system/bin:/system/xbin:$PATH setprop net.dns1 8.8.8.8 #   DNS setprop net.dns2 8.8.4.4 #      openvpn. if [ "init" = "$script_context" ]; then ACT="add" [ "down" = "$script_type" ] && ACT="del" ip route $ACT throw $remote_1 table 100 ip route $ACT default dev $dev table 100 ip rule $ACT table 100 pref 1000 fi
      
      







ここで少し説明する価値があります。

デフォルトゲートウェイvpnトンネルを示す番号100の代替ルーティングテーブルを作成します。 そして、mainという名前でメインテーブルに入る前に、100番のテーブルのすべてのトラフィックをラップするルーティングルールを追加します。



代替テーブルには、サーバー宛てのパケットをルールのチェーンに戻すルートがあります。 次に、メインルーティングテーブルに移動します。 そこで、物理接続のメインルートを見つけることができます。 しかし、もし彼らがそれを見つけなければ、これは再接続の間に起こります、そして、これは怖くないです。 Openvpnはしばらく苦しむかもしれませんが、決して永遠に続くわけではありません。 ログ内のメッセージのみが、短時間の通信不足を思い出させます。



スクリプトが改行で終わることを忘れないでください。



Androidでスクリプトを実行できるようにするには、「組み込み+スクリプト」を「設定」に設定する必要があります。「設定」は、接続のロングタップで呼び出されます。 今、あなたは試すことができます。



テストの結果、一部のプログラム自体がネットワークのステータスをチェックし、変更中に再接続を試みることが判明しました。 ここで、著者に状況を修正するよう依頼してください。 または、自分でコンパイルして修正します。 いずれの場合でも、TCPセッションはタイムアウトではなく、必要に応じて閉じられます。



どんな批判やコメントも歓迎します。 安定した接続を望みます!



All Articles