Ajouter le SDK Outline à votre application mobile

Ce document explique comment intégrer le SDK Outline à vos applications mobiles, en mettant l'accent sur la bibliothèque MobileProxy pour simplifier la gestion des proxys locaux.

MobileProxy est une bibliothèque basée sur Go conçue pour simplifier l'intégration des fonctionnalités de proxy dans les applications mobiles. Il utilise Go Mobile pour générer des bibliothèques mobiles, ce qui vous permet de configurer les bibliothèques réseau de votre application pour acheminer le trafic via un proxy local.

Application sans MobileProxy

Application de contenu sans MobileProxy

Application avec MobileProxy

Application de contenu avec MobileProxy

Étape 1: Créer des bibliothèques mobiles MobileProxy

Utilisez gomobile pour compiler le code Go en bibliothèques pour Android et iOS.

  1. Clonez le dépôt du SDK Outline:

    git clone https://github.com/Jigsaw-Code/outline-sdk.git
    cd outline-sdk/x
    
  2. Créez les binaires Go Mobile avec go build:

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

    Ajouter la prise en charge de Psiphon

    Pour utiliser le réseau Psiphon, procédez comme suit:

    • Contactez l'équipe Psiphon pour obtenir une configuration qui vous donne accès à son réseau. Un contrat peut être nécessaire.
    • Ajoutez la configuration Psiphon reçue à la section fallback de votre configuration SmartDialer.
    • Créez le proxy mobile à l'aide de l'option -tags psiphon:

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

    L'indicateur -tags psiphon est obligatoire, car le codebase Psiphon est sous licence GPL, ce qui peut imposer des restrictions de licence à votre propre code. Vous pouvez envisager d'obtenir une licence spéciale auprès de ces organismes.

  3. Générez des bibliothèques mobiles et ajoutez-les à votre projet:

    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
    

    Dans Android Studio, sélectionnez File > Import Project (Fichier > Importer un projet) pour importer le bundle out/mobileproxy.aar généré. Pour en savoir plus, consultez Créer et déployer sur Android dans 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
    

    Faites glisser le bundle out/mobileproxy.xcframework vers le projet Xcode. Pour en savoir plus, consultez la section Créer et déployer sur iOS de Go Mobile.

Étape 2: Exécutez MobileProxy

Initialisez et démarrez le proxy local MobileProxy dans l'environnement d'exécution de votre application. Vous pouvez utiliser une configuration de transport statique ou le proxy intelligent pour la sélection dynamique des stratégies.

  • Configuration de transport statique: utilisez la fonction RunProxy avec une adresse locale et une configuration de transport.

    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()
    
  • Proxy intelligent: le proxy intelligent sélectionne dynamiquement des stratégies DNS et TLS en fonction des domaines de test spécifiés. Vous devez spécifier la stratégie de configuration au format YAML (exemple).

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

Étape 3: Configurer les clients HTTP et les bibliothèques réseau

Configurez vos bibliothèques réseau pour qu'elles utilisent l'adresse et le port du proxy local.

HttpClient Dart/Flutter

Définissez le proxy avec HttpClient.findProxy.

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

OkHttp (Android)

Définissez le proxy avec OkHttpClient.Builder.proxy.

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

JVM (Java, Kotlin)

Configurez le proxy à utiliser avec les propriétés système:

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 Web View

Appliquez une configuration de proxy à toutes les vues Web de votre application avec la bibliothèque 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
    )

Vue Web iOS

Depuis iOS 17, vous pouvez ajouter une configuration de proxy à un WKWebView à l'aide de sa propriété 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)

Avancé: générer une bibliothèque mobile personnalisée

Pour les cas d'utilisation avancés, vous pouvez générer vos propres bibliothèques mobiles:

  1. Créer une bibliothèque Go: développez un package Go encapsulant les fonctionnalités du SDK requises.
  2. Générer des bibliothèques mobiles: utilisez gomobile bind pour générer des archives Android (AAR) et des frameworks Apple. Exemples :
  3. Intégrez-la à votre application: ajoutez la bibliothèque générée à votre application mobile.