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.
99 lines
3.7 KiB
Bash
Executable File
99 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Install Moonlight on macOS via Homebrew cask.
|
|
# Standalone: does not source lib/common.sh (intended to run on a Mac that
|
|
# may not have the full repo checked out yet).
|
|
|
|
set -euo pipefail
|
|
|
|
if [[ -t 1 ]]; then
|
|
BOLD=$'\033[1m'
|
|
RED=$'\033[31m'
|
|
GREEN=$'\033[32m'
|
|
YELLOW=$'\033[33m'
|
|
BLUE=$'\033[34m'
|
|
RESET=$'\033[0m'
|
|
else
|
|
BOLD="" RED="" GREEN="" YELLOW="" BLUE="" RESET=""
|
|
fi
|
|
|
|
step() { printf '\n%s==>%s %s%s%s\n' "$BLUE" "$RESET" "$BOLD" "$*" "$RESET"; }
|
|
info() { printf ' %s\n' "$*"; }
|
|
ok() { printf ' %s✓%s %s\n' "$GREEN" "$RESET" "$*"; }
|
|
warn() { printf ' %s!%s %s\n' "$YELLOW" "$RESET" "$*" >&2; }
|
|
err() { printf ' %s✗%s %s\n' "$RED" "$RESET" "$*" >&2; }
|
|
|
|
# Refuse to run anywhere but macOS.
|
|
if [[ "$(uname -s)" != "Darwin" ]]; then
|
|
err "This script only runs on macOS (Darwin). Detected: $(uname -s)"
|
|
exit 1
|
|
fi
|
|
|
|
step "Checking for Homebrew"
|
|
if ! command -v brew >/dev/null 2>&1; then
|
|
err "Homebrew is not installed."
|
|
info "Install it with the official one-liner, then re-run this script:"
|
|
info ""
|
|
info ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
|
|
info ""
|
|
info "See https://brew.sh for details."
|
|
exit 1
|
|
fi
|
|
ok "Homebrew found: $(command -v brew)"
|
|
|
|
step "Installing Moonlight (brew cask)"
|
|
# brew install --cask is idempotent: re-running on an already-installed cask
|
|
# is a no-op and exits 0.
|
|
if brew install --cask moonlight; then
|
|
ok "Moonlight installed (or already present)."
|
|
else
|
|
err "brew install --cask moonlight failed."
|
|
warn "Try: brew update && brew install --cask moonlight"
|
|
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"
|
|
info ""
|
|
info "Pair this Mac with your Sunshine host by following the walkthrough in:"
|
|
info " client/README.md"
|
|
info ""
|
|
ok "Done."
|