Dodawanie pakietu Outline SDK do aplikacji mobilnej

W tym dokumencie opisujemy sposób integracji pakietu Outline SDK z aplikacjami mobilnymi, skupiając się na bibliotece MobileProxy umożliwiającej uproszczone zarządzanie lokalnym serwerem proxy.

MobileProxy to biblioteka Go, która ułatwia integrację funkcji proxy z aplikacjami mobilnymi. Wykorzystuje Go Mobile do generowania bibliotek mobilnych, co umożliwia skonfigurowanie bibliotek sieciowych aplikacji w celu kierowania ruchu przez lokalny serwer proxy.

Aplikacja bez MobileProxy

Aplikacja do treści bez MobileProxy

Aplikacja z MobileProxy

Aplikacja do treści z MobileProxy

Krok 1. Kompilacja bibliotek mobilnych MobileProxy

Użyj polecenia gomobile, aby skompilować kod Go z bibliotekami na Androida oraz iOS.

  1. Sklonuj repozytorium Outline SDK:

    git clone https://github.com/Jigsaw-Code/outline-sdk.git
    cd outline-sdk/x
    
  2. Utwórz pliki binarne Go Mobile za pomocą polecenia go build:

    go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
    

    Dodawanie obsługi aplikacji Psiphon

    Aby dodać obsługę sieci Psiphon, wykonaj te dodatkowe czynności:

    • Skontaktuj się z zespołem Psiphon, aby otrzymać konfigurację umożliwiającą dostęp do tej sieci. Może to wymagać zawarcia umowy.
    • Dodaj otrzymaną konfigurację Psiphon do sekcji fallback konfiguracji SmartDialer.
    • Skompiluj bibliotekę MobileProxy przy użyciu flagi -tags psiphon:

      go build -tags psiphon -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
      

    Flaga -tags psiphon jest wymagana, ponieważ baza kodu Psiphon jest objęta licencją GPL, która może nakładać ograniczenia licencyjne na Twój własny kod. W związku z tym być może warto uzyskać specjalną licencję od firmy Psiphon.

  3. Wygeneruj biblioteki mobilne i dodaj je do projektu:

    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
    

    W Android Studio wybierz Plik > Importuj projekt…, aby zaimportować wygenerowany pakiet out/mobileproxy.aar. Więcej informacji znajdziesz w instrukcjach kompilowania i wdrażania aplikacji na Androida dotyczących Go Mobile.

    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
    

    Przeciągnij pakiet out/mobileproxy.xcframework do projektu w Xcode. Więcej informacji znajdziesz w instrukcjach kompilowania i wdrażania aplikacji na iOS dotyczących Go Mobile.

Krok 2. Uruchamianie MobileProxy

Zainicjuj i uruchom lokalny serwer proxy MobileProxy w środowisku wykonawczym aplikacji. Możesz użyć statycznej konfiguracji transportu lub inteligentnego serwera proxy, który dynamicznie wybiera strategię.

  • Statyczna konfiguracja transportu: użyj funkcji RunProxy z lokalnym adresem i konfiguracją transportu.

    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()
    
  • Inteligentny serwer proxy: ten serwer dynamicznie wybiera strategie DNS i TLS na podstawie określonych domen testowych. Strategię dotyczącą konfiguracji należy określić w formacie YAML (przykład).

    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()
    

Krok 3. Konfiguracja klientów HTTP i bibliotek sieciowych

Skonfiguruj biblioteki sieciowe, aby używały adresu i portu lokalnego serwera proxy.

HttpClient Dart/Flutter

Ustaw serwer proxy przy użyciu metody HttpClient.findProxy.

HttpClient client = HttpClient();
client.findProxy = (Uri uri) {
  return "PROXY " + proxy.address();
};

OkHttp (Android)

Ustaw serwer proxy przy użyciu metody OkHttpClient.Builder.proxy.

val proxyConfig = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxy.host(), proxy.port()))
val client = OkHttpClient.Builder().proxy(proxyConfig).build()

JVM (Java, Kotlin)

Skonfiguruj serwer proxy za pomocą właściwości systemowych:

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

Zastosuj konfigurację serwera proxy do wszystkich widoków WebView w bibliotece androidx.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

Od wersji iOS 17 możesz dodać konfigurację serwera proxy do obiektu WKWebView za pomocą jego właściwości WKWebsiteDataStore:

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)

Zaawansowane: generowanie niestandardowej biblioteki mobilnej

W zaawansowanych przypadkach użycia możesz wygenerować własne biblioteki mobilne:

  1. Tworzenie biblioteki Go: utwórz pakiet Go zawierający wymagane funkcje SDK.
  2. Generowanie bibliotek mobilnych: użyj polecenia gomobile bind, aby utworzyć pliki Android Archive (AAR) i frameworki Apple. Przykłady:
  3. Integracja aplikacji: dodaj wygenerowaną bibliotekę do aplikacji mobilnej.