From 2f7edc1d3f78b7e8841e063a6ebab430ce7faeb3 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sun, 30 Aug 2026 14:48:43 +0000 Subject: [PATCH] feat(install): install the pinned-TLS proxy, so https:// works without a manual step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `moshcode dns enable` can finish perfectly and every https:// URL still fails. No public CA will ever sign for `.eggs`, so a name answers its origin's own self-signed leaf and a stock client refuses it — correctly. The fix was documented as a separate install of moshpit-proxy, which meant the supported path ended one step short of working and the alternative was trusting certificates one name at a time. install.sh now installs it, and `moshcode update` re-runs install.sh, so an existing install picks it up too. One local root covers every ending instead of per-name trust. MOSHCODE_NO_PROXY=1 skips it: this is the only part of the install that touches the system trust store, so it is the only part with an opt-out. MOSHCODE_PROXY_INSTALLER overrides the source, which is also how the failure paths are tested. No DNS routing is installed and no resolver is started — `dns enable` stays something a person types deliberately. Downloaded first and run second, rather than `curl … | sh`. A pipeline reports the status of its last command, and a `sh` handed empty stdin by a 404 exits 0, so the piped form printed "✓ pinned-TLS proxy installed, local root trusted" for a script that never arrived. Caught by pointing it at a missing URL. Never fatal: a machine that cannot reach GitHub for an optional component still wants the CLI it asked for. Adds warn(), which unlike fail() does not exit. Verified across all five branches — success, installer exits non-zero, 404, unreachable host, and MOSHCODE_NO_PROXY — each reporting honestly and none aborting the install. Suite: 2726 tests, 0 failures. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01ThnQwoieWt8VR6N7gtgnhp --- install.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/install.sh b/install.sh index 7368f113..28fe281e 100644 --- a/install.sh +++ b/install.sh @@ -23,6 +23,8 @@ # MOSHCODE_BIN=/path/dir wrapper bin dir (default: $HOME/.local/bin) # MOSHCODE_REF=vX.Y.Z pin a tag/branch (default: latest release, else main) # MOSHCODE_ALLOW_ROOT=1 install as root anyway (see below) +# MOSHCODE_NO_PROXY=1 skip the pinned-TLS proxy (https:// on a Moshpit +# name will not verify without it) # # Do not install this with sudo. moshcode is a user-level CLI, and every path # here is derived from $HOME — under sudo that is /root, so the payload and the @@ -41,6 +43,8 @@ MOSHCODE_BIN="${MOSHCODE_BIN:-$HOME/.local/bin}" WRAPPER="$MOSHCODE_BIN/moshcode" SCRIPT_WRAPPER="$MOSHCODE_BIN/moshscript" +PROXY_INSTALLER="${MOSHCODE_PROXY_INSTALLER:-https://raw.githubusercontent.com/profullstack/moshpit-proxy/main/install.sh}" + # ---- pretty output (acid-lime, matching the CLI) -------------------------- if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then ACID=$(printf '\033[38;2;158;240;26m'); ASH=$(printf '\033[38;2;139;147;138m') @@ -51,6 +55,9 @@ fi info() { printf '%s·%s %s\n' "$ASH" "$RESET" "$*"; } ok() { printf '%s✓%s %s\n' "$ACID" "$RESET" "$*"; } fail() { printf '%s✗%s %s\n' "$RED" "$RESET" "$*" >&2; exit 1; } +# Unlike fail(), does not exit: an optional component that did not install is +# not a reason to leave the CLI half-written. +warn() { printf '%s!%s %s\n' "$RED" "$RESET" "$*" >&2; } # ---- prerequisites -------------------------------------------------------- need() { command -v "$1" >/dev/null 2>&1 || fail "$1 is required but not found."; } @@ -155,6 +162,66 @@ ensure_path() { info "add $MOSHCODE_BIN to PATH in this shell: export PATH=\"$MOSHCODE_BIN:\$PATH\"" } +# ---- the pinned-TLS proxy ------------------------------------------------- +# Without this, HTTPS on a Moshpit name cannot work. No public CA will ever sign +# for `.eggs`, so a name answers its origin's own self-signed leaf and a stock +# client refuses it — correctly. moshpit-proxy generates one local root and +# terminates TLS in the one language a browser accepts, which turns "trust this +# certificate" from a thing you do per name into a thing you do once. +# +# Installed here rather than left as a follow-up step because the alternative is +# `moshcode dns enable` finishing successfully, every name resolving, and every +# https:// URL still failing — which reads as broken, not as unfinished. +# +# This is the one part of the install that touches the system's trust store, so +# it is the one part with an opt-out: MOSHCODE_NO_PROXY=1 skips it entirely, and +# `moshpit-proxy install.sh --uninstall` undoes it later. It installs no DNS +# routing and starts no resolver -- `moshcode dns enable` stays a thing a person +# types deliberately. +install_proxy() { + if [ -n "${MOSHCODE_NO_PROXY:-}" ]; then + info "skipping the pinned-TLS proxy (MOSHCODE_NO_PROXY is set) — https:// on a Moshpit name will not verify" + return 0 + fi + + info "installing the pinned-TLS proxy (so https:// on a Moshpit name verifies)" + + # Downloaded first and run second, rather than `curl … | sh`. + # + # A pipeline reports the exit status of its LAST command, and a `sh` handed + # an empty stdin by a 404 exits 0 — so piping reports a successful install + # for a script that never arrived. Verified: pointed at a missing URL, the + # piped form printed "✓ pinned-TLS proxy installed, local root trusted". + _proxy_sh="$(mktemp 2>/dev/null)" || { + warn "could not create a temp file for the pinned-TLS proxy installer — skipping" + return 0 + } + if ! curl -fsSL "$PROXY_INSTALLER" -o "$_proxy_sh" 2>/dev/null; then + rm -f "$_proxy_sh" + warn "could not download the pinned-TLS proxy — moshcode is fine, but https:// on a Moshpit name will not verify" + warn " retry: curl -fsSL $PROXY_INSTALLER | sh" + return 0 + fi + + # `--yes` because this installer is normally reached through a pipe, where + # there is no terminal to answer its prompt on. Announced above rather than + # asked, and MOSHCODE_NO_PROXY is the opt-out. + if sh "$_proxy_sh" --yes >/dev/null 2>&1; then + ok "pinned-TLS proxy installed, local root trusted" + info " it covers .moshpit by default — for other endings:" + info " MOSHPIT_PROXY_TLDS=moshpit,eggs,hacker,2600" + info " undo just this: curl -fsSL $PROXY_INSTALLER | sh -s -- --uninstall" + else + # Never fatal. moshcode is a coding CLI first, and a machine that cannot + # finish an optional component still wants the CLI it asked for. Said out + # loud so it is not discovered later as a TLS error with no explanation. + warn "the pinned-TLS proxy did not install — moshcode is fine, but https:// on a Moshpit name will not verify" + warn " retry: curl -fsSL $PROXY_INSTALLER | sh" + fi + rm -f "$_proxy_sh" + unset _proxy_sh +} + # ---- commands ------------------------------------------------------------- run_install() { printf '\n%smoshcode installer%s %s— code hard, mosh harder 🤘%s\n\n' "$BOLD" "$RESET" "$ASH" "$RESET" @@ -165,6 +232,7 @@ run_install() { fetch_and_unpack "$_ref" write_wrapper ensure_path + install_proxy printf '\n%sdone.%s run:\n' "$ACID" "$RESET" printf ' moshcode # open the TUI shell\n' printf ' moshcode start claude # raw engine session (use agents for autonomous)\n'