このドキュメントでは、Outline SDK をモバイル アプリケーションに統合する方法を概説します。特に、ローカル プロキシの管理を簡素化するための MobileProxy
ライブラリに重点を置きます。
MobileProxy
は、プロキシの機能を効率的にモバイルアプリに統合するための、Go をベースにしたライブラリです。Go Mobile を使用してモバイル ライブラリを生成し、アプリのネットワーキング ライブラリを構成してトラフィックをローカル プロキシにルーティングできるようにします。
MobileProxy を使用しないアプリ
MobileProxy を使用するアプリ
ステップ 1: MobileProxy モバイル ライブラリをビルドする
gomobile を使用して Go 言語のコードをコンパイルし、Android 用と iOS 用のライブラリをビルドします。
Outline SDK のリポジトリのクローンを作成します:
git clone https://github.com/Jigsaw-Code/outline-sdk.git cd outline-sdk/x
go build
を使用して Go Mobile のバイナリをビルドします:go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
Psiphon サポートを追加する
以下の追加ステップを行うことにより、Psiphon ネットワークを使用するためのサポートを追加できます:
- Psiphon のネットワークにアクセスするための構成を入手するには、Psiphon チームに問い合わせてください。これには、契約が必要になる場合があります。
- 入手した Psiphon の構成を
SmartDialer
の構成のfallback
セクションに追加します。 -tags psiphon
フラグを使用して Mobile Proxy をビルドします:go build -tags psiphon -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
-tags psiphon
フラグが必要なのは、Psiphon のコードベースのライセンスが GPL の元で付与されているからであり、そのため、あなたのコードにもライセンス制限が課される可能性があります。Psiphon から特別なライセンスを取得することも検討してください。モバイル ライブラリを生成し、プロジェクトに追加します:
Android
PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=android -androidapi=21 -o "$(pwd)/out/mobileproxy.aar" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy
Android Studio で [File] > [Import Project…] を選択し、生成した
out/mobileproxy.aar
バンドルをインポートします。詳しくは、Go Mobile のビルドと Android へのデプロイをご覧ください。iOS
PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=ios -iosversion=11.0 -o "out/mobileproxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy
out/mobileproxy.xcframework
バンドルを Xcode プロジェクトにドラッグします。詳しくは、Go Mobile のビルドと iOS へのデプロイをご覧ください。
ステップ 2: MobileProxy を実行する
アプリのランタイム内で MobileProxy
ローカル プロキシを初期化し、開始します。静的なトランスポート構成を使用することも、動的な戦略選択のために Smart Proxy を使用することも可能です。
静的トランスポート構成:
RunProxy
関数を使用して、ローカル アドレスとトランスポートを構成します。Android
import mobileproxy.* val dialer = StreamDialer("split:3") // Use port zero to let the system pick an open port for you. val proxy = Mobileproxy.runProxy("localhost:0", dialer) // Configure your networking library using proxy.host() and proxy.port() or proxy.address(). // ... // Stop running the proxy. proxy.stop()
iOS
import Mobileproxy let dialer = MobileproxyStreamDialer("split:3") // Use port zero to let the system pick an open port for you. let proxy = MobileproxyRunProxy("localhost:0", dialer) // Configure your networking library using proxy.host() and proxy.port() or proxy.address(). // ... // Stop running the proxy. proxy.stop()
Smart Proxy: Smart Proxy は、指定したテストドメインに応じて DSN と TLS の戦略を動的に選択します。構成の戦略は YAML 形式で指定します(例)。
Android
val testDomains = Mobileproxy.newListFromLines("www.youtube.com\ni.ytimg.com") val strategiesConfig = "..." // Config YAML. val dialer = Mobileproxy.newSmartStreamDialer(testDomains, strategiesConfig, Mobileproxy.newStderrLogWriter()) // Use port zero to let the system pick an open port for you. val proxy = Mobileproxy.runProxy("localhost:0", dialer) // Configure your networking library using proxy.host() and proxy.port() or proxy.address(). // ... // Stop running the proxy. proxy.stop()
iOS
import Mobileproxy var dialerError: NSError? let testDomains = MobileproxyNewListFromLines("www.youtube.com\ni.ytimg.com") let strategiesConfig = "..." // Config YAML. let dialer = MobileproxyNewSmartStreamDialer( testDomains, strategiesConfig, MobileproxyNewStderrLogWriter(), &dialerError ) var proxyError: NSError? // Use port zero to let the system pick an open port for you. MobileproxyRunProxy("localhost:0", dialer, &proxyError) // Configure your networking library using proxy.host() and proxy.port() or proxy.address(). // ... // Stop running the proxy. proxy.stop()
ステップ 3: HTTP クライアントとネットワーキング ライブラリを構成する
ローカル プロキシ アドレスとポートを使用するようにネットワーキング ライブラリを構成します。
Dart/Flutter HttpClient
HttpClient.findProxy
を使用してプロキシを設定します。
HttpClient client = HttpClient();
client.findProxy = (Uri uri) {
return "PROXY " + proxy.address();
};
OkHttp(Android)
OkHttpClient.Builder.proxy
を使用してプロキシを設定します。
val proxyConfig = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxy.host(), proxy.port()))
val client = OkHttpClient.Builder().proxy(proxyConfig).build()
JVM(Java、Kotlin)
システム プロパティを使用してプロキシを構成します。
System.setProperty("http.proxyHost", proxy.host())
System.setProperty("http.proxyPort", String.valueOf(proxy.port()))
System.setProperty("https.proxyHost", proxy.host())
System.setProperty("https.proxyPort", String.valueOf(proxy.port()))
Android WebView
androidx.webview
ライブラリを使用して、アプリケーション内のすべての WebView にプロキシの構成を適用します。
ProxyController.getInstance()
.setProxyOverride(
ProxyConfig.Builder()
.addProxyRule(this.proxy!!.address())
.build(),
{}, // execution context for the following callback - do anything needed here once the proxy is applied, like refreshing web views
{} // callback to be called once the ProxyConfig is applied
)
iOS WebView
iOS 17 以降では、WKWebsiteDataStore
プロパティを使用して WKWebView
にプロキシの構成を追加できます。
let configuration = WKWebViewConfiguration()
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(proxyHost), port: NWEndpoint.Port(proxyPort)!)
let proxyConfig = ProxyConfiguration.init(httpCONNECTProxy: endpoint)
let websiteDataStore = WKWebsiteDataStore.default()
websiteDataStore.proxyConfigurations = [proxyConfig]
let webview = WKWebView(configuration: configuration)
高度な用例: カスタム モバイル ライブラリを生成する
高度な用例として、独自のモバイル ライブラリを生成することも可能です。
- Go ライブラリを作成する: 必要な SDK 機能をラップした Go パッケージを作成します。
- モバイル ライブラリを生成する:
gomobile bind
を使用して Android ARchive(AAR)と Apple フレームワークを作成します。例: - アプリに統合する: 生成したライブラリをモバイル アプリケーションに追加します。