앱별 프록시

루팅 없이 폰에서 고른 앱만 업스트림 SOCKS5나 HTTP 프록시로 보내고, 그 앱이 어떤 주소로 보이는지 확인하고, 인증 정보는 스크립트 밖에 둡니다.

번역된 페이지입니다. 영어 문서와 내용이 다르면 영어 문서가 기준입니다. English

proxy는 내가 고른 앱만 내가 정한 프록시 서버를 거치게 합니다. 폰의 나머지 트래픽과, Droidline이 PC와 주고받는 연결은 평소 네트워크를 그대로 씁니다. 대표적인 용도는 선반 가득한 폰에서, 폰마다 특정 앱 하나가 서로 다른 주소로 나가게 하는 것입니다.

시작하기 전에

  • Android 10 이상.
  • VPN 권한. 앱의 설정 탭에서 한 번 허용합니다. 허용하기 전에는 proxy가 NO_PERMISSION으로 실패합니다.
  • 폰에서 다른 VPN 앱이 켜져 있지 않아야 합니다. 안드로이드는 VPN을 한 번에 하나만 실행하므로 Tailscale, WireGuard 같은 앱과 함께 쓸 수 없습니다.
  • 사용이 허락된 업스트림 프록시. socks5://나 http://이며, 사용자 이름과 비밀번호는 있어도 없어도 됩니다.

켜고, 확인하고, 끄기

d.proxy("socks5://user:pass@203.0.113.10:1080", app="com.android.chrome")
print(d.proxy_check("com.android.chrome"))
# {'active': True, 'ip': '203.0.113.10', 'upstream': 'socks5://203.0.113.10:1080', 'error': ''}
d.proxy("off")
await d.proxy("socks5://user:pass@203.0.113.10:1080", { app: "com.android.chrome" });
console.log(await d.proxyCheck("com.android.chrome"));
// { active: true, ip: '203.0.113.10', upstream: 'socks5://203.0.113.10:1080', error: '' }
await d.proxy("off");
droidline proxy socks5://user:pass@203.0.113.10:1080 --app com.android.chrome
droidline proxy_check com.android.chrome
droidline proxy off

app에는 패키지명 하나나 목록을 넘깁니다. proxy_check는 폰에서 업스트림을 거쳐 요청을 보내고, 외부에서 그 앱이 어떤 주소로 보이는지 알려 줍니다.

비밀번호를 스크립트 밖에 두기

프록시를 짧은 이름으로 PC에 한 번 저장해 두세요. 비밀번호는 config.toml이나 내 코드가 아니라 서버의 비밀 저장소(Windows에서는 DPAPI)에 들어갑니다.

droidline proxy add kr1 socks5://user:pass@203.0.113.10:1080
droidline proxy list

그런 다음 @와 이름으로 가리킵니다.

d.proxy("@kr1", app=["com.android.chrome", "com.example.app"])
await d.proxy("@kr1", { app: ["com.android.chrome", "com.example.app"] });
droidline proxy @kr1 --app com.android.chrome,com.example.app

동작 방식

앱은 고른 앱에만 적용되는 VPN을 시작하고, 그 앱들의 프록시를 Droidline 앱 안의 작은 프록시 서버로 지정합니다. 이 로컬 프록시가 연결을 하나하나 업스트림으로 넘깁니다.

  • http://host:port: user:pass는 선택이며, HTTP CONNECT를 씁니다.
  • socks5://host:port: user:pass는 선택입니다. 호스트 이름은 폰이 아니라 프록시가 해석합니다.

고른 앱의 그 밖의 트래픽은 프록시를 우회해 새어 나가지 않도록 버립니다. 그래서 시스템 프록시 설정을 무시하는 앱은 직접 접속하는 대신 네트워크를 쓸 수 없게 됩니다. Chrome과, WebView나 OkHttp로 만든 앱 대부분은 이 설정을 따릅니다.

실패할 때

proxy는 PROXY_FAILED와 함께 reason을 알려 주며 실패합니다.

이유보통 뜻하는 것
auth사용자 이름이나 비밀번호가 틀림
timeout프록시가 응답하지 않음. 주소가 맞는지, 폰에서 프록시에 닿을 수 있는지 확인하세요
refused그 포트에서 대기 중인 프로그램이 없음
protocolURL은 socks5인데 서버는 HTTP로 응답하거나, 그 반대

proxy_check는 실패하지 않고 같은 문제를 error 필드에 담아 알려 줍니다.

제한

  • 폰마다 한 번에 업스트림 하나만 씁니다. 다른 URL로 proxy를 다시 호출하면 교체됩니다.
  • 프록시가 켜져 있는 동안 앱 안의 로컬 프록시는 폰의 루프백 주소에서 대기합니다. 같은 폰의 다른 앱이 마음먹으면 이 프록시를 쓸 수 있습니다. 내가 관리하는 폰이라면, 믿을 수 없는 앱을 설치할 때만 문제가 됩니다.
  • 사용할 권리가 있는 프록시를, 그런 사용을 허용하는 서비스에만 쓰세요. 이용 약관을 참고하세요.