Until now a bridge line existed in one place, the bridge container's stdout. Doc 27 Milestone 1 needs a list: what is handed out, since when, and what is retired. - obfs4_bridges: host, port, fingerprint (40-hex obfs4 node ID, unique), line, added_at, retired_at. Additive migration, appended last. - The line is derived from the bridge's own state file, as the bridge prints it. The private key is read from stdin, used for the X25519 public key, and dropped; no row holds it. Checked against RFC 7748 here, and against the live bridge on the box (derived cert == printed cert). - A retired identity is never listed again. - No route reads the table. flamenet-relay bridges list|add|retire is dispatched in main BEFORE configure, so it opens the database and does not migrate, sweep, drain or boot lifecycle handlers beside the live relay. Scripts/bridges.sh wraps it on the box, like suspend.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.3 KiB
Bash
Executable File
69 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# The obfs4 bridge inventory: which bridges this operator runs, since when,
|
|
# and which are retired. One row per bridge identity, in the relay's database
|
|
# (table obfs4_bridges). No route reads it; this script is the way in.
|
|
#
|
|
# Scripts/bridges.sh list [--all] bridges in service (--all: retired ones too)
|
|
# Scripts/bridges.sh add <host> <port> [state] list a bridge (state: this box's bridge by default)
|
|
# Scripts/bridges.sh retire <fingerprint> take one out of service; the row stays
|
|
#
|
|
# Run on the box with sudo, like suspend.sh.
|
|
#
|
|
# `add` derives the line from the bridge's own state file, the same file the
|
|
# bridge reads at start ({"nodeID": ..., "privateKey": ...}). The file goes to
|
|
# the relay container on stdin; the relay computes the public key from it and
|
|
# keeps only the public parts. Nothing writes the private key anywhere. For a
|
|
# bridge on another machine, pipe its state file in and pass `-`:
|
|
#
|
|
# ssh bridge2 sudo cat /var/lib/obfs4/state.json | sudo Scripts/bridges.sh add 203.0.113.9 443 -
|
|
#
|
|
# `<host>` is the address clients dial, not the container's. `<port>` is the
|
|
# published port (8443 for the bridge beside this relay).
|
|
#
|
|
# `list` prints bridge lines. Each one is what a client is given: hand them
|
|
# out one at a time, and never paste the list into a ticket, a chat or a doc.
|
|
# A retired identity is never listed again; give a burned bridge a new state
|
|
# file rather than reusing the old one.
|
|
|
|
set -euo pipefail
|
|
cd /srv/prod/messenger
|
|
|
|
relay() { docker compose exec -T relay flamenet-relay bridges "$@"; }
|
|
|
|
# Where this box's bridge keeps its identity.
|
|
local_state() {
|
|
local mp
|
|
mp="$(docker volume inspect messenger_obfs4-state --format '{{.Mountpoint}}')"
|
|
printf '%s/state.json' "$mp"
|
|
}
|
|
|
|
usage() {
|
|
sed -n '6,8p' "$0" | sed 's/^# *//' >&2
|
|
exit 64
|
|
}
|
|
|
|
case "${1:-}" in
|
|
list)
|
|
shift
|
|
relay list "$@"
|
|
;;
|
|
add)
|
|
host="${2:-}"; port="${3:-}"
|
|
[ -n "$host" ] && [ -n "$port" ] || usage
|
|
src="${4:-$(local_state)}"
|
|
if [ "$src" = "-" ]; then
|
|
relay add --host "$host" --port "$port" --state -
|
|
else
|
|
[ -r "$src" ] || { echo "cannot read $src (run with sudo)" >&2; exit 66; }
|
|
relay add --host "$host" --port "$port" --state - < "$src"
|
|
fi
|
|
;;
|
|
retire)
|
|
[ -n "${2:-}" ] || usage
|
|
relay retire "$2"
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|