במאמר הזה מוסבר איך לשלב את Outline SDK באפליקציות לנייד, עם דגש על ספריית MobileProxy לניהול פשוט של פרוקסי מקומי.
MobileProxy היא ספרייה מבוססת-Go שנועדה לייעל את השילוב של פונקציות proxy באפליקציות לנייד. הוא משתמש ב-Go
Mobile כדי ליצור ספריות לנייד, וכך מאפשר לכם להגדיר את ספריות הרשת של האפליקציה להפניית תנועה דרך שרת proxy מקומי.
אפליקציה ללא 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 Mobile באמצעות
go build:go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobindהוספת תמיכה ב-Psiphon
כדי להוסיף תמיכה לשימוש ברשת Psiphon, צריך לבצע את השלבים הנוספים הבאים:
- כדי לקבל קובץ הגדרות שיאפשר לכם גישה לרשת שלהם, צריך לפנות לצוות של Psiphon. יכול להיות שיהיה צורך בחוזה.
- מוסיפים את תצורת Psiphon שהתקבלה לקטע
fallbackבתצורתSmartDialer. מריצים את הפקודה
-tags psiphonכדי ליצור את פרוקסי לנייד:go build -tags psiphon -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobindרושמים את Psiphon בחייגן החכם בקוד המקורי.
השימוש בדגל
-tags psiphonנדרש כי בסיס הקוד של Psiphon מורשה במסגרת GPL, שיכולה להטיל הגבלות על הרישיון של הקוד שלכם. אולי כדאי לך לקבל מהם רישיון מיוחד.יוצרים ספריות לנייד ומוסיפים אותן לפרויקט:
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שנוצרה. לקבלת עזרה נוספת, אפשר לעיין במאמר Building and deploying to Android (בנייה ופריסה ב-Android) של Go Mobile.iOS
PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=ios -iosversion=11.0 -o "$(pwd)/out/mobileproxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/mobileproxyגוררים את חבילת
out/mobileproxy.xcframeworkלפרויקט Xcode. למידע נוסף, אפשר לעיין במאמר יצירה ופריסה ב-iOS של Go Mobile.
שלב 2: מריצים את MobileProxy
- מאתחלים ומפעילים את ה-proxy המקומי
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 בוחר באופן דינמי אסטרטגיות DNS ו-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()
- לאחר מכן, אם אתם משתמשים ב-Psiphon, עליכם לרשום את Psiphon באפשרויות של Smart Dialer בקוד המקורי.
Android:
import mobileproxy.Mobileproxy
import psiphon.Psiphon
// ...
val testDomains = Mobileproxy.newListFromLines("www.google.com\ni.ytimg.com")
// You can get a Psiphon config from the Psiphon team at sponsor@psiphon.ca.
val psiphonConfig = "<YOUR_PSIPHON_CONFIG_JSON_HERE>"
val config = """
dns:
- {system: {}}
tls:
- ""
fallback:
- {"psiphon": \(psiphonConfig)}
"""
val options = Mobileproxy.newSmartDialerOptions(testDomains, config)
// Register Psiphon
Psiphon.registerConfig(options, "psiphon")
try {
// Create the dialer
val dialer = options.newStreamDialer()
// ... use the dialer
} catch (e: Exception) {
// Handle error
}
iOS:
import Mobileproxy
import Psiphon
// ...
let testDomains = MobileproxyNewListFromLines("www.google.com\ni.ytimg.com")
// You can get a Psiphon config from the Psiphon team at sponsor@psiphon.ca.
let psiphonConfig = "<YOUR_PSIPHON_CONFIG_JSON_HERE>"
let config = """
dns:
- {system: {}}
tls:
- ""
fallback:
- {"psiphon": \(psiphonConfig)}
"""
let options = MobileproxyNewSmartDialerOptions(testDomains, config)
// Register Psiphon
PsiphonRegisterConfig(options, "psiphon")
do {
// Create the dialer
let dialer = try options.newStreamDialer()
// ... use the dialer
} catch {
// Handle error
}
שלב 3: הגדרת לקוחות HTTP וספריות רשת
מגדירים את ספריות הרשת כך שישתמשו בכתובת ובפורט של ה-proxy המקומי.
Dart/Flutter HttpClient
מגדירים את ה-Proxy באמצעות
HttpClient.findProxy.
HttpClient client = HttpClient();
client.findProxy = (Uri uri) {
return "PROXY " + proxy.address();
};
OkHttp (Android)
מגדירים את ה-Proxy באמצעות
OkHttpClient.Builder.proxy.
val proxyConfig = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxy.host(), proxy.port()))
val client = OkHttpClient.Builder().proxy(proxyConfig).build()
JVM (Java, Kotlin)
מגדירים את ה-proxy לשימוש במאפייני המערכת:
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
כדי להחיל הגדרת Proxy על כל תצוגות האינטרנט באפליקציה, משתמשים בספרייה 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
החל מ-iOS 17, אפשר להוסיף הגדרת שרת proxy ל-WKWebView באמצעות המאפיין 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)
מתקדם: יצירת ספרייה מותאמת אישית לנייד
בתרחישי שימוש מתקדמים, אפשר ליצור ספריות משלכם לנייד:
- יצירת ספריית Go: פיתוח חבילת Go שעוטפת את הפונקציות הנדרשות של ה-SDK.
- יצירת ספריות לנייד: אפשר להשתמש ב-
gomobile bindכדי ליצור ארכיונים של Android (AAR) ומסגרות של Apple. דוגמאות: - שילוב באפליקציה: מוסיפים את הספרייה שנוצרה לאפליקציה לנייד.