Merge ship/mirrors-and-cf: branded error pages and the mirrors docs
These three commits were pushed to the forge's theseus and site repos from their branch but never reached master, so pushing master would have dropped them there. Merged so master carries them: the branded error page on BCNR-to-clearnet fallback failures, the Cloudflare Bot Fight 503 hint with a .bch mirror suggestion, and the site's docs page for the p-record reverse-proxy workaround.
This commit is contained in:
commit
c8ab0e239b
2 changed files with 201 additions and 0 deletions
194
mirrors/index.html
Normal file
194
mirrors/index.html
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Mirrors — Silent Mode</title>
|
||||
<meta name="description" content="Cloudflare's Bot Fight Mode fingerprints Electron's TLS handshake and blocks Theseus with HTTP 503. BNS `p` records reverse-proxy the request through Node's HTTP stack, bypassing the fingerprint — Theseus renders the page under a .bch name.">
|
||||
<link rel="stylesheet" href="../shared.css">
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<style>
|
||||
.mirror-list{display:grid;gap:10px;margin:1rem 0 1.4rem}
|
||||
.mirror{
|
||||
display:grid;grid-template-columns:1fr auto;gap:14px;align-items:center;
|
||||
background:var(--panel);border:1px solid var(--line);border-radius:12px;
|
||||
padding:14px 18px;
|
||||
}
|
||||
.mirror .row1{font:600 15px/1.35 ui-monospace,monospace;color:var(--acid)}
|
||||
.mirror .row2{color:var(--mut);font-size:12.5px;margin-top:3px;
|
||||
font-family:ui-monospace,monospace;word-break:break-all}
|
||||
.mirror .badge{
|
||||
font:600 10.5px/1 system-ui;letter-spacing:.18em;text-transform:uppercase;
|
||||
color:var(--acid);background:rgba(214,255,61,.10);
|
||||
border:1px solid rgba(214,255,61,.28);padding:5px 9px;border-radius:999px;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.empty-note{
|
||||
color:var(--mut);font-size:13px;padding:14px 16px;
|
||||
background:var(--panel2);border:1px dashed var(--line);border-radius:10px;
|
||||
}
|
||||
code.k{font-family:ui-monospace,monospace;background:var(--panel2);
|
||||
padding:1px 6px;border-radius:5px;color:var(--acid)}
|
||||
.step{display:flex;gap:14px;padding:12px 0}
|
||||
.step + .step{border-top:1px solid var(--line)}
|
||||
.step .n{flex:none;width:26px;height:26px;border-radius:999px;
|
||||
background:rgba(214,255,61,.10);color:var(--acid);
|
||||
display:grid;place-items:center;font:600 12px/1 system-ui}
|
||||
.step .b{color:var(--mut);font-size:14px;line-height:1.6}
|
||||
.step .b b{color:var(--ink)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="topnav">
|
||||
<a class="brand" href="./"><svg class="logo" viewBox="0 0 32 20" aria-hidden="true"><rect class="l1" x="1.5" y="3.5" width="17" height="13" rx="6.5" ry="6.5" fill="none" stroke-width="2.6"/><rect class="l2" x="13.5" y="3.5" width="17" height="13" rx="6.5" ry="6.5" fill="none" stroke-width="2.6"/></svg>Silent <span class="g">Mode</span></a>
|
||||
<a href="theseus">Theseus</a>
|
||||
<a href="prometheus">Prometheus</a>
|
||||
<a href="sirius">Sirius</a>
|
||||
<a href="hephaestus">Hephaestus</a>
|
||||
<a href="helios">Helios</a>
|
||||
<a href="hermes">Hermes</a>
|
||||
<a href="tools">Tools</a>
|
||||
</nav>
|
||||
|
||||
<header class="hero">
|
||||
<h1>Reverse-proxy <span class="g">mirrors</span></h1>
|
||||
<p class="tag">Some sites — including several of the most-cited pages in the Bitcoin
|
||||
Cash ecosystem — return <b>HTTP 503</b> to Theseus, no matter what user-agent it sends.
|
||||
A short note on why, and how a <code class="inline">.bch</code> name gets you through.</p>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
<!-- ============ WHAT'S HAPPENING ============ -->
|
||||
<section>
|
||||
<h2>Why Theseus 503s on some sites</h2>
|
||||
<p class="lede">Cloudflare's Bot Fight Mode (and similar WAF rules) fingerprints the
|
||||
<b>TLS ClientHello</b> — the cipher list, extensions, and JA3/JA4 hash your browser
|
||||
sends before any HTTP header is negotiated. Chromium's TLS stack, which Theseus is
|
||||
built on via Electron, ships with a slightly different fingerprint than desktop
|
||||
Chrome — enough to trigger the bot heuristic. The server replies with a short
|
||||
503 page and the load fails.</p>
|
||||
<p class="lede">Stripping <code class="inline">Electron/…</code> from the user-agent
|
||||
doesn't help: the fingerprint sits below HTTP. Disabling HTTP/2 doesn't help either.
|
||||
From the site's perspective, Theseus is indistinguishable from a scraper.</p>
|
||||
</section>
|
||||
|
||||
<!-- ============ THE FIX ============ -->
|
||||
<section>
|
||||
<h2>What a <code class="inline">p</code> record does</h2>
|
||||
<p class="lede">A BCDN name can carry a <code class="inline">p</code> record — a
|
||||
single upstream URL. When Theseus loads a name whose record picker returns
|
||||
<code class="inline">p</code>, it doesn't hand the request to Chromium's network
|
||||
stack. It hands it to <b>Node's <code class="inline">fetch()</code></b> from the
|
||||
main process, which uses a different HTTP client (undici) with a completely
|
||||
different TLS fingerprint — one Cloudflare doesn't flag. The response body comes
|
||||
back and gets served under the <code class="inline">.bch</code> origin.</p>
|
||||
<p class="lede">The address bar stays on the BNS name; the upstream never sees your
|
||||
IP resolve through Cloudflare's browser-bot rules, only through Theseus's outbound
|
||||
Node fetch. No captcha, no interstitial, no 503.</p>
|
||||
<p class="lede">Trade-offs to know: the <code class="inline">p</code> path uses the
|
||||
upstream's own DNS and public certificate authority (unlike <code class="inline">ip</code>,
|
||||
which pins to a raw IP + on-chain TLS fingerprint), and Theseus streams the body
|
||||
through its own process — so the upstream sees Theseus's outbound IP, not yours.
|
||||
This is a shared proxy in effect, though only for the one request.</p>
|
||||
</section>
|
||||
|
||||
<!-- ============ FEATURED MIRRORS ============ -->
|
||||
<section>
|
||||
<h2>Featured mirrors</h2>
|
||||
<p class="lede">These names are registered on the Bitcoin Cash chain with a
|
||||
<code class="inline">p</code> record pointing at a Cloudflare-fronted upstream
|
||||
Theseus can't reach directly. Click any to open it in Theseus (or via
|
||||
<a href="https://navigate.st/">navigate.st</a> if you don't have the browser
|
||||
installed yet).</p>
|
||||
|
||||
<div class="mirror-list" id="mirror-list">
|
||||
<!-- Populated at ship time. Keep entries in sync with site/home-cards.json's
|
||||
"Mirrored" section so the home tiles and this page tell the same story. -->
|
||||
<div class="empty-note">
|
||||
<b>No mirrors published yet.</b> The list will fill in as names are minted
|
||||
through Sirius. Check back, or mint one yourself — instructions below.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="lede" style="margin-top:1.2rem">
|
||||
<b>See a site missing?</b> If a Cloudflare-fronted page you care about is
|
||||
unreachable from Theseus, either mint a <code class="inline">p</code> record for
|
||||
it yourself, or open an issue on
|
||||
<a href="https://code.silentmode.st/silentmode/theseus">the Theseus repo</a> and
|
||||
we'll add it to the featured list once it's on chain.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ============ DIY ============ -->
|
||||
<section>
|
||||
<h2>Mint a mirror yourself</h2>
|
||||
<p class="lede">Registration costs a few sats of BCH. Theseus 0.3.14+ ships with the
|
||||
<b>Aegis wallet</b> — the wallet the Sirius UI signs against — so this is a couple
|
||||
of clicks once your wallet has a small balance.</p>
|
||||
|
||||
<div>
|
||||
<div class="step">
|
||||
<div class="n">1</div>
|
||||
<div class="b">Open <a href="https://sirius.x/">sirius.x</a> in Theseus and search
|
||||
for the label you want. Pick a <code class="k">.bch</code> TLD if the site is
|
||||
BCH-related; other registered TLDs work too. Mint the name.</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="n">2</div>
|
||||
<div class="b">Once minted, open the name's record editor and add:
|
||||
<br><code class="k">p: "https://the-original-upstream.example/"</code>
|
||||
<br>The trailing slash matters — anything in the path is used as a prefix
|
||||
for every request.</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="n">3</div>
|
||||
<div class="b">Sign the record change. Wait one confirmation. The record is live
|
||||
as soon as the next Theseus resolve fetches the beacon.</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="n">4</div>
|
||||
<div class="b">Test: type <code class="k">yourname.bch</code> in Theseus's address
|
||||
bar. If the upstream returns 200, Theseus renders it under your name. Send us
|
||||
the name and we'll add it to the featured list.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note" style="margin-top:1.4rem">
|
||||
<b>Be honest about what a mirror is.</b> The upstream is unchanged — the site
|
||||
operator hasn't consented to being served under your BNS name, and doesn't get
|
||||
paid for any traffic that lands through the mirror. This is a workaround for a
|
||||
reachability problem, not a rehosting. If you'd rather leave the mirror to us,
|
||||
open an issue and we'll consider whether it's canonical enough to include.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ TECHNICAL DETAIL ============ -->
|
||||
<section>
|
||||
<h2>The relevant code</h2>
|
||||
<p class="lede">For anyone curious about the exact mechanism:</p>
|
||||
<ul style="color:var(--mut);font-size:14px;line-height:1.7;padding-left:1.2rem">
|
||||
<li>Record priority — <code class="inline">pickRecord()</code> in Argus:
|
||||
<code class="inline">h > s3 > ip > p > u</code> at the apex, and
|
||||
subdomain inheritance never picks <code class="inline">p</code>. Theseus
|
||||
carries an inline copy to keep in step.</li>
|
||||
<li>Theseus proxy pipeline — <a href="https://code.silentmode.st/silentmode/theseus/src/branch/master/main.js"><code class="inline">theseus/main.js</code></a>,
|
||||
the <code class="inline">serveP</code> closure inside <code class="inline">serveBns()</code>.
|
||||
Uses <code class="inline">fetch(target, { redirect: "manual" })</code>
|
||||
from the main process, which is Node's undici — a different TLS stack from
|
||||
Chromium's, and the reason the fingerprint check doesn't fire.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div>Silent Mode — a Deviant project.</div>
|
||||
<div class="fine">Mirrors are provided as-is. The upstream site's terms and privacy
|
||||
policy still apply — a <code class="inline">.bch</code> name changes only how the
|
||||
bytes reach you, not who wrote them.</div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -189,6 +189,13 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note" style="border-left-color:var(--acid)"><b>Some sites 503 in Theseus.</b>
|
||||
Cloudflare's Bot Fight Mode fingerprints Electron's TLS handshake and blocks it, no
|
||||
matter what user-agent Theseus sends. The workaround is a BCDN
|
||||
<code class="inline">p</code> record that reverse-proxies the site through Node's
|
||||
HTTP stack — see <a href="../mirrors">Reverse-proxy mirrors</a> for the featured
|
||||
list and how to mint your own.</div>
|
||||
|
||||
<div class="note"><b>Not in a store.</b> Neither version is on the Microsoft Store,
|
||||
Google Play or the App Store. Distributing there requires a legal identity and the
|
||||
store's permission, the two things this project exists to do without. You will have
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue