Raven Scott e5a1fa71fe
CI / Build & Test (push) Successful in 3m21s
fix: comprehensive bug fixes, security improvements, and feature additions
Critical fixes:
- Fix wrong registry key (com.bridgeswarm → com.holesail.browser) in
  update-native-manifest-extension-id.ps1 — script was always failing on Windows
- Create missing wrong-domain.html redirect page for .host.test URLs
- Remove options_ui pointing to non-existent options.html from manifest

High-priority bug fixes:
- ssh-manager: track and kill orphaned printf FIFO writer when key auth succeeds
- ssh-manager: fix uncancelled 2000ms fallback password timer (assign to fallbackTimer,
  clear in cancelPasswordWatch); fix null-check before removeAllListeners
- ssh-manager: add 30s Promise.race timeout to holesailInst.ready()
- backup-manager: fix macOS cp -R nesting bug by removing destination before copy;
  add tar -tzf integrity check after archive creation
- host.js: restoreBackup now stops running tunnels before restore and re-starts them
- holesail-manager: fix stale closure bug in virtual host and service tunnel
  error/close handlers (guard with v.holesail === hs check)
- dashboard.js: remove dead setText('dashTabs', ...) call referencing non-existent element

Medium improvements:
- manifest: remove unused storage and scripting permissions; restrict
  web_accessible_resources match from <all_urls> to chrome-extension://*/*
- background.js: fix self-referential browser alias (globalThis.browser ?? chrome);
  add 30s per-request timeout to send(); clean up dashboardTabs on tab close
- holesail-manager: gate saveStateSync stderr log behind DEBUG flag; updateSettings
  now returns requiresRestart:true when proxy port changes; add backupRetention field
- host.js: pass requiresRestart through in updateSettings response
- dashboard.js: remove dead loadSettings() function; add requiresRestart warning toast;
  add chrome.runtime.lastError guards in fetchState and refreshBackups;
  set dynamic version from chrome.runtime.getManifest()
- dashboard.html: remove stray </button> tag; add id="sidebarVersion" for dynamic version
- install.sh/install.ps1: fetch version from RELEASE_BASE/VERSION instead of hardcoded 1.0.0
- install.ps1: add Firefox .xpi download and Firefox registry key
- update-native-manifest-extension-id.sh: add optional Firefox manifest update
- certificate-authority.js: defer RSA key generation to setImmediate to avoid blocking
  startup; expose caReady promise
- host.js: await caReady before starting HTTPS proxy

Documentation:
- REMOTE-DESKTOP.md: correct RDP WebSocket protocol field names to match rdp-manager.js
  (destLeft/destTop/destRight/destBottom, mouseMove/mouseButton/keyEvent/keyUnicode)

Feature additions:
- dashboard.js: add Reconnect button for service tunnels in error/closed state
- https-proxy.js: add WebSocket upgrade handler to support ws:// over *.hole.sail
- connect-proxy.js: add 10s header-read timeout to protect against idle connections
- native-host: add bare-fs as explicit dependency
2026-02-28 19:00:13 -05:00
2026-02-27 18:49:12 -05:00
2026-02-27 18:13:59 -05:00
2026-02-27 18:13:59 -05:00
2026-02-27 18:13:59 -05:00

Holesail Browser

Browse P2P Holesail tunnels directly in your browser. Holesail Browser is a Chrome/Firefox extension paired with a native host that routes *.hole.sail domains through Holesail tunnels — with automatic TLS, no port-forwarding, and no central servers.

How it works

  1. You add a virtual host in the dashboard: myapp.hole.sailhs://abc123...
  2. The extension sets a PAC script that routes *.hole.sail → local CONNECT proxy (port 8442)
  3. The CONNECT proxy pipes the raw TLS stream to the HTTPS proxy (port 8443)
  4. The HTTPS proxy terminates TLS (using a locally-trusted wildcard cert) and forwards HTTP to the Holesail tunnel
  5. The Holesail tunnel connects P2P to the remote peer over the DHT

All traffic is end-to-end encrypted via the Noise protocol. The local CA is only used for the browser↔proxy TLS leg.

Features

  • Virtual Hosts — browse any hs:// URL as https://name.hole.sail/
  • Server Tunnels — expose a local port as an hs:// key (TCP or UDP)
  • Service Tunnels — forward a remote hs:// peer to a local TCP port
  • SSH — in-browser SSH terminal via xterm.js, over a Holesail tunnel
  • Remote Desktop — VNC (noVNC) and RDP viewer in the browser, over a Holesail tunnel
  • Backupstar.gz snapshots of all state and certificates, with configurable retention
  • Auto CA — generates and installs a local root CA; signs a wildcard *.hole.sail cert
  • Persistent state — all tunnels, connections, and settings survive restarts

Installation

curl -fsSL https://git.ssh.surf/snxraven/holesail-browser/raw/branch/main/scripts/web-installer.sh | bash

Windows

Download and run the PowerShell installer:

irm https://git.ssh.surf/snxraven/holesail-browser/raw/branch/main/scripts/install.ps1 | iex

Or download install.ps1 from the latest release and run it manually.

What the installer does

  1. Downloads the pre-built native host binary for your platform from the latest release
  2. Installs it to ~/.holesail-browser/ (macOS/Linux) or %LOCALAPPDATA%\holesail-browser\ (Windows)
  3. Writes the native messaging manifest so Chrome/Firefox can find it
  4. Downloads the extension .zip (Chrome) and .xpi (Firefox) to ~/Downloads
  5. On macOS: removes Gatekeeper quarantine and ad-hoc signs the binary and native addons

Loading the extension

Chrome / Edge

  1. Open chrome://extensions
  2. Enable Developer mode (top right)
  3. Drag ~/Downloads/Holesail-Browser-1.0.0.zip onto the page
    (or click Load unpacked after extracting the zip)

Firefox (regular)

Firefox requires extensions to be signed by Mozilla for permanent installation. Use the temporary add-on loader instead:

  1. Open about:debugging
  2. Click This Firefox
  3. Click Load Temporary Add-on...
  4. Select ~/Downloads/Holesail-Browser-1.0.0.zip (or any file inside the extracted folder)

Note: Temporary add-ons are removed when Firefox restarts. You will need to reload it each time.

Firefox Developer Edition / Nightly (permanent, unsigned)

Developer Edition and Nightly allow disabling signature enforcement:

  1. Open about:config → search for xpinstall.signatures.required → set it to false
  2. Open about:addons → gear icon → Install Add-on From File
  3. Select ~/Downloads/Holesail-Browser-1.0.0.xpi

Firefox (permanent, signed)

For a permanent install in regular Firefox, the extension must be signed by Mozilla via addons.mozilla.org. Self-hosted distribution (no public listing required) is available — see docs/INSTALLATION.md for details.

First run

  1. Click the Holesail Browser icon in your toolbar to open the dashboard
  2. Go to Proxy & CA → click Install Root CA
  3. Fully quit and reopen Chrome (Cmd+Q on macOS) for the CA trust to take effect
  4. Go to Virtual Hosts → add a hostname and hs:// key
  5. Navigate to https://your-hostname.hole.sail/

Note: The CA must be installed and Chrome must be restarted before *.hole.sail sites will load without a certificate warning.

Dashboard pages

Page Description
Overview Status summary, connection count, proxy ports
Virtual Hosts Map hs:// keys to *.hole.sail hostnames
Server Tunnels Expose local ports as hs:// keys (TCP/UDP)
Service Tunnels Forward remote hs:// peers to local TCP ports
Proxy & CA Proxy port settings, CA install/status
SSH In-browser SSH terminal over Holesail
Remote Desktop VNC/RDP viewer over Holesail
Backups Create, restore, and manage backups
Logs Live log stream from the native host
Settings Proxy ports, timeouts, notifications, debug mode

File locations

Path Description
~/.holesail-browser/holesail-browser-host Native host binary
~/.holesail-browser/holesail-browser-storage/state.json All persistent state
~/.holesail-browser/holesail-browser-certs/ CA and domain certificates
~/.holesail-browser/holesail-browser.log Native host log file
~/.holesail-browser/holesail-browser-storage/backups/ Backup archives

Troubleshooting

*.hole.sail sites show a certificate error

The root CA is not trusted, or Chrome was not restarted after installing it. Open the dashboard → Proxy & CA and check the CA status. If it shows "Not Installed", click Install Root CA, then fully quit and reopen Chrome (Cmd+Q).

If the CA shows "Installed" but you still see errors, the keychain may have a stale entry from a previous installation. Click Install Root CA again — it will detect the mismatch, remove the old entry, and install the correct one.

No tunnel for this hostname

The native host has no active tunnel for that hostname. Possible causes:

  • The tunnel is still connecting — wait a few seconds and refresh
  • The native host was restarted and is reconnecting — open the dashboard to check
  • The hostname in the dashboard doesn't exactly match what you're browsing

Native host not connecting / hostConnected: false

  • Make sure you haven't started holesail-browser-host manually from a terminal — only Chrome should spawn it via native messaging
  • Check ~/.holesail-browser/holesail-browser.log for errors
  • Try reloading the extension at chrome://extensions

macOS: "Apple cannot verify..." / Gatekeeper warning

Run the installer again — it handles quarantine removal and ad-hoc signing automatically. If you moved the binary manually, run:

xattr -rd com.apple.quarantine ~/.holesail-browser/holesail-browser-host
codesign --force --sign - ~/.holesail-browser/holesail-browser-host

Access to the specified native messaging host is forbidden

The extension ID in the native messaging manifest doesn't match the installed extension. Re-run the installer, or manually update the allowed_origins field in the manifest JSON to match the extension ID shown in chrome://extensions.

Building from source

git clone https://git.ssh.surf/snxraven/holesail-browser
cd holesail-browser
npm install
cd native-host && npm install && cd ..

# Build extension
npm run pack

# Build native host binary for current platform
npm run build:dist

# Build for all platforms
npm run build:dist:all

The built extension will be in releases/Holesail-Browser-*.zip and .xpi. Platform binaries will be in releases/<platform>-<arch>/.

Platform support

Platform Architecture Binary
macOS Apple Silicon (arm64) darwin-arm64
macOS Intel (x64) darwin-x64
Linux x64 linux-x64
Linux ARM64 linux-arm64
Windows x64 win32-x64 (.exe)

Documentation

License

MIT

S
Description
No description provided
Readme
223 MiB
Languages
JavaScript 76.6%
HTML 13.8%
CSS 6.7%
Shell 1.8%
PowerShell 1.1%