Files
peardock-website/docs/holesail.html
T
2026-07-11 19:13:34 -04:00

219 lines
10 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>Holesail tunnels · PearDock Docs</title>
<meta name="description" content="Holesail P2P tunnels in PearDock: reach published services without opening firewall ports. Architecture, RPC, security." />
<meta name="keywords" content="Holesail, PearDock tunnels, hs://, P2P ports" />
<meta name="author" content="HoneyPeer, LLC" />
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
<meta name="googlebot" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
<meta name="theme-color" content="#2dd4bf" />
<meta name="color-scheme" content="dark light" />
<meta name="application-name" content="PearDock" />
<meta name="apple-mobile-web-app-title" content="PearDock" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="msapplication-TileColor" content="#2dd4bf" />
<meta name="msapplication-config" content="/assets/favicons/browserconfig.xml" />
<meta name="format-detection" content="telephone=no" />
<link rel="canonical" href="https://peardock.boats/docs/holesail" />
<link rel="alternate" hreflang="en" href="https://peardock.boats/docs/holesail" />
<link rel="alternate" hreflang="x-default" href="https://peardock.boats/docs/holesail" />
<!-- Open Graph -->
<meta property="og:type" content="article" />
<meta property="og:site_name" content="PearDock" />
<meta property="og:locale" content="en_US" />
<meta property="og:url" content="https://peardock.boats/docs/holesail" />
<meta property="og:title" content="Holesail tunnels · PearDock Docs" />
<meta property="og:description" content="Holesail P2P tunnels in PearDock: reach published services without opening firewall ports. Architecture, RPC, security." />
<meta property="og:image" content="https://peardock.boats/assets/brand/og-image.png" />
<meta property="og:image:secure_url" content="https://peardock.boats/assets/brand/og-image.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="PearDock: decentralized Docker management on HyperDHT" />
<!-- Twitter / X -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Holesail tunnels · PearDock Docs" />
<meta name="twitter:description" content="Holesail P2P tunnels in PearDock: reach published services without opening firewall ports. Architecture, RPC, security." />
<meta name="twitter:image" content="https://peardock.boats/assets/brand/twitter-card.png" />
<meta name="twitter:image:alt" content="PearDock: decentralized Docker management" />
<!-- Icons & PWA -->
<link rel="icon" href="/assets/favicons/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png" />
<link rel="icon" type="image/png" sizes="48x48" href="/assets/favicons/favicon-48x48.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/assets/favicons/apple-touch-icon.png" />
<link rel="manifest" href="/assets/favicons/site.webmanifest" />
<link rel="mask-icon" href="/assets/logo/peardock-wordmark.svg" color="#2dd4bf" />
<!-- Article -->
<meta property="article:section" content="Documentation" />
<meta property="article:author" content="HoneyPeer, LLC" />
<meta property="article:publisher" content="HoneyPeer, LLC" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": [
"WebPage",
"TechArticle"
],
"name": "Holesail tunnels \u00b7 PearDock Docs",
"description": "Holesail P2P tunnels in PearDock: reach published services without opening firewall ports. Architecture, RPC, security.",
"url": "https://peardock.boats/docs/holesail",
"isPartOf": {
"@type": "WebSite",
"name": "PearDock",
"url": "https://peardock.boats"
},
"publisher": {
"@type": "Organization",
"name": "HoneyPeer, LLC",
"url": "https://peardock.boats"
},
"inLanguage": "en-US",
"primaryImageOfPage": {
"@type": "ImageObject",
"url": "https://peardock.boats/assets/brand/og-image.png",
"width": 1200,
"height": 630
},
"headline": "Holesail tunnels \u00b7 PearDock Docs"
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/src/styles/global.css" />
<link rel="stylesheet" href="/src/styles/docs.css" />
</head>
<body>
<div class="bg-mesh" aria-hidden="true"></div>
<div data-nav data-prefix="../"></div>
<div class="docs-layout">
<aside class="docs-sidebar" data-docs-nav data-prefix="../"></aside>
<button type="button" class="docs-sidebar-toggle" aria-label="Docs menu"></button>
<article class="docs-main">
<h1>Holesail tunnels</h1>
<p class="docs-lead">
<a href="https://github.com/holesail/holesail" target="_blank" rel="noopener">Holesail</a>
is a peer-to-peer TCP/UDP reverse proxy on HyperDHT. PearDock uses it <strong>beside</strong>
the Docker control plane so you can share published services via <code>hs://</code> keys.
<strong>No open ports, no inbound firewall rules, no “expose this to the internet” step.</strong>
</p>
<h2>Do not conflate the two planes</h2>
<pre class="mermaid">
flowchart LR
subgraph Control["Control plane"]
CLI[Client RPC]
SRV[Server handlers]
CLI -- "protomux-rpc" --> SRV
SRV --> DK[Docker]
end
subgraph Data["Data plane"]
HS[HolesailServer]
HC[Holesail client]
HC -- "hs:// P2P" --> HS
HS --> PT["host:port"]
end
Control -.->|"orthogonal · not a replacement"| Data
</pre>
<div class="table-wrap">
<table>
<thead>
<tr><th>Plane</th><th>Technology</th><th>Purpose</th></tr>
</thead>
<tbody>
<tr><td>Control</td><td>HyperDHT + protomux-rpc</td><td>Docker RPC, ACL, logs, deploy</td></tr>
<tr><td>Data / tunnels</td><td>Holesail</td><td>L4 proxy host:port ↔ remote peer</td></tr>
</tbody>
</table>
</div>
<h2>Enable / disable</h2>
<p>Holesail tunnels are <strong>enabled by default</strong>. The <code>holesail</code> package is a required dependency.</p>
<pre><code># default: tunnels on
npm run server
# opt out
export ENABLE_HOLESAIL=0
npm run server</code></pre>
<div class="table-wrap">
<table>
<thead>
<tr><th>Variable</th><th>Default</th><th>Meaning</th></tr>
</thead>
<tbody>
<tr><td><code>ENABLE_HOLESAIL</code></td><td>on</td><td>Set 0 / false / off / no to disable</td></tr>
<tr><td><code>PEARDOCK_MAX_TUNNELS</code></td><td>20</td><td>Concurrent tunnel cap</td></tr>
<tr><td><code>PEARDOCK_TUNNEL_HOSTS</code></td><td>loopback + 0.0.0.0</td><td>Allowed tunnel targets (SSRF guard)</td></tr>
</tbody>
</table>
</div>
<h2>RPC</h2>
<div class="table-wrap">
<table>
<thead>
<tr><th>Method</th><th>Role</th><th>Description</th></tr>
</thead>
<tbody>
<tr><td><code>getHolesailStatus</code></td><td>viewer</td><td>Feature flag + availability</td></tr>
<tr><td><code>listTunnels</code></td><td>viewer</td><td>Active tunnels (+ hs:// URLs)</td></tr>
<tr><td><code>getTunnel</code></td><td>viewer</td><td>One tunnel by id</td></tr>
<tr><td><code>createTunnel</code></td><td>operator</td><td>Start tunnel (host/port or container + port)</td></tr>
<tr><td><code>closeTunnel</code></td><td>operator</td><td>Stop tunnel</td></tr>
</tbody>
</table>
</div>
<p><code>createTunnel</code> uses <strong>secure</strong> mode by default so the DHT capability is not the raw listen key.</p>
<h2>UI</h2>
<p>Sidebar → <strong>Tunnels</strong>: create by host/port, list active tunnels, copy <code>hs://</code> URL, close.</p>
<p>Remote connect (outside PearDock):</p>
<pre><code>npx holesail 'hs://s000…'
# then open http://127.0.0.1:&lt;bound-port&gt;</code></pre>
<h2>Security</h2>
<ul>
<li>Treat <code>hs://</code> URLs as <strong>secrets</strong> (capability to reach the service).</li>
<li>Default targets are loopback / published Docker binds only.</li>
<li>Create/close are audited when <code>PEARDOCK_AUDIT</code> is on.</li>
<li>Max tunnel count limits resource exhaustion.</li>
<li>Do <strong>not</strong> reuse <code>SERVER_SEED</code> for tunnel keypairs. Each tunnel gets its own Holesail seed.</li>
</ul>
<h2>License note</h2>
<div class="callout warn">
<div class="callout-icon">!</div>
<div class="callout-body">
<code>holesail</code> is a required dependency.
PearDock and Holesail are both <strong>AGPL-3.0</strong>.
Operators of modified network servers should review AGPL source-offer obligations.
Set <code>ENABLE_HOLESAIL=0</code> if you must run without opening tunnels (package still installed).
</div>
</div>
<div class="docs-pager">
<a href="/docs/operator"><span>Previous</span><strong>← Operator</strong></a>
<a class="next" href="/docs/security"><span>Next</span><strong>Security →</strong></a>
</div>
</article>
</div>
<div data-footer data-prefix="../"></div>
<script type="module" src="/src/js/site.js"></script>
</body>
</html>