proxy-inspector

Introduction

proxy-inspector is a HTTP/HTTPS proxy based on pingora, proxy-inspector can issue certificate just in time, proxy-inspector can dump HTTP/HTTPS request and response.

Configuration

proxy_config.json sample config:

{
  "groups": [
    {
      "port": 443,
      "lookup_dns": true,
      "tls": {
        "issuer_cert": "cert.pem",
        "issuer_key": "cert.key"
      },
      "proxy_map": {
        "hatter.ink": {
          "address": "101.132.122.240:443",
          "tls": true
        }
      }
    }
  ]
}

Only send DNS query for assigned domain patterns:

{
  "groups": [
    {
      "lookup_dns": false,
      "dns_domains": [
        "example.com",
        "*.example.com",
        "example.*",
        "*.example.*"
      ]
    }
  ]
}

Make self-signed certificate

Generate self-signed certificate:

$ cargo r --example generate_self_signed_ca

When generate success, cert and key will write to files cert.pem, cert.key, fail if any file is existed.

Run Example

Edit /etc/hosts add line:

127.0.0.1 www.baidu.com

Send HTTP request via cURL:

$ curl https://www.baidu.com/not-found -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to www.baidu.com (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=www.baidu.com
*  start date: Mar 30 11:20:17 2024 GMT
*  expire date: Jun 28 12:20:17 2024 GMT
*  subjectAltName: host "www.baidu.com" matched cert's "www.baidu.com"
*  issuer: CN=Hatter Test Intermediate EC CA Class 2
*  SSL certificate verify ok.
> GET /not-found HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< Content-Length: 207
< Content-Type: text/html; charset=iso-8859-1
< Date: Sat, 30 Mar 2024 12:20:22 GMT
< Server: Apache
< Connection: keep-alive
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /not-found was not found on this server.</p>
</body></html>

Log from proxy-inspector console:

[2024-03-30T12:21:28Z INFO  proxy_inspector::service] SNI provided: www.baidu.com
[2024-03-30T12:21:28Z INFO  proxy_inspector::cert] New certificate for: www.baidu.com -> 4f33ad6b50c67dd3356a04bf7885830c90cf0369
[2024-03-30T12:21:28Z INFO  proxy_inspector::app] Request:
    GET /not-found HTTP/1.1
    host: www.baidu.com
    user-agent: curl/7.64.1
    accept: */*
    
    <none>
[2024-03-30T12:21:28Z INFO  proxy_inspector::app] Find host header: www.baidu.com
[2024-03-30T12:21:28Z INFO  proxy_inspector::app] DNS found www.baidu.com --> 180.101.50.188
[2024-03-30T12:21:28Z INFO  proxy_inspector::app] DNS peer: www.baidu.com --> 180.101.50.188:443
[2024-03-30T12:21:28Z INFO  proxy_inspector::app] Response: 
    HTTP/1.1 404 Not Found
    content-length: 207
    content-type: text/html; charset=iso-8859-1
    date: Sat, 30 Mar 2024 12:21:28 GMT
    server: Apache
[2024-03-30T12:21:28Z INFO  proxy_inspector::app] Body true: [[[
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html><head>
    <title>404 Not Found</title>
    </head><body>
    <h1>Not Found</h1>
    <p>The requested URL /not-found was not found on this server.</p>
    </body></html>
    
    ]]] 

proxy-inspector do the follow steps:

  1. issue certificate for www.baidu.com
  2. receive request GET /not-found, print request to log
  3. send DNS query www.baidu.com -> 180.101.40.188
  4. send HTTPS request to 180.101.50.188:443
  5. receive response header, print response header to log
  6. receive response body, print response body to log

Important

  • Intermediate certificate tested:
    • ECDSA(P384) with SHA384
    • P256 with SHA256
  • P384 with SHA256 is NOT supported

TODOs

  • support socks5 -> proxy -> backend
Description
No description provided
Readme 364 KiB
Languages
Rust 100%