이 문서에서는 간소화된 로컬 프록시 관리를 위한 MobileProxy
라이브러리에 중점을 두고 Outline SDK를 모바일 애플리케이션에 통합하는 방법을 설명합니다.
MobileProxy
는 모바일 앱에 프록시 기능을 통합하는 과정을 간소화하도록 설계된 Go 기반 라이브러리입니다. Go 모바일을 사용하여 모바일 라이브러리를 생성하므로 로컬 프록시를 통해 트래픽을 라우팅하도록 앱의 네트워킹 라이브러리를 구성할 수 있습니다.
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 모바일 바이너리를 빌드합니다.go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
Psiphon 지원 추가
다음 추가 단계에 따라 Psiphon 네트워크를 사용할 수 있는 지원을 추가할 수 있습니다.
- Psiphon팀에 문의하여 네트워크에 액세스할 수 있는 구성을 받습니다. 계약이 필요할 수 있습니다.
- 수신된 Psiphon 구성을
SmartDialer
구성의fallback
섹션에 추가합니다. -tags psiphon
플래그를 사용하여 모바일 프록시를 빌드합니다.go build -tags psiphon -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind
Psiphon 코드베이스는 GPL에 따라 라이선스가 부여되며, 이는 자체 코드에 라이선스 제한을 적용할 수 있기 때문에
-tags 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 스튜디오에서 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
로컬 프록시를 초기화하고 시작합니다.
동적 전략 선택을 위해 정적 전송 구성 또는 스마트 프록시를 사용할 수 있습니다.
정적 전송 구성: 로컬 주소 및 전송 구성과 함께
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()
스마트 프록시: 스마트 프록시는 지정된 테스트 도메인을 기반으로 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()
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 Web View
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 Web View
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 보관 파일 (AAR) 및 Apple 프레임워크를 생성합니다. 예를 들면 다음과 같습니다. - 앱에 통합: 생성된 라이브러리를 모바일 애플리케이션에 추가합니다.