feat(nonprod): bind native Agent to signed calls and live capture
This commit is contained in:
+10
-2
@@ -17,7 +17,7 @@ systemd service or add it to a production host.
|
||||
## Native Asterisk validation
|
||||
|
||||
`nonprod-call-evidence.sh` is the mandatory capture-first wrapper for
|
||||
non-production `mock`, `mixed` and `real` call checks. It runs on a validation
|
||||
non-production `mock`, `mixed` and explicit `nonprod-real` call checks. It runs on a validation
|
||||
host with native Asterisk and required diagnostics; it is not an Asterisk or
|
||||
Agent replacement and is not containerized. Run it explicitly with the current
|
||||
call authorization and the approved target/trunk. It refuses production mode
|
||||
@@ -29,7 +29,15 @@ of the installed binary and configuration. Missing facts fail the validation;
|
||||
`--preflight-only` never authorizes a call. After capture, missing capture or
|
||||
recording SHA-256, Asterisk journal, SIP summary, logger shutdown, timestamp, or
|
||||
restricted evidence ownership is recorded in `diagnostic-errors.txt` and fails
|
||||
the check; an already failed call keeps its nonzero result. Isolated tests
|
||||
the check; an already failed call keeps its nonzero result. Once live tcpdump
|
||||
and the PJSIP logger are running, the script creates a root-owned, group-readable
|
||||
`<call-id>.active` capture arm under `--proof-root` (default
|
||||
`/run/sip-go-agent/nonprod-armed`). The real Agent must set `AGENT_EVIDENCE_ROOT`
|
||||
to this directory; it checks the exact approved event ID, trunk, raw callee,
|
||||
recent arm and live capture PID before origination. The script removes the arm
|
||||
before stopping capture. Run one approved call per invocation, with
|
||||
`--call-id` equal to that call's MQ `event_id`; never reuse a stale arm.
|
||||
Isolated tests
|
||||
replace host tools with fakes: they do not prove a real host or supplier is ready.
|
||||
|
||||
For the **nonproduction user-level Asterisk service only**, pass
|
||||
|
||||
@@ -39,6 +39,9 @@ target=""
|
||||
call_command=()
|
||||
preflight_only=0
|
||||
attempt_ledger="/var/lib/sip-go-agent/state/real-call-attempts.tsv"
|
||||
proof_root="/run/sip-go-agent/nonprod-armed"
|
||||
proof_file=""
|
||||
proof_created=0
|
||||
attempt_number=0
|
||||
|
||||
while (($#)); do
|
||||
@@ -55,6 +58,7 @@ while (($#)); do
|
||||
--rtp-end) [[ $# -ge 2 ]] || usage; rtp_end=$2; shift 2 ;;
|
||||
--preflight-only) preflight_only=1; shift ;;
|
||||
--attempt-ledger) [[ $# -ge 2 ]] || usage; attempt_ledger=$2; shift 2 ;;
|
||||
--proof-root) [[ $# -ge 2 ]] || usage; proof_root=$2; shift 2 ;;
|
||||
--trunk) [[ $# -ge 2 ]] || usage; trunk=$2; shift 2 ;;
|
||||
--target) [[ $# -ge 2 ]] || usage; target=$2; shift 2 ;;
|
||||
--) shift; call_command=("$@"); break ;;
|
||||
@@ -73,6 +77,7 @@ esac
|
||||
[[ "$trunk" =~ ^(provider-primary|provider-second|provider-third|trunk-[A-Za-z0-9._-]+)$ ]] || { echo 'trunk is not an approved non-production trunk id' >&2; exit 1; }
|
||||
[[ "$target" =~ ^(15003164745|15830461047)$ ]] || { echo 'target is outside the approved outbound whitelist' >&2; exit 1; }
|
||||
[[ "$attempt_ledger" =~ ^/[A-Za-z0-9._/-]+$ ]] || { echo 'invalid attempt ledger path' >&2; exit 1; }
|
||||
[[ "$proof_root" =~ ^/[A-Za-z0-9._/-]+$ ]] || { echo 'invalid proof root path' >&2; exit 1; }
|
||||
[[ ${#call_command[@]} -gt 0 ]] || { echo 'call command is required after --' >&2; exit 1; }
|
||||
[[ "$interface" =~ ^[A-Za-z0-9_.:-]+$ ]] || { echo 'invalid capture interface' >&2; exit 1; }
|
||||
[[ "$sip_port" =~ ^[0-9]+$ && "$rtp_start" =~ ^[0-9]+$ && "$rtp_end" =~ ^[0-9]+$ ]] || { echo 'invalid port' >&2; exit 1; }
|
||||
@@ -294,6 +299,10 @@ cleanup() {
|
||||
local call_exit=$? evidence_failed=0
|
||||
trap - EXIT
|
||||
set +e
|
||||
if ((proof_created)) && ! rm -f -- "$proof_file"; then
|
||||
printf 'capture arm removal failed\n' >>"$evidence_dir/diagnostic-errors.txt"
|
||||
evidence_failed=1
|
||||
fi
|
||||
stop_capture
|
||||
if ((logger_enabled)) && ! asterisk_cli "pjsip set logger off" >"$evidence_dir/pjsip-logger-off.txt" 2>&1; then
|
||||
printf 'PJSIP logger stop failed\n' >>"$evidence_dir/diagnostic-errors.txt"
|
||||
@@ -394,6 +403,18 @@ if ((preflight_only)); then
|
||||
fi
|
||||
|
||||
require_call_window
|
||||
# The Agent checks this root-owned, call-specific live capture arm before any
|
||||
# originate. A stale arm is never overwritten; the trap removes it first.
|
||||
install -d -o root -g "$run_as" -m 0750 -- "$proof_root"
|
||||
proof_file="$proof_root/$call_id.active"
|
||||
[[ ! -e "$proof_file" ]] || { echo 'stale or concurrent capture arm; fail-closed' >&2; exit 1; }
|
||||
proof_tmp="$(mktemp --tmpdir="$proof_root" ".$call_id.XXXXXX")"
|
||||
printf '%s\t%s\t%s\n' "$capture_pid" "$trunk" "$target" >"$proof_tmp"
|
||||
chown "root:$run_as" "$proof_tmp"
|
||||
chmod 0640 "$proof_tmp"
|
||||
ln -- "$proof_tmp" "$proof_file" || { rm -f -- "$proof_tmp"; echo 'capture arm already exists; fail-closed' >&2; exit 1; }
|
||||
proof_created=1
|
||||
rm -f -- "$proof_tmp"
|
||||
call_status=0
|
||||
set +e
|
||||
runuser -u "$run_as" -- "${call_command[@]}" >"$evidence_dir/call-output.private" 2>&1
|
||||
|
||||
Reference in New Issue
Block a user