
Cloudflare R2 객체 스토리지를 통해 터널링되는 SOCKS5 프록시로, Python 및 종속성 없는 C++ 에이전트가 암호화된 R2 객체를 통해 TCP 트래픽을 중계하여 은밀한 접근을 제공합니다.
Cloudflare R2 버킷을 통해 터널링되는 SOCKS5 프록시.
[Client App] ◄─SOCKS5─► [Proxy] ◄─── R2 Bucket ───► [Agent] ◄─TCP─► [Target]
프록시는 운영자 머신에서 로컬 SOCKS5 서버를 실행합니다. 모든 CONNECT 요청은 바이너리 패킷으로 직렬화되어 R2 객체로 저장됩니다. 에이전트는 대상 네트워크에서 동일한 버킷을 폴링하여 연결 요청을 가져오고, 실제 TCP 연결을 설정한 후 R2를 통해 데이터를 릴레이합니다.
| 구성 요소 | 언어 | 파일 | 설명 |
|---|---|---|---|
| Proxy | Python | r2socks.py | SOCKS5 서버 (운영자 측) |
| Agent | Python | r2socks.py | 대상 측 릴레이 (에이전트 모드) |
| Agent | C++ | r2agent.cpp | 독립 실행형 Windows 에이전트, 의존성 없음 |
C++ 에이전트는 Python 프록시와 프로토콜 호환됩니다. Windows 네이티브 API(WinHTTP, bcrypt, Winsock2)만 사용하며 외부 라이브러리가 필요하지 않습니다.
dash.cloudflare.com/<ACCOUNT_ID>/r2/...pip install boto3
python r2socks.py proxy -b my-bucket -a <account_id> \
--access-key <R2_ACCESS_KEY> --secret-key <R2_SECRET_KEY>
프록시는 채널 ID를 생성하고 에이전트를 시작하는 명령을 출력합니다.
Python 에이전트:
python r2socks.py agent -b my-bucket -a <account_id> -c <channel_id> \
--access-key <R2_ACCESS_KEY> --secret-key <R2_SECRET_KEY>
C++ 에이전트 (Windows):
.\r2agent.exe -b my-bucket -a <account_id> -c <channel_id> -k <access_key> -s <secret_key>
python r2socks.py proxy [options]
Required:
-b, --bucket BUCKET R2 bucket name
-a, --account-id ID Cloudflare account ID
Optional:
-c, --channel ID Channel ID (auto-generated if omitted)
-l, --listen ADDR Listen address (default: 127.0.0.1:1080)
--access-key KEY R2 API token Access Key ID
--secret-key KEY R2 API token Secret Access Key
--socks-user USER Enable SOCKS5 user/pass authentication
--socks-pass PASS SOCKS5 password
-p, --password PWD AES-256-GCM encryption password
-v, --verbose Debug logging
Python:
python r2socks.py agent [options]
Required:
-b, --bucket BUCKET R2 bucket name
-a, --account-id ID Cloudflare account ID
-c, --channel ID Channel ID (from proxy output)
C++ (Windows):
r2agent.exe [options]
Required:
-b, --bucket BUCKET R2 bucket name
-a, --account-id ID Cloudflare account ID
-c, --channel ID Channel ID (from proxy output)
Credentials (flags override env vars):
-k, --access-key KEY R2 API token Access Key ID
-s, --secret-key KEY R2 API token Secret Access Key
Optional:
-v, --verbose Debug logging
작업 완료 후 채널의 모든 R2 객체 제거:
python r2socks.py clean -b my-bucket -a <account_id> -c <channel_id>
프록시와 에이전트 간에 공유되는 바이너리 패킷 형식:
┌──────────┬────────────────────┬────────────┬──────────────────┐
│ CMD (1B) │ ConnectionID (16B) │ Len (4B BE)│ Payload (var) │
└──────────┴────────────────────┴────────────┴──────────────────┘
여러 패킷이 단일 R2 객체(최대 4MB)로 배치되어 API 호출을 줄입니다. 객체는 순서를 위해 마이크로초 타임스탬프로 이름이 지정되며 소비 후 삭제됩니다.
모든 R2 페이로드에 대한 선택적 AES-256-GCM 암호화:
pip install cryptography
# Both sides must use the same password
python r2socks.py proxy -b bucket -a account_id -p "my-secret-password"
python r2socks.py agent -b bucket -a account_id -c channel -p "my-secret-password"
키는 600,000회 반복의 PBKDF2-SHA256을 사용하여 파생됩니다.
Visual Studio Developer Command Prompt에서:
cl /std:c++17 /EHsc /O2 r2agent.cpp /link ws2_32.lib winhttp.lib bcrypt.lib
프록시와 에이전트 모두 적응형 절전 간격을 사용합니다:
이는 응답성과 API 호출량 간의 균형을 맞춥니다. 통계는 30초마다 기록되며 활성 연결, 전송된 객체, 이동된 바이트를 표시합니다.
SignatureDoesNotMatchw32tm /resync /force (Windows) 또는 sudo ntpdate pool.ntp.org (Linux)RequestTimeTooSkewedw32tm /resync /force
AccessDenied프록시 (Python):
boto3 (필수)cryptography (선택 사항, 암호화용)에이전트 (C++):
| 명령 | 코드 | 방향 | 페이로드 |
|---|
| NEW | 0x01 | Proxy→Agent | ATYP + Address + Port |
| ACK | 0x02 | Agent→Proxy | 1 byte status (0=success) |
| DATA | 0x03 | Bidirectional | Raw TCP data (up to 1MB) |
| CLOSE | 0x04 | Bidirectional | Empty |
| PING | 0x05 | Bidirectional | Empty |