OpenRung
A free, privacy-first relay network that helps you reach the open internet. Open source and nonprofit-run.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Self-hosted, end-to-end-signed SSH key sync
翻訳待ち
Loading the full README.
Read the full README ↗Publish your SSH authorized_keys from a web page and have your machines pull
updates automatically — without trusting the web server. Every update is
verified against a hardware-backed signing key before it touches
authorized_keys, so a compromised host, CDN, DNS, or TLS cert cannot inject a
key or roll you back to an old one.
This is the system that runs at https://illixion.github.io. You can adopt it for your own keys; it's a single static Go binary plus two shell scripts.
curl https://example.com/keys >> authorized_keys?Because that trusts the web server completely. If the site (or its CDN/host)
serves attacker bytes with 200 OK, you've authorized the attacker. The whole
point here is to remove that trust:
See updater/DESIGN.md for the full threat model.
Your Mac (trusted) your website (UNTRUSTED) your machines
────────────────── ──────────────────────── ─────────────
generate/sign-keys.sh ─push─► /discovery.json ─GET─► ssh-keys-updater
build manifest /manifest.json (pinned keys
sign with YubiKey /manifest.json.sig compiled in)
+ self-verify discover → verify →
write discovery.json serial → atomic install
serial, issued_at, the keys
list, and an optional disable_signer for revoking a compromised signing key.SSHSIG (ssh-keygen -Y sign).install; the binary bakes in only the signing keys, so moving the site needs
no rebuild.<repo root, served at your Pages URL>/
index.html generated page (served at /)
discovery.json PUBLIC location descriptor clients fetch first
manifest.json[.sig] the signed, published artifacts
bin/ binaries + SHA256SUMS — built by CI on deploy, NOT committed
CNAME custom domain for GitHub Pages (ssh.illixion.com)
README.md this file
keys.list YOUR source key list (authorized_keys format) — edit + re-sign
updater/
config.env deployment config: base URL, identity, repo, cadence, source list
*.go the updater (pure stdlib, no external deps)
pinned_signers YOUR trust anchor: the signing public keys
page.tmpl.html self-contained page template (gen-page fills it)
generate/sign-keys.sh build + sign + self-verify; write discovery.json + page
release.sh cross-compile all targets (bakes only the version)
DESIGN.md threat model & internals
INSTALL.md per-platform download/verify/install
Make a signing keypair on hardware, plus an offline backup keypair.
Plain ed25519 keys (the verifier is a single ed25519.Verify):
ssh-keygen -t ed25519 -C you@backup -f securebackup_ed25519 # keep offline
# your YubiKey's ed25519 (PGP/PIV/FIDO) exposed to ssh-agent is the daily signer
Pin them. Put both public keys in updater/pinned_signers,
one per line, ssh-ed25519 AAAA... comment. This is the trust anchor baked
into every binary — get it right.
Configure. Edit updater/config.env — your public
base URL, page title/handle, source repo, cadence, and the source key list.
That one file feeds the signer, the page, and discovery.json.
Record the binary hashes out-of-band. cd updater && ./release.sh v1
cross-compiles all targets and writes dist/SHA256SUMS. Save those numbers
somewhere you control (an iOS note). The Pages CI rebuilds the same bytes
on deploy (reproducible: -trimpath, fixed -ldflags, Go pinned via
go.mod), so what's served matches what you recorded. See INSTALL.md.
List the keys to authorize in keys.list (one SSH public key
per line), then sign: generate/sign-keys.sh builds manifest.json,
signs it through your agent (auto-finds the pinned signer; touch your key),
self-verifies, and writes discovery.json + index.html.
Publish: commit and push. CI builds the binaries and deploys. Binaries are never committed, so the repo stays small.
This is the beginning of the README. Read the rest at the original. Read the full README ↗