Caddy now serves both :80 (plain HTTP, unchanged default) and :443 with tls internal — it generates its own per-box root CA on first start, stored under /var/lib/caddy/.local/share/caddy/pki/authorities/local/. Users can download rootCA.crt at /rootCA.crt (served on both listeners) and install it per-OS via the new /https-install/ guide. Settings page grows a Local HTTPS card with CA fingerprint, download button, reachability probe, and an opt-in "force HTTPS" toggle. The toggle only unhides itself once the current browser already trusts the cert, so enabling it can't lock the user out of the settings page. Backend: GET /api/furtka/https/status and POST /api/furtka/https/force in furtka.https. The force toggle drops a Caddy import snippet into /etc/caddy/furtka.d/redirect.caddyfile and reloads Caddy; reload failure rolls the snippet state back so a bad config can't wedge the next service start. updater._refresh_caddyfile() ensures /etc/caddy/furtka.d exists before every reload so 26.3-alpha → 26.4-alpha self-updates don't trip on the new glob import directive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
159 lines
6.7 KiB
HTML
159 lines
6.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Install local HTTPS · Furtka</title>
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<link rel="stylesheet" href="/style.css">
|
|
</head>
|
|
<body>
|
|
<main class="wrap">
|
|
<nav class="nav">
|
|
<a class="brand" href="/">Furtka</a>
|
|
<div class="nav-links">
|
|
<a href="/">Home</a>
|
|
<a href="/apps">Apps</a>
|
|
<a href="/settings/" aria-current="page">Settings</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<h1>Install local HTTPS</h1>
|
|
<p class="lede">
|
|
Trust the Furtka root CA on your device, then reach this box at
|
|
<code>https://<span id="hostname">—</span>/</code> with a green padlock.
|
|
HTTP stays available until you enable the redirect in
|
|
<a class="inline-link" href="/settings/">Settings</a>.
|
|
</p>
|
|
|
|
<section>
|
|
<h2>Download the CA</h2>
|
|
<div class="card">
|
|
<dl class="kv">
|
|
<dt>Fingerprint (SHA-256)</dt><dd id="fingerprint">—</dd>
|
|
</dl>
|
|
<p class="hint">
|
|
Check this fingerprint matches what <code>/settings</code> shows before
|
|
trusting it on another device. The root CA is unique to this box.
|
|
</p>
|
|
<div class="update-actions">
|
|
<button id="download-btn" class="secondary">Download rootCA.crt</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Linux (system-wide)</h2>
|
|
<div class="card">
|
|
<p class="hint">Arch / Fedora / RHEL:</p>
|
|
<pre>sudo cp rootCA.crt /etc/ca-certificates/trust-source/anchors/furtka-local.crt
|
|
sudo update-ca-trust</pre>
|
|
<p class="hint">Debian / Ubuntu:</p>
|
|
<pre>sudo cp rootCA.crt /usr/local/share/ca-certificates/furtka-local.crt
|
|
sudo update-ca-certificates</pre>
|
|
<p class="hint">
|
|
Firefox keeps its own certificate store. After the above, open
|
|
<code>about:preferences#privacy</code> → <em>View Certificates</em> →
|
|
<em>Authorities</em> → <em>Import</em>, pick <code>rootCA.crt</code>,
|
|
tick <em>Trust this CA to identify websites</em>.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>macOS</h2>
|
|
<div class="card">
|
|
<ol>
|
|
<li>Double-click <code>rootCA.crt</code>. Keychain Access opens.</li>
|
|
<li>When prompted, add it to the <strong>System</strong> keychain.</li>
|
|
<li>Find the <em>Furtka</em> entry, double-click, expand <em>Trust</em>,
|
|
set <em>When using this certificate</em> to <strong>Always Trust</strong>.</li>
|
|
<li>Close the window — you will be asked for your password.</li>
|
|
</ol>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Windows</h2>
|
|
<div class="card">
|
|
<ol>
|
|
<li>Double-click <code>rootCA.crt</code>.</li>
|
|
<li>Click <strong>Install Certificate</strong>.</li>
|
|
<li>Choose <strong>Local Machine</strong> (requires admin) and click <em>Next</em>.</li>
|
|
<li>Select <strong>Place all certificates in the following store</strong> →
|
|
<em>Browse</em> → <strong>Trusted Root Certification Authorities</strong>.</li>
|
|
<li>Finish. Chrome and Edge pick this up immediately. Firefox keeps its
|
|
own store — import the same file via Firefox settings.</li>
|
|
</ol>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Android</h2>
|
|
<div class="card">
|
|
<ol>
|
|
<li>Transfer <code>rootCA.crt</code> to the device (AirDrop, email,
|
|
USB — whatever is handy).</li>
|
|
<li>Settings → <em>Security</em> (or <em>Security & privacy</em>)
|
|
→ <em>More security settings</em> → <em>Encryption & credentials</em>
|
|
→ <em>Install a certificate</em> → <strong>CA certificate</strong>.</li>
|
|
<li>Confirm the warning, then pick the file.</li>
|
|
</ol>
|
|
<p class="hint">
|
|
Android 11+ only trusts user-installed CAs for browsers by default.
|
|
Some apps (banking, Play services) ignore them. Not a Furtka bug —
|
|
an Android policy choice.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>iOS & iPadOS</h2>
|
|
<div class="card">
|
|
<p class="hint">
|
|
Honest warning: iOS needs a signed configuration profile for a
|
|
properly trusted CA. What works today:
|
|
</p>
|
|
<ol>
|
|
<li>Email <code>rootCA.crt</code> to yourself and open the attachment
|
|
in Mail. iOS prompts to install a profile.</li>
|
|
<li>Settings → <em>General</em> → <em>VPN & Device Management</em>
|
|
→ tap the Furtka profile → <strong>Install</strong>.</li>
|
|
<li>Settings → <em>General</em> → <em>About</em> → <em>Certificate
|
|
Trust Settings</em> → toggle <strong>Furtka</strong> on.</li>
|
|
</ol>
|
|
<p class="hint">
|
|
A packaged <code>.mobileconfig</code> makes this smoother; it's on
|
|
the roadmap but not in this release.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<footer>
|
|
<p>Furtka · <a href="https://furtka.org">furtka.org</a></p>
|
|
</footer>
|
|
</main>
|
|
|
|
<script>
|
|
document.getElementById('hostname').textContent = location.hostname;
|
|
|
|
document.getElementById('download-btn').addEventListener('click', () => {
|
|
const a = document.createElement('a');
|
|
a.href = '/rootCA.crt';
|
|
a.download = 'furtka-local-rootCA.crt';
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
a.remove();
|
|
});
|
|
|
|
(async () => {
|
|
try {
|
|
const r = await fetch('/api/furtka/https/status', { cache: 'no-store' });
|
|
if (!r.ok) return;
|
|
const s = await r.json();
|
|
document.getElementById('fingerprint').textContent =
|
|
s.fingerprint_sha256 || 'waiting for Caddy…';
|
|
} catch (e) { /* keep the placeholder */ }
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|