
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) │
└──────────┴────────────────────┴────────────┴──────────────────┘
複数のパケットは API 呼び出しを減らすために単一の R2 オブジェクト (最大 4MB) にバッチ化されます。オブジェクトは順序付けのためにマイクロ秒のタイムスタンプで命名され、消費後に削除されます。
すべての 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"
鍵は PBKDF2-SHA256 を 600,000 回の反復で使用して導出されます。
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 |