Fix SSH key collision when installing sensor-proxy on multiple cluster nodes

When running install-sensor-proxy.sh on multiple nodes in a cluster, each
installation was removing all existing pulse-managed-key entries before
adding its own. This caused the following scenario:

1. Run script on node A: node A's key is added to all nodes
2. Run script on node B: node B's key replaces node A's key on all nodes
3. Result: node A's proxy can no longer SSH to other nodes

The fix changes the behavior to:
- Check if the specific SSH key already exists on the target
- Only add the key if not present (idempotent)
- Never remove existing pulse-managed-key entries

This allows multiple sensor-proxy installations to coexist in a cluster,
with each node's proxy key authorized on all nodes.

Related to #738
This commit is contained in:
rcourtman 2025-11-30 21:03:36 +00:00
parent f52bd26b08
commit 30c8440e17

View file

@ -244,31 +244,29 @@ END {
configure_local_authorized_key() { configure_local_authorized_key() {
local auth_line=$1 local auth_line=$1
local auth_keys_file="/root/.ssh/authorized_keys" local auth_keys_file="/root/.ssh/authorized_keys"
local tmp_auth
tmp_auth=$(mktemp)
mkdir -p /root/.ssh mkdir -p /root/.ssh
touch "$tmp_auth" touch "$auth_keys_file"
chmod 600 "$auth_keys_file"
if [[ -f "$auth_keys_file" ]]; then # Extract just the key portion (without forced command prefix) for matching
grep -vF '# pulse-managed-key' "$auth_keys_file" >"$tmp_auth" 2>/dev/null || true # Format: command="...",options KEY_TYPE KEY_DATA COMMENT
chmod --reference="$auth_keys_file" "$tmp_auth" 2>/dev/null || chmod 600 "$tmp_auth" local key_data
chown --reference="$auth_keys_file" "$tmp_auth" 2>/dev/null || true key_data=$(echo "$auth_line" | grep -oE 'ssh-[a-z0-9-]+ [A-Za-z0-9+/=]+')
else
chmod 600 "$tmp_auth" # Check if this exact key already exists (regardless of forced command)
if grep -qF "$key_data" "$auth_keys_file" 2>/dev/null; then
if [ "$QUIET" != true ]; then
print_success "SSH key already configured on localhost"
fi
return 0
fi fi
echo "${auth_line}" >>"$tmp_auth" # Key not present, add it
if mv "$tmp_auth" "$auth_keys_file"; then echo "${auth_line}" >>"$auth_keys_file"
if [ "$QUIET" != true ]; then if [ "$QUIET" != true ]; then
print_success "SSH key configured on localhost" print_success "SSH key configured on localhost"
fi fi
else
rm -f "$tmp_auth"
print_warn "Failed to configure SSH key on localhost"
print_info "Add this line manually to /root/.ssh/authorized_keys:"
print_info " ${auth_line}"
fi
} }
configure_container_proxy_env() { configure_container_proxy_env() {
@ -3076,10 +3074,6 @@ if [[ -n "$CLUSTER_NODES" ]]; then
continue continue
fi fi
# Remove any existing proxy keys first
ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 root@"$node_ip" \
"sed -i '/# pulse-managed-key\$/d' /root/.ssh/authorized_keys" 2>/dev/null || true
# Ensure wrapper compatibility on remote node (supports old installations) # Ensure wrapper compatibility on remote node (supports old installations)
# Create symlink if old wrapper exists but new path doesn't # Create symlink if old wrapper exists but new path doesn't
ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 root@"$node_ip" \ ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 root@"$node_ip" \
@ -3088,7 +3082,18 @@ if [[ -n "$CLUSTER_NODES" ]]; then
ln -sf /usr/local/bin/pulse-sensor-wrapper.sh /opt/pulse/sensor-proxy/bin/pulse-sensor-wrapper.sh; \ ln -sf /usr/local/bin/pulse-sensor-wrapper.sh /opt/pulse/sensor-proxy/bin/pulse-sensor-wrapper.sh; \
fi" 2>/dev/null || true fi" 2>/dev/null || true
# Add new key with forced command # Extract just the key portion for matching (ssh-TYPE KEY_DATA)
KEY_DATA=$(echo "$AUTH_LINE" | grep -oE 'ssh-[a-z0-9-]+ [A-Za-z0-9+/=]+')
# Check if key already exists on remote node
KEY_EXISTS=$(ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 root@"$node_ip" \
"grep -qF '$KEY_DATA' /root/.ssh/authorized_keys 2>/dev/null && echo 'yes' || echo 'no'" 2>/dev/null)
if [[ "$KEY_EXISTS" == "yes" ]]; then
print_success "SSH key already configured on $node_ip"
((SSH_SUCCESS_COUNT+=1))
else
# Add new key with forced command (appends, does not remove existing keys)
SSH_ERROR=$(ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 root@"$node_ip" \ SSH_ERROR=$(ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 root@"$node_ip" \
"echo '${AUTH_LINE}' >> /root/.ssh/authorized_keys" 2>&1) "echo '${AUTH_LINE}' >> /root/.ssh/authorized_keys" 2>&1)
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
@ -3103,6 +3108,7 @@ if [[ -n "$CLUSTER_NODES" ]]; then
print_info " Error details: $(echo "$SSH_ERROR" | head -1)" print_info " Error details: $(echo "$SSH_ERROR" | head -1)"
fi fi
fi fi
fi
done done
# Print summary # Print summary