diff --git a/.gitignore b/.gitignore index 48e9af8..0dca800 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /frx-data/ /comments.txt +/relay.log diff --git a/DEPLOY.md b/DEPLOY.md index b2e239c..931c164 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -47,7 +47,7 @@ Run `frxd` on loopback and terminate TLS with Caddy: caddy reverse-proxy --from relay.federatedsearch.org --to 127.0.0.1:7700 ``` -Caddyfile equivalent (apex is the public front door, `ma.` the membership service, `relay.` the relay — all on one host): +Caddyfile equivalent (apex is the public front door, `ma.` the membership service, `relay.` the relay, `git.` the code host — all on one host): ``` federatedsearch.org { @@ -61,6 +61,10 @@ ma.federatedsearch.org { relay.federatedsearch.org { reverse_proxy 127.0.0.1:7700 } + +git.federatedsearch.org { + reverse_proxy 127.0.0.1:3000 +} ``` Relay command (peers and registry gated by the MA): @@ -112,6 +116,77 @@ frxd registry --dir /var/lib/frxd/registry serve --listen 127.0.0.1:7800 Put the same Caddy in front, or distribute `registry.json` out of band (it is signed, so the channel does not matter). The snapshot is versioned; nodes reject rollback and fail static during outages. +## Code hosting and downloads (Gitea) + +The public source and release binaries live at `git.federatedsearch.org` (Gitea), so the +download step on the membership page stays on infrastructure the federation operates. + +One-time install on the server (root): + +``` +VER=1.27.3 +curl -fsSLO https://dl.gitea.com/gitea/$VER/gitea-$VER-linux-amd64{,.sha256} +sha256sum -c gitea-$VER-linux-amd64.sha256 +install -m 0755 gitea-$VER-linux-amd64 /usr/local/bin/gitea +adduser --system --shell /bin/bash --gecos 'Gitea' --home /home/git --group git +mkdir -p /var/lib/gitea/{custom,data,log} /etc/gitea && chown -R git:git /var/lib/gitea /etc/gitea +``` + +`/etc/gitea/app.ini` essentials (rest defaults; secrets via `gitea generate secret`): + +```ini +WORK_PATH = /var/lib/gitea + +[database] +DB_TYPE = sqlite3 +PATH = /var/lib/gitea/data/gitea.db + +[server] +DOMAIN = git.federatedsearch.org +SSH_DOMAIN = git.federatedsearch.org +ROOT_URL = https://git.federatedsearch.org/ +HTTP_ADDR = 127.0.0.1 +HTTP_PORT = 3000 + +[security] +INSTALL_LOCK = true + +[service] +DISABLE_REGISTRATION = true +REQUIRE_SIGNIN_VIEW = false +``` + +systemd unit (`User=git`, `ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini`, +`WorkingDirectory=/var/lib/gitea`), then `gitea migrate --config /etc/gitea/app.ini` as the +`git` user and `systemctl enable --now gitea`. Git-over-SSH uses the host sshd via the `git` +user's Gitea-managed `authorized_keys`; HTTPS pushes can use an access token instead. + +Admin bootstrap (as `git` user): + +``` +gitea admin user create --admin --username --email @federatedsearch.org --random-password --config /etc/gitea/app.ini +gitea admin user generate-access-token -u -t bootstrap --scopes all --config /etc/gitea/app.ini +``` + +The org is `frx`, the repo `frxd` → clone URL +`https://git.federatedsearch.org/frx/frxd.git`. Membership stays closed (signup code); +repo reads are public. + +Publishing a release (from the checkout): + +``` +git tag v0.1.0 && git push gitea v0.1.0 +# build static binaries (see next section), then attach via the API: +curl -X POST https://git.federatedsearch.org/api/v1/repos/frx/frxd/releases \ + -H "Authorization: token " -H 'content-type: application/json' \ + -d '{"tag_name":"v0.1.0","name":"v0.1.0"}' +curl -X POST https://git.federatedsearch.org/api/v1/repos/frx/frxd/releases//assets?name=frxd-linux-amd64 \ + -H "Authorization: token " -F attachment=@frxd-linux-amd64 +``` + +Asset URLs follow `/frx/frxd/releases/download//` — the membership page pins +those. Bump the page when a release changes. + ## Private networks and custom CAs - `ca_cert = "/etc/ssl/private-ca.pem"` in `[node]`, or `--ca-cert` on the relay: adds a private/corporate root CA for relay and registry connections. @@ -125,7 +200,15 @@ rustup target add x86_64-unknown-linux-musl cargo build --release --target x86_64-unknown-linux-musl ``` -`[profile.release]` enables LTO and stripping. All dependencies are pure Rust, so the musl build has no system-library requirements. +`[profile.release]` enables LTO and stripping. All dependencies are pure Rust, so the musl build has no system-library requirements. `ring` needs a musl C toolchain (`musl-tools`); without host sudo, build in a container instead: + +``` +docker run --rm -v "$PWD":/src -w /src rust:1-slim-bookworm bash -c \ + "apt-get update -qq && apt-get install -y -qq musl-tools && rustup target add x86_64-unknown-linux-musl && cargo build --release --target x86_64-unknown-linux-musl" +``` + +Binaries land in `target/x86_64-unknown-linux-musl/release/`; rename to +`frxd-linux-amd64` / `frx-linux-amd64` for release assets, with `sha256sum` sidecar files. ## What TLS does and does not cover diff --git a/src/commands.rs b/src/commands.rs index bfae7b0..2337f42 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -713,8 +713,11 @@ const REGISTRY_PAGE: &str = r##" button:hover { background: #0f3d91; } #out { display: none; background: #101418; color: #d6f5d6; padding: 0.85rem 1rem; border-radius: 8px; white-space: pre-wrap; word-break: break-all; margin-top: 1rem; } + pre.cmd { background: #101418; color: #d6f5d6; padding: 0.85rem 1rem; + border-radius: 8px; overflow-x: auto; } .muted { color: #666; font-size: 0.92rem; } ol { padding-left: 1.3rem; } + li { margin: 0.35rem 0; } a { color: #174ea6; } @@ -726,7 +729,7 @@ small: signed messages, budgets, honest truncation, aggregate courtesy. No annou scores on the wire, no in-protocol payment.

Everything else — matching, ranking, retention, trust — is local.

-

Join the federation

+

1. Register

-

After you get credentials

+

2. Download

+
+

Static Linux x86_64 binaries (musl — no runtime dependencies):

+
curl -LO https://git.federatedsearch.org/frx/frxd/releases/download/v0.1.0/frxd-linux-amd64
+curl -LO https://git.federatedsearch.org/frx/frxd/releases/download/v0.1.0/frxd-linux-amd64.sha256
+curl -LO https://git.federatedsearch.org/frx/frxd/releases/download/v0.1.0/frx-linux-amd64
+curl -LO https://git.federatedsearch.org/frx/frxd/releases/download/v0.1.0/frx-linux-amd64.sha256
+

All releases: git.federatedsearch.org/frx/frxd/releases. +Source and spec (rfc.txt): git.federatedsearch.org/frx/frxd.

+
+ +

3. Install

+
+
sha256sum -c frxd-linux-amd64.sha256
+chmod +x frxd-linux-amd64 frx-linux-amd64
+sudo mv frxd-linux-amd64 /usr/local/bin/frxd
+sudo mv frx-linux-amd64 /usr/local/bin/frx
+

No sudo? Run them in place — each is a single self-contained binary.

+
+ +

4. Onboard

+
+
frxd --onboarding
    -
  1. Install the single static binary: frxd.
  2. -
  3. Run frxd --onboarding and paste the credential block it gives you.
  4. -
  5. The wizard binds your keys, verifies the signed registry, and wires your relays — no domains, DNS, or ports needed on your side.
  6. +
  7. Paste the credential block from step 1.
  8. +
  9. The wizard generates your keys, enrolls them with the MA, verifies the signed registry +against the pinned MA key, and wires the federation relays — no domains, DNS, or open ports +needed on your side.
  10. +
  11. Index a directory and mark what you share:
+
frxd add ~/documents --name docs --shared --exposure metadata
+frxd serve
+

Search local-first with frx search "..."; broadcast to the federation with +frx query "...". Nothing is shared until a collection is explicitly marked +--shared.

+

Who is in

@@ -762,7 +798,7 @@ document.getElementById("f").onsubmit = async (e) => { const body = await res.json(); out.style.display = "block"; out.textContent = res.ok - ? "Membership approved.\n\nRun `frxd --onboarding` and paste this block:\n\n" + body.credentials + "\n" + ? "Membership approved.\n\nNext: download frxd (step 2), install it (step 3), then run `frxd --onboarding` and paste this block:\n\n" + body.credentials + "\n" : "Failed: " + (body.error || ("http " + res.status)); };