Sign Sunshine certs with a 1Password-backed root CA
Replaces Sunshine's self-signed cert with one minted from a private root CA
whose key material lives in 1Password. Every host running install.sh fetches
the CA via 'op read', mints itself a host cert with SANs for <hostname>.lan
and the current LAN IP, and installs the CA into the system trust store.
Bootstrap (run once, anywhere)
- scripts/cert-bootstrap.sh: generates a 4096-bit RSA root CA (10y validity),
uploads it as a Secure Note titled "Omarchy-Stream Root CA" in the Private
vault with two fields: cert (text) and key (concealed). Refuses to overwrite
an existing item without --force.
Per-host (lib/certs.sh)
- fetch_and_install_certs: reads op://Private/Omarchy-Stream Root CA/{cert,key}
to a tmpfs-staged temp dir (XDG_RUNTIME_DIR), mints a host cert via openssl
with serverAuth + clientAuth EKU, drops cert/key at ~/.config/sunshine/
credentials/{cacert,cakey}.pem, installs the CA at
/etc/ca-certificates/trust-source/anchors/omarchy-stream-ca.pem and runs
update-ca-trust.
- Idempotent: skips re-mint when on-disk cert is signed by the current CA,
has the expected SANs, and isn't within 30 days of expiry. Override with
FORCE_CERTS=1 or --force-certs.
install.sh
- Adds --no-certs, --force-certs flags; sources lib/certs.sh; runs cert step
after permissions/config and before firewall so the service restart at the
end of install picks up the new cert.
client/install-macos.sh
- After installing Moonlight, if `op` is available and signed in, fetches the
CA and adds it as a trusted root to /Library/Keychains/System.keychain via
`security add-trusted-cert -d -r trustRoot`. Skips cleanly when op isn't
ready.
uninstall.sh
- Adds --remove-ca-trust to delete the system trust anchor. By default the
CA is left in place since other tools may rely on it.
verify.sh
- Adds checks for: cert signed by omarchy-stream CA, cert >30 days from
expiry, CA present in system trust store.
Docs
- README "Trusted TLS certs via 1Password" section: bootstrap flow, per-host
flow, client trust matrix (Linux / macOS / iOS / Android / Apple TV),
re-pairing note (first cert install on a host invalidates pinned Moonlight
fingerprints), config env vars.
- client/README gains per-platform CA-trust install steps with concrete
`op read` + platform-specific commands.
This commit is contained in:
@@ -51,6 +51,56 @@ to the same Apple ID.
|
||||
Use `moonlight-qt` from your distro's package manager (Flatpak on Steam Deck,
|
||||
`pacman`/`apt` elsewhere). It is the same Qt-based client as macOS and Windows.
|
||||
|
||||
## Trusting the omarchy-stream CA
|
||||
|
||||
If the host was installed with the cert step (default), its Sunshine web UI
|
||||
uses a cert signed by a private root CA whose key is stored in 1Password. To
|
||||
avoid the browser warning on `https://<host>.lan:47990`, install the CA on each
|
||||
client device. This is a one-time step per device.
|
||||
|
||||
### macOS
|
||||
|
||||
`./install-macos.sh` handles this automatically if `op` is signed in. To do it
|
||||
manually:
|
||||
|
||||
```bash
|
||||
op read --no-newline "op://Private/Omarchy-Stream Root CA/cert" > /tmp/ca.pem
|
||||
sudo security add-trusted-cert -d -r trustRoot \
|
||||
-k /Library/Keychains/System.keychain /tmp/ca.pem
|
||||
rm /tmp/ca.pem
|
||||
```
|
||||
|
||||
### iOS / iPadOS
|
||||
|
||||
1. In the 1Password app, open the **Omarchy-Stream Root CA** item in the
|
||||
**Private** vault. Copy the `cert` field into the body of an email and send
|
||||
it to yourself with the file extension `.crt` or `.pem` (Mail handles inline
|
||||
PEM oddly; an attachment is cleanest).
|
||||
2. Open the email on the iOS device and tap the attachment. iOS will offer to
|
||||
install a configuration profile.
|
||||
3. Settings → General → VPN & Device Management → Downloaded Profile → Install.
|
||||
4. **Important second step**: Settings → General → About → Certificate Trust
|
||||
Settings → enable full trust for the omarchy-stream Root CA. Without this,
|
||||
Safari still warns.
|
||||
|
||||
### Android
|
||||
|
||||
1. From 1Password, save the CA `cert` field to a `.crt` file on the device
|
||||
(Downloads folder is fine).
|
||||
2. Settings → Security → Encryption & credentials → Install a certificate → CA
|
||||
certificate.
|
||||
3. Acknowledge the warning, select the file, give it a name.
|
||||
|
||||
(Path varies slightly by Android version / OEM skin — search Settings for "CA
|
||||
certificate" if the path above doesn't match.)
|
||||
|
||||
### Apple TV
|
||||
|
||||
Cert profiles can be installed by emailing the cert to an account on the
|
||||
Apple TV and tapping it, or by using Apple Configurator from a Mac. For
|
||||
LAN-only use the self-signed warning is also tolerable — Apple TV has no
|
||||
browser, so the cert is only relevant if you ever inspect the host directly.
|
||||
|
||||
## First pair
|
||||
|
||||
The pairing flow is the same on every client.
|
||||
|
||||
@@ -51,6 +51,43 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- CA trust install (1Password-backed) ------------------------------------
|
||||
# If `op` is available and signed in, fetch the omarchy-stream Root CA from
|
||||
# 1Password and add it to the System keychain as a trusted root. This makes
|
||||
# Safari / Chrome / curl trust the Sunshine web UI on every host without the
|
||||
# self-signed warning. Skip cleanly if op isn't available or not signed in;
|
||||
# the user can re-run after `eval $(op signin)`.
|
||||
SKIP_CA="${SKIP_CA:-0}"
|
||||
OP_VAULT="${OP_VAULT:-Private}"
|
||||
OP_CA_ITEM="${OP_CA_ITEM:-Omarchy-Stream Root CA}"
|
||||
|
||||
if [[ $SKIP_CA -eq 1 ]]; then
|
||||
info "Skipping CA install (SKIP_CA=1)"
|
||||
elif ! command -v op >/dev/null 2>&1; then
|
||||
info "1Password CLI ('op') not found. Skipping CA trust install."
|
||||
info "Install it from https://1password.com/downloads/command-line/ and re-run for trusted certs."
|
||||
elif ! op whoami >/dev/null 2>&1; then
|
||||
info "1Password CLI is not signed in. Skipping CA trust install."
|
||||
info "Sign in with 'eval \$(op signin)' and re-run for trusted certs."
|
||||
else
|
||||
step "Installing omarchy-stream CA into System keychain"
|
||||
ca_tmp="$(mktemp -t omarchy-ca.XXXXXX.pem)"
|
||||
trap 'rm -f "$ca_tmp"' EXIT
|
||||
if op read --no-newline "op://${OP_VAULT}/${OP_CA_ITEM}/cert" >"$ca_tmp" 2>/dev/null && [[ -s "$ca_tmp" ]]; then
|
||||
info "Fetched CA from 1Password (vault: ${OP_VAULT})"
|
||||
info "Adding to /Library/Keychains/System.keychain — you may be prompted for your password."
|
||||
if sudo security add-trusted-cert -d -r trustRoot \
|
||||
-k /Library/Keychains/System.keychain "$ca_tmp"; then
|
||||
ok "CA installed as trusted root."
|
||||
else
|
||||
warn "security add-trusted-cert failed. You can add the cert manually via Keychain Access."
|
||||
fi
|
||||
else
|
||||
warn "Could not read 'cert' field from item '${OP_CA_ITEM}' in vault '${OP_VAULT}'."
|
||||
warn "Run scripts/cert-bootstrap.sh on a Linux host first, then re-run this script."
|
||||
fi
|
||||
fi
|
||||
|
||||
step "Next steps"
|
||||
info "App location: /Applications/Moonlight.app"
|
||||
info "Launch: open -a Moonlight"
|
||||
|
||||
Reference in New Issue
Block a user