Merge pull request 'fix: edge-control: deregister has no ownership check — any authorized SSH key can take over any project (#1091)' (#1101) from fix/issue-1091-ownership-check into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/nomad-validate Pipeline was successful

This commit is contained in:
dev-qwen 2026-04-21 06:04:13 +00:00
commit 0d61819184
2 changed files with 38 additions and 14 deletions

View file

@ -2885,12 +2885,23 @@ disinto_edge() {
edge_host="${EDGE_HOST:-edge.disinto.ai}" edge_host="${EDGE_HOST:-edge.disinto.ai}"
fi fi
# Read tunnel pubkey for ownership proof
local secrets_dir="${FACTORY_ROOT}/secrets"
local tunnel_pubkey="${secrets_dir}/tunnel_key.pub"
if [ ! -f "$tunnel_pubkey" ]; then
echo "Error: tunnel keypair not found at ${tunnel_pubkey}" >&2
echo "Cannot prove ownership without the tunnel public key." >&2
exit 1
fi
local pubkey
pubkey=$(tr -d '\n' < "$tunnel_pubkey")
# SSH to edge host and deregister # SSH to edge host and deregister
echo "Deregistering tunnel for ${project} on ${edge_host}..." echo "Deregistering tunnel for ${project} on ${edge_host}..."
local response local response
response=$(ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes \ response=$(ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes \
"disinto-register@${edge_host}" \ "disinto-register@${edge_host}" \
"deregister ${project}" 2>&1) || { "deregister ${project} ${pubkey}" 2>&1) || {
echo "Error: failed to deregister tunnel" >&2 echo "Error: failed to deregister tunnel" >&2
echo "Response: ${response}" >&2 echo "Response: ${response}" >&2
exit 1 exit 1

View file

@ -11,7 +11,7 @@
# #
# Usage (via SSH): # Usage (via SSH):
# ssh disinto-register@edge "register <project> <pubkey>" # ssh disinto-register@edge "register <project> <pubkey>"
# ssh disinto-register@edge "deregister <project>" # ssh disinto-register@edge "deregister <project> <pubkey>"
# ssh disinto-register@edge "list" # ssh disinto-register@edge "list"
# #
# Output: JSON on stdout # Output: JSON on stdout
@ -90,7 +90,7 @@ usage() {
cat <<EOF cat <<EOF
Usage: Usage:
register <project> <pubkey> Register a new tunnel register <project> <pubkey> Register a new tunnel
deregister <project> Remove a tunnel deregister <project> <pubkey> Remove a tunnel (requires owner pubkey)
list List all registered tunnels list List all registered tunnels
Example: Example:
@ -231,9 +231,15 @@ do_register() {
} }
# Deregister a tunnel # Deregister a tunnel
# Usage: do_deregister <project> # Usage: do_deregister <project> <pubkey>
do_deregister() { do_deregister() {
local project="$1" local project="$1"
local caller_pubkey="$2"
if [ -z "$caller_pubkey" ]; then
echo '{"error":"deregister requires <project> <pubkey>"}'
exit 1
fi
# Record who is deregistering before removal # Record who is deregistering before removal
local deregistered_by="$CALLER" local deregistered_by="$CALLER"
@ -247,13 +253,16 @@ do_deregister() {
exit 1 exit 1
fi fi
pubkey_fp=$(get_project_info "$project" | jq -r '.pubkey // empty' 2>/dev/null) || pubkey_fp="" # Verify caller owns this project — pubkey must match stored value
if [ -n "$pubkey_fp" ]; then local stored_pubkey
pubkey_fp=$(ssh-keygen -lf /dev/stdin <<<"$pubkey_fp" 2>/dev/null | awk '{print $2}') || pubkey_fp="unknown" stored_pubkey=$(get_project_info "$project" | jq -r '.pubkey // empty' 2>/dev/null) || stored_pubkey=""
else if [ "$caller_pubkey" != "$stored_pubkey" ]; then
pubkey_fp="unknown" echo '{"error":"pubkey mismatch"}'
exit 1
fi fi
pubkey_fp=$(ssh-keygen -lf /dev/stdin <<<"$stored_pubkey" 2>/dev/null | awk '{print $2}') || pubkey_fp="unknown"
# Remove from registry # Remove from registry
free_port "$project" >/dev/null free_port "$project" >/dev/null
@ -335,13 +344,17 @@ main() {
do_register "$project" "$pubkey" do_register "$project" "$pubkey"
;; ;;
deregister) deregister)
# deregister <project> # deregister <project> <pubkey>
local project="$args" local project="${args%% *}"
if [ -z "$project" ]; then local pubkey="${args#* }"
echo '{"error":"deregister requires <project>"}' if [ "$pubkey" = "$args" ]; then
pubkey=""
fi
if [ -z "$project" ] || [ -z "$pubkey" ]; then
echo '{"error":"deregister requires <project> <pubkey>"}'
exit 1 exit 1
fi fi
do_deregister "$project" do_deregister "$project" "$pubkey"
;; ;;
list) list)
do_list do_list