rustgate-proxy 0.1.1

MITM-capable HTTP/HTTPS proxy library and CLI
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# RustGate

[![Crates.io](https://img.shields.io/crates/v/rustgate-proxy.svg)](https://crates.io/crates/rustgate-proxy)
[![docs.rs](https://docs.rs/rustgate-proxy/badge.svg)](https://docs.rs/rustgate-proxy)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

MITM-capable HTTP/HTTPS proxy written in Rust. It can be used both as a CLI tool and as a library (crate: `rustgate-proxy`, lib: `rustgate`).

## Features

- **HTTP Proxy** - Forwards plain HTTP requests (with hop-by-hop header stripping)
- **CONNECT Tunneling** - HTTPS passthrough via bidirectional byte relay
- **MITM Mode** - TLS termination for HTTPS interception and inspection
- **Dynamic Certificate Generation** - Per-domain CA-signed cert generation with caching
- **CA Certificate Management** - Auto-generates and stores root CA in `~/.rustgate/` on first run (private key set to `0600`)
- **Request/Response Rewriting** - Hook mechanism via the `RequestHandler` trait
- **IPv6 Support** - Correctly handles CONNECT targets like `[::1]:443`
- **Security Considerations** - Masks query parameters in logs and warns on non-loopback bind

## Architecture

```
Client ──TCP──> RustGate Proxy ──TCP/TLS──> Upstream Server
                    |
              +-----+-----+
              | HTTP Router |
              +-----+------+
           +--------+--------+
           v        v        v
      HTTP Forward CONNECT   CONNECT
        (Plain)   (Tunnel)   (MITM)
                 Passthrough TLS Termination
```

## Installation

### From crates.io

```bash
cargo install rustgate-proxy
```

### Build from source

```bash
git clone https://github.com/uky007/RustGate-Proxy.git
cd RustGate-Proxy
cargo build --release
```

## Usage

### Basic (passthrough mode)

```bash
# Default: starts on 127.0.0.1:8080
rustgate

# Custom port
rustgate --port 9090
```

### MITM mode (TLS interception)

```bash
rustgate --mitm
```

On first startup, a CA certificate is generated at `~/.rustgate/ca.pem`.

### CLI options

```
Usage: rustgate [OPTIONS]

Options:
      --host <HOST>  Listen address [default: 127.0.0.1]
  -p, --port <PORT>  Listen port [default: 8080]
      --mitm         Enable MITM mode (TLS interception)
  -h, --help         Print help
```

### Log level

Controlled with the `RUST_LOG` environment variable:

```bash
RUST_LOG=rustgate=debug rustgate --mitm
RUST_LOG=rustgate=trace rustgate --mitm
```

## Quick verification

### HTTP proxy

```bash
curl -x http://localhost:8080 http://httpbin.org/get
```

### HTTPS passthrough

```bash
curl -x http://localhost:8080 https://httpbin.org/get
```

### MITM (TLS interception)

Send an HTTPS request with the CA certificate:

```bash
curl --cacert ~/.rustgate/ca.pem -x http://localhost:8080 https://httpbin.org/get
```

If you install the CA certificate into your OS trust store, `--cacert` is no longer needed:

```bash
# macOS
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain ~/.rustgate/ca.pem

# Ubuntu/Debian
sudo cp ~/.rustgate/ca.pem /usr/local/share/ca-certificates/rustgate.crt
sudo update-ca-certificates
```

## Use as a library

Crate name is `rustgate-proxy`; library name is `rustgate`.

```toml
[dependencies]
rustgate-proxy = "0.1"
```

### Custom handler

Implement `RequestHandler` to inspect or modify requests and responses passing through the proxy:

```rust
use rustgate::handler::{BoxBody, RequestHandler};
use hyper::{Request, Response};

struct MyHandler;

impl RequestHandler for MyHandler {
    fn handle_request(&self, req: &mut Request<BoxBody>) {
        req.headers_mut()
            .insert("X-Proxied-By", "RustGate".parse().unwrap());
    }

    fn handle_response(&self, res: &mut Response<BoxBody>) {
        res.headers_mut()
            .insert("X-Proxy", "RustGate".parse().unwrap());
    }
}
```

### Embed the proxy server

```rust
use rustgate::cert::CertificateAuthority;
use rustgate::handler::LoggingHandler;
use rustgate::proxy::{handle_connection, ProxyState};
use std::sync::Arc;
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let ca = Arc::new(CertificateAuthority::new().await?);
    let state = Arc::new(ProxyState {
        ca,
        mitm: true,
        handler: Arc::new(LoggingHandler),
    });

    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    loop {
        let (stream, addr) = listener.accept().await?;
        let state = state.clone();
        tokio::spawn(handle_connection(stream, addr, state));
    }
}
```

### Public modules

| Module | Description |
|-----------|------|
| `rustgate::proxy` | `ProxyState`, `handle_connection`, `parse_host_port` |
| `rustgate::cert` | `CertificateAuthority`, `CertifiedKey` |
| `rustgate::tls` | `make_tls_acceptor`, `connect_tls_upstream` |
| `rustgate::handler` | `RequestHandler` trait, `LoggingHandler`, `BoxBody` |
| `rustgate::error` | `ProxyError`, `Result` |

## File layout

```
src/
├── lib.rs        # Library entry point (exports modules)
├── main.rs       # CLI entry point
├── proxy.rs      # Proxy handlers (HTTP forward + CONNECT + MITM)
├── cert.rs       # CA management and dynamic certificate generation
├── tls.rs        # TLS termination and upstream TLS connection
├── handler.rs    # RequestHandler trait definition
└── error.rs      # Error type definitions
tests/
└── integration_test.rs  # Integration tests
```

## Notes

- **Use MITM features only with consent from all parties involved.** Unauthorized interception may violate laws.
- **Authentication and access control are not implemented.** Binding to non-loopback addresses (`0.0.0.0`, `::`, LAN IP, public IP, etc.) can expose the proxy on your network. RustGate warns at startup when binding to non-loopback addresses. Use trusted networks only, or restrict access with firewalls.
- This tool is intended for security testing, debugging, and educational use.

## License

[MIT](LICENSE)

---

## Japanese (日本語)

RustGate は Rust 製の MITM 対応 HTTP/HTTPS プロキシです。CLI ツールとしてもライブラリとしても利用できます。

### 機能

- **HTTP プロキシ** - 平文 HTTP リクエストを転送(hop-by-hop ヘッダ除去対応)
- **CONNECT トンネリング** - HTTPS 通信を双方向バイトコピーでパススルー
- **MITM モード** - TLS 終端による HTTPS 通信の傍受・閲覧
- **動的証明書生成** - ドメインごとの CA 署名証明書を自動生成(キャッシュ付き)
- **CA 証明書管理** - 初回起動時に `~/.rustgate/` へルート CA を自動生成・保存(秘密鍵は `0600`- **リクエスト/レスポンス改変** - `RequestHandler` トレイトによるフック機構
- **IPv6 対応** - `[::1]:443` 形式の CONNECT ターゲットを正しく処理
- **セキュリティ配慮** - ログ出力時にクエリパラメータをマスク、非ループバック bind 時に警告

### インストール

```bash
cargo install rustgate-proxy
```

### ソースからビルド

```bash
git clone https://github.com/uky007/RustGate-Proxy.git
cd RustGate-Proxy
cargo build --release
```

### アーキテクチャ

```text
Client ──TCP──> RustGate Proxy ──TCP/TLS──> Upstream Server
                    |
              +-----+-----+
              | HTTP判定   |
              +-----+------+
           +--------+--------+
           v        v        v
        HTTP転送  CONNECT   CONNECT
        (平文)   (トンネル)  (MITM)
                  パススルー  TLS終端
```

### 使い方

```bash
# デフォルト: 127.0.0.1:8080
rustgate

# ポート指定
rustgate --port 9090

# MITM モード
rustgate --mitm
```

初回起動時に `~/.rustgate/ca.pem` が生成されます。MITM 利用時は必要に応じて OS の信頼ストアに追加してください。

### CLI オプション

```text
Usage: rustgate [OPTIONS]

Options:
      --host <HOST>  リッスンアドレス [default: 127.0.0.1]
  -p, --port <PORT>  リッスンポート [default: 8080]
      --mitm         MITM モード(TLS 傍受)を有効化
  -h, --help         Print help
```

### ログレベル

環境変数 `RUST_LOG` で制御できます:

```bash
RUST_LOG=rustgate=debug rustgate --mitm
RUST_LOG=rustgate=trace rustgate --mitm
```

### 動作確認

HTTP プロキシ:

```bash
curl -x http://localhost:8080 http://httpbin.org/get
```

HTTPS パススルー:

```bash
curl -x http://localhost:8080 https://httpbin.org/get
```

MITM(TLS 傍受):

```bash
curl --cacert ~/.rustgate/ca.pem -x http://localhost:8080 https://httpbin.org/get
```

OS の信頼ストアに CA 証明書を追加すれば `--cacert` は不要です:

```bash
# macOS
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain ~/.rustgate/ca.pem

# Ubuntu/Debian
sudo cp ~/.rustgate/ca.pem /usr/local/share/ca-certificates/rustgate.crt
sudo update-ca-certificates
```

### ライブラリ利用

```toml
[dependencies]
rustgate-proxy = "0.1"
```

公開ライブラリ名は `rustgate` です(crate 名は `rustgate-proxy`)。

#### カスタムハンドラ

```rust
use rustgate::handler::{BoxBody, RequestHandler};
use hyper::{Request, Response};

struct MyHandler;

impl RequestHandler for MyHandler {
    fn handle_request(&self, req: &mut Request<BoxBody>) {
        req.headers_mut()
            .insert("X-Proxied-By", "RustGate".parse().unwrap());
    }

    fn handle_response(&self, res: &mut Response<BoxBody>) {
        res.headers_mut()
            .insert("X-Proxy", "RustGate".parse().unwrap());
    }
}
```

#### プロキシサーバーの組み込み

```rust
use rustgate::cert::CertificateAuthority;
use rustgate::handler::LoggingHandler;
use rustgate::proxy::{handle_connection, ProxyState};
use std::sync::Arc;
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let ca = Arc::new(CertificateAuthority::new().await?);
    let state = Arc::new(ProxyState {
        ca,
        mitm: true,
        handler: Arc::new(LoggingHandler),
    });

    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    loop {
        let (stream, addr) = listener.accept().await?;
        let state = state.clone();
        tokio::spawn(handle_connection(stream, addr, state));
    }
}
```

#### 公開モジュール

| モジュール | 説明 |
|-----------|------|
| `rustgate::proxy` | `ProxyState`, `handle_connection`, `parse_host_port` |
| `rustgate::cert` | `CertificateAuthority`, `CertifiedKey` |
| `rustgate::tls` | `make_tls_acceptor`, `connect_tls_upstream` |
| `rustgate::handler` | `RequestHandler` トレイト, `LoggingHandler`, `BoxBody` |
| `rustgate::error` | `ProxyError`, `Result` |

### ファイル構成

```text
src/
├── lib.rs        # ライブラリエントリポイント(モジュール公開)
├── main.rs       # CLI エントリポイント
├── proxy.rs      # プロキシハンドラ(HTTP転送 + CONNECT + MITM)
├── cert.rs       # CA証明書管理、動的証明書生成
├── tls.rs        # TLS終端、upstream TLS接続
├── handler.rs    # RequestHandler トレイト定義
└── error.rs      # エラー型定義
tests/
└── integration_test.rs  # 統合テスト
```

### 注意事項

- MITM 機能は通信当事者全員の同意を得たうえで使用してください。
- 認証・アクセス制御は未実装です。`0.0.0.0``::` で bind するとネットワーク公開される可能性があります。
- 本ツールはセキュリティテスト、デバッグ、教育目的での利用を想定しています。