<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A stealth HTTPS forward proxy in Rust. Auto-obtains TLS certificates via Let's Encrypt, authenticates users with basic auth, and disguises itself as nginx.">
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://madeye.github.io/https_proxy/">
<meta property="og:title" content="https_proxy — Stealth HTTPS Forward Proxy">
<meta property="og:description" content="A stealth HTTPS forward proxy in Rust with automatic Let's Encrypt TLS, HTTP/2, browser compatibility, and nginx camouflage.">
<!-- Twitter / X -->
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="https_proxy — Stealth HTTPS Forward Proxy">
<meta name="twitter:description" content="A stealth HTTPS forward proxy in Rust with automatic Let's Encrypt TLS, HTTP/2, browser compatibility, and nginx camouflage.">
<title>https_proxy — Stealth HTTPS Forward Proxy</title>
<style>
:root {
--bg: #0d1117;
--surface: #161b22;
--border: #30363d;
--text: #e6edf3;
--text-muted: #8b949e;
--accent: #58a6ff;
--accent-hover: #79c0ff;
--green: #3fb950;
--orange: #d29922;
--red: #f85149;
--purple: #bc8cff;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.6;
}
.container {
max-width: 960px;
margin: 0 auto;
padding: 0 24px;
}
/* Hero */
.hero {
text-align: center;
padding: 80px 0 60px;
border-bottom: 1px solid var(--border);
}
.hero-badge {
display: inline-block;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 20px;
padding: 4px 14px;
font-size: 13px;
color: var(--text-muted);
margin-bottom: 24px;
letter-spacing: 0.5px;
}
.hero h1 {
font-size: 48px;
font-weight: 700;
margin-bottom: 16px;
letter-spacing: -1px;
}
.hero h1 span {
color: var(--accent);
}
.hero p {
font-size: 20px;
color: var(--text-muted);
max-width: 640px;
margin: 0 auto 32px;
}
.hero-buttons {
display: flex;
gap: 12px;
justify-content: center;
flex-wrap: wrap;
}
.btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
text-decoration: none;
transition: all 0.15s ease;
}
.btn-primary {
background: var(--accent);
color: var(--bg);
}
.btn-primary:hover {
background: var(--accent-hover);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
border-color: var(--text-muted);
}
/* Features */
.features {
padding: 60px 0;
border-bottom: 1px solid var(--border);
}
.section-title {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1.5px;
color: var(--accent);
margin-bottom: 12px;
}
.section-heading {
font-size: 32px;
font-weight: 700;
margin-bottom: 40px;
letter-spacing: -0.5px;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.feature-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 24px;
transition: border-color 0.15s ease;
}
.feature-card:hover {
border-color: var(--text-muted);
}
.feature-icon {
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
margin-bottom: 16px;
}
.feature-card h3 {
font-size: 16px;
font-weight: 600;
margin-bottom: 8px;
}
.feature-card p {
font-size: 14px;
color: var(--text-muted);
line-height: 1.5;
}
/* How it works */
.how-it-works {
padding: 60px 0;
border-bottom: 1px solid var(--border);
}
.flow {
display: flex;
flex-direction: column;
gap: 0;
position: relative;
}
.flow-step {
display: flex;
gap: 20px;
align-items: flex-start;
position: relative;
padding-bottom: 32px;
}
.flow-step:last-child {
padding-bottom: 0;
}
.flow-num {
width: 36px;
height: 36px;
min-width: 36px;
border-radius: 50%;
background: var(--surface);
border: 2px solid var(--accent);
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 700;
color: var(--accent);
position: relative;
z-index: 1;
}
.flow-step:not(:last-child) .flow-num::after {
content: '';
position: absolute;
top: 36px;
left: 50%;
transform: translateX(-50%);
width: 2px;
height: calc(100% + 0px);
background: var(--border);
}
.flow-content h4 {
font-size: 16px;
font-weight: 600;
margin-bottom: 4px;
padding-top: 6px;
}
.flow-content p {
font-size: 14px;
color: var(--text-muted);
}
/* Code block */
.quickstart {
padding: 60px 0;
border-bottom: 1px solid var(--border);
}
.code-block {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
margin-top: 8px;
}
.code-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid var(--border);
font-size: 13px;
color: var(--text-muted);
}
.code-dots {
display: flex;
gap: 6px;
}
.code-dots span {
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--border);
}
.code-body {
padding: 16px 20px;
overflow-x: auto;
}
.code-body pre {
font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
font-size: 14px;
line-height: 1.7;
color: var(--text);
}
.code-body .comment { color: var(--text-muted); }
.code-body .command { color: var(--green); }
.code-body .flag { color: var(--orange); }
.code-body .string { color: var(--accent); }
.code-body .output { color: var(--text-muted); font-style: italic; }
/* Architecture */
.architecture {
padding: 60px 0;
border-bottom: 1px solid var(--border);
}
.arch-diagram {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 0;
padding: 32px 0;
}
.arch-node {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 10px;
padding: 14px 20px;
text-align: center;
min-width: 120px;
}
.arch-node strong {
display: block;
font-size: 14px;
margin-bottom: 2px;
}
.arch-node small {
font-size: 12px;
color: var(--text-muted);
}
.arch-arrow {
color: var(--text-muted);
font-size: 20px;
padding: 0 8px;
}
.module-table {
width: 100%;
border-collapse: collapse;
margin-top: 24px;
}
.module-table th,
.module-table td {
text-align: left;
padding: 12px 16px;
border-bottom: 1px solid var(--border);
font-size: 14px;
}
.module-table th {
color: var(--text-muted);
font-weight: 600;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
}
.module-table code {
font-family: 'SF Mono', 'Fira Code', monospace;
background: var(--bg);
padding: 2px 8px;
border-radius: 4px;
font-size: 13px;
color: var(--accent);
}
.module-table td:last-child {
color: var(--text-muted);
}
/* Download */
.download {
padding: 60px 0;
border-bottom: 1px solid var(--border);
}
.download-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.download-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 28px 24px;
display: flex;
flex-direction: column;
gap: 16px;
transition: border-color 0.15s ease;
}
.download-card:hover {
border-color: var(--text-muted);
}
.download-card-header {
display: flex;
align-items: center;
gap: 12px;
}
.download-card-icon {
width: 44px;
height: 44px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
}
.download-card-header div h3 {
font-size: 16px;
font-weight: 600;
margin-bottom: 2px;
}
.download-card-header div p {
font-size: 13px;
color: var(--text-muted);
}
.download-card .btn-download {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 10px 20px;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
text-decoration: none;
background: var(--accent);
color: var(--bg);
transition: background 0.15s ease;
}
.download-card .btn-download:hover {
background: var(--accent-hover);
}
.download-card .download-meta {
font-size: 12px;
color: var(--text-muted);
}
.download-card .download-meta code {
font-family: 'SF Mono', 'Fira Code', monospace;
background: var(--bg);
padding: 2px 6px;
border-radius: 4px;
font-size: 12px;
color: var(--text-muted);
}
/* Footer */
footer {
padding: 40px 0;
text-align: center;
color: var(--text-muted);
font-size: 14px;
}
footer a {
color: var(--accent);
text-decoration: none;
}
footer a:hover {
text-decoration: underline;
}
/* Responsive */
@media (max-width: 640px) {
.hero { padding: 48px 0 40px; }
.hero h1 { font-size: 32px; }
.hero p { font-size: 16px; }
.section-heading { font-size: 24px; }
.arch-diagram { flex-direction: column; }
.arch-arrow { transform: rotate(90deg); }
}
</style>
</head>
<body>
<!-- Hero -->
<section class="hero">
<div class="container">
<div class="hero-badge">Rust · Async · Let's Encrypt</div>
<h1><span>https_proxy</span></h1>
<p>A stealth HTTPS forward proxy that auto-obtains TLS certificates and disguises itself as a normal nginx web server.</p>
<div class="hero-buttons">
<a href="https://github.com/madeye/https_proxy" class="btn btn-primary">
<svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg>
View on GitHub
</a>
<a href="https://github.com/madeye/https_proxy/releases" class="btn btn-secondary">
Download Latest
</a>
</div>
</div>
</section>
<!-- Features -->
<section class="features">
<div class="container">
<div class="section-title">Features</div>
<h2 class="section-heading">Invisible by design</h2>
<div class="feature-grid">
<div class="feature-card">
<div class="feature-icon" style="background: rgba(63,185,80,0.1); color: var(--green);">🔒</div>
<h3>Automatic TLS</h3>
<p>Certificates issued and auto-renewed via Let's Encrypt using TLS-ALPN-01. No port 80 listener needed.</p>
</div>
<div class="feature-card">
<div class="feature-icon" style="background: rgba(88,166,255,0.1); color: var(--accent);">👻</div>
<h3>Stealth Mode</h3>
<p>Non-proxy requests get an identical nginx-style 404. Proxy requests with bad auth get a standard 407 so real clients can authenticate.</p>
</div>
<div class="feature-card">
<div class="feature-icon" style="background: rgba(210,153,34,0.1); color: var(--orange);">🌐</div>
<h3>HTTP/2 Support</h3>
<p>Full HTTP/2 with extended CONNECT protocol (RFC 8441) for native browser proxy compatibility including Chrome and Firefox.</p>
</div>
<div class="feature-card">
<div class="feature-icon" style="background: rgba(188,140,255,0.1); color: var(--purple);">🔀</div>
<h3>CONNECT Tunneling</h3>
<p>Full HTTPS tunnel support via HTTP CONNECT with bidirectional streaming for proxying encrypted traffic.</p>
</div>
<div class="feature-card">
<div class="feature-icon" style="background: rgba(63,185,80,0.1); color: var(--green);">➡️</div>
<h3>HTTP Forwarding</h3>
<p>Plain HTTP proxy requests forwarded transparently to upstream servers with proxy headers stripped.</p>
</div>
<div class="feature-card">
<div class="feature-icon" style="background: rgba(248,81,73,0.1); color: var(--red);">👥</div>
<h3>Multi-User Auth</h3>
<p>Basic authentication with multiple username/password pairs. All configured in a simple YAML file.</p>
</div>
<div class="feature-card">
<div class="feature-icon" style="background: rgba(88,166,255,0.1); color: var(--accent);">🖥️</div>
<h3>TUI Setup Wizard</h3>
<p>Interactive terminal UI to generate your configuration file. No manual YAML editing required.</p>
</div>
</div>
</div>
</section>
<!-- How it works -->
<section class="how-it-works">
<div class="container">
<div class="section-title">How It Works</div>
<h2 class="section-heading">Every request goes through five gates</h2>
<div class="flow">
<div class="flow-step">
<div class="flow-num">1</div>
<div class="flow-content">
<h4>TLS Termination</h4>
<p>All connections terminate TLS with a valid Let's Encrypt certificate (HTTP/1.1 and HTTP/2). ACME challenges are handled transparently.</p>
</div>
</div>
<div class="flow-step">
<div class="flow-num">2</div>
<div class="flow-content">
<h4>Stealth Gate</h4>
<p>Requests without an absolute URI or CONNECT method are treated as probes and receive a fake nginx 404.</p>
</div>
</div>
<div class="flow-step">
<div class="flow-num">3</div>
<div class="flow-content">
<h4>Auth Gate</h4>
<p>Proxy requests with missing or invalid credentials get a 407 with <code>Proxy-Authenticate</code> header, enabling browser auth prompts.</p>
</div>
</div>
<div class="flow-step">
<div class="flow-num">4</div>
<div class="flow-content">
<h4>CONNECT Tunnel</h4>
<p>Authenticated CONNECT requests become a TCP tunnel via HTTP upgrade with bidirectional byte copying.</p>
</div>
</div>
<div class="flow-step">
<div class="flow-num">5</div>
<div class="flow-content">
<h4>HTTP Forward</h4>
<p>Authenticated HTTP requests are forwarded upstream with proxy headers stripped and URIs rewritten.</p>
</div>
</div>
</div>
</div>
</section>
<!-- Quick Start -->
<section class="quickstart">
<div class="container">
<div class="section-title">Quick Start</div>
<h2 class="section-heading">Up and running in minutes</h2>
<div class="code-block">
<div class="code-header">
<div class="code-dots"><span></span><span></span><span></span></div>
<span>Terminal</span>
</div>
<div class="code-body"><pre><span class="comment"># Build from source</span>
<span class="command">cargo build</span> <span class="flag">--release</span>
<span class="comment"># Generate config interactively</span>
<span class="command">./target/release/https_proxy</span> <span class="flag">setup</span>
<span class="comment"># Or copy the example config</span>
<span class="command">cp</span> config.example.yaml config.yaml
<span class="comment"># Start the proxy</span>
<span class="command">./target/release/https_proxy</span> <span class="flag">run</span></pre></div>
</div>
<div class="code-block" style="margin-top: 20px;">
<div class="code-header">
<div class="code-dots"><span></span><span></span><span></span></div>
<span>Usage</span>
</div>
<div class="code-body"><pre><span class="comment"># Use as HTTPS proxy</span>
<span class="command">curl</span> <span class="flag">--proxy</span> <span class="string">https://alice:hunter2@proxy.example.com:443</span> https://httpbin.org/ip
<span class="comment"># Probe the server directly — looks like nginx</span>
<span class="command">curl</span> <span class="string">https://proxy.example.com/</span>
<span class="output"># => 404 Not Found (Server: nginx/1.24.0)</span>
<span class="comment"># Wrong credentials — 407 auth challenge (enables browser auth prompts)</span>
<span class="command">curl</span> <span class="flag">--proxy</span> <span class="string">https://wrong:creds@proxy.example.com:443</span> https://example.com
<span class="output"># => 407 Proxy Authentication Required</span></pre></div>
</div>
</div>
</section>
<!-- Architecture -->
<section class="architecture">
<div class="container">
<div class="section-title">Architecture</div>
<h2 class="section-heading">Clean, modular Rust</h2>
<div class="arch-diagram">
<div class="arch-node"><strong>Client</strong><small>HTTPS</small></div>
<div class="arch-arrow">→</div>
<div class="arch-node"><strong>TLS</strong><small>tls.rs</small></div>
<div class="arch-arrow">→</div>
<div class="arch-node"><strong>Stealth</strong><small>stealth.rs</small></div>
<div class="arch-arrow">→</div>
<div class="arch-node"><strong>Auth</strong><small>auth.rs</small></div>
<div class="arch-arrow">→</div>
<div class="arch-node"><strong>Proxy</strong><small>proxy.rs</small></div>
<div class="arch-arrow">→</div>
<div class="arch-node"><strong>Target</strong><small>upstream</small></div>
</div>
<table class="module-table">
<thead>
<tr><th>Module</th><th>Role</th></tr>
</thead>
<tbody>
<tr><td><code>tls.rs</code></td><td>ACME acceptor, automatic cert provisioning and renewal</td></tr>
<tr><td><code>stealth.rs</code></td><td>Detects proxy vs. normal requests; generates fake nginx responses</td></tr>
<tr><td><code>auth.rs</code></td><td>Validates Proxy-Authorization Basic credentials</td></tr>
<tr><td><code>proxy.rs</code></td><td>CONNECT tunneling and HTTP request forwarding</td></tr>
<tr><td><code>config.rs</code></td><td>YAML config loading and validation</td></tr>
<tr><td><code>setup.rs</code></td><td>Interactive TUI setup wizard</td></tr>
</tbody>
</table>
</div>
</section>
<!-- Download -->
<section class="download">
<div class="container">
<div class="section-title">Download</div>
<h2 class="section-heading">Prebuilt binaries — v0.2.0</h2>
<div class="download-grid">
<div class="download-card">
<div class="download-card-header">
<div class="download-card-icon" style="background: rgba(88,166,255,0.1); color: var(--accent);">🍎</div>
<div>
<h3>macOS (ARM64)</h3>
<p>Apple Silicon — M1, M2, M3, M4</p>
</div>
</div>
<a href="https://github.com/madeye/https_proxy/releases/download/v0.2.0/https_proxy-v0.2.0-darwin-arm64.zip" class="btn-download">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"/><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"/></svg>
Download .zip
</a>
<div class="download-meta"><code>https_proxy-v0.2.0-darwin-arm64.zip</code></div>
</div>
<div class="download-card">
<div class="download-card-header">
<div class="download-card-icon" style="background: rgba(63,185,80,0.1); color: var(--green);">🐧</div>
<div>
<h3>Linux (x86_64)</h3>
<p>GNU/Linux — AMD64 / Intel 64</p>
</div>
</div>
<a href="https://github.com/madeye/https_proxy/releases/download/v0.2.0/https_proxy-v0.2.0-linux-amd64.zip" class="btn-download">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"/><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"/></svg>
Download .zip
</a>
<div class="download-meta"><code>https_proxy-v0.2.0-linux-amd64.zip</code></div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer>
<div class="container">
<p>
<a href="https://github.com/madeye/https_proxy">GitHub</a> ·
<a href="https://github.com/madeye/https_proxy/releases">Releases</a> ·
MIT License
</p>
</div>
</footer>
</body>
</html>