#!/usr/bin/env bash set -euo pipefail umask 077 ssh_config=${SSH_CONFIG:-/etc/guanghu/nodes/ssh/config} package=${RECOVERY_PACKAGE:-/tmp/jd-recovery-controller.tgz} jd_ip=${JD_PUBLIC_IP:-} [[ -f "$ssh_config" && -f "$package" && "$jd_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || { echo "recovery bootstrap prerequisites missing or public address invalid" >&2; exit 70; } install -d -m 0700 /var/backups/guanghu/jd-recovery-bootstrap /var/lib/guanghu/recovery-public-keys stamp=$(date -u +%Y%m%dT%H%M%SZ) cp -a /root/.ssh/authorized_keys "/var/backups/guanghu/jd-recovery-bootstrap/authorized_keys.$stamp" nodes=( "BS-GZ-006:bs-gz-006" "BS-SG-001:bs-sg-001" "BS-SG-002:bs-sg-002" "BS-SG-003:bs-sg-003" "BS-SH-005:bs-sh-005" "ZY-SG-006:zy-sg-006" ) for binding in "${nodes[@]}"; do node_id=${binding%%:*} alias_name=${binding#*:} source_ip=$(ssh -G -F "$ssh_config" "$alias_name" | awk '$1=="hostname"{print $2; exit}') [[ -n "$source_ip" ]] || { echo "$node_id source address unavailable" >&2; exit 71; } cat "$package" | ssh -F "$ssh_config" -o BatchMode=yes -o ConnectTimeout=10 "$alias_name" \ "rm -rf /tmp/jd-recovery-package && install -d -m 0700 /tmp/jd-recovery-package && tar -xzf - -C /tmp/jd-recovery-package && install -d -m 0755 /opt/guanghu/jd-disaster-recovery && cp -a /tmp/jd-recovery-package/. /opt/guanghu/jd-disaster-recovery/ && chmod 0755 /opt/guanghu/jd-disaster-recovery/*.sh /opt/guanghu/jd-disaster-recovery/jd-recovery-runner" ssh -F "$ssh_config" -o BatchMode=yes "$alias_name" \ "install -d -m 0700 /etc/guanghu/secrets/jd-recovery; test -f /etc/guanghu/secrets/jd-recovery/to-jd-ed25519 || ssh-keygen -q -t ed25519 -N '' -C '${node_id}-recovery-to-JD-FD-PRIMARY' -f /etc/guanghu/secrets/jd-recovery/to-jd-ed25519; chmod 0600 /etc/guanghu/secrets/jd-recovery/to-jd-ed25519; cat /etc/guanghu/secrets/jd-recovery/to-jd-ed25519.pub" \ > "/var/lib/guanghu/recovery-public-keys/${node_id}.pub" pub=$(cat "/var/lib/guanghu/recovery-public-keys/${node_id}.pub") grep -qF "${node_id}-recovery-to-JD-FD-PRIMARY" /root/.ssh/authorized_keys || \ printf 'from="%s",restrict,command="/usr/local/libexec/guanghu/jd-recovery-entry" %s\n' "$source_ip" "$pub" >> /root/.ssh/authorized_keys ssh -F "$ssh_config" -o BatchMode=yes "$alias_name" \ "ssh-keyscan -H -T 5 '$jd_ip' > /etc/guanghu/secrets/jd-recovery/known_hosts 2>/dev/null; chmod 0600 /etc/guanghu/secrets/jd-recovery/known_hosts; printf '%s\\n' 'Host jd-recovery' ' HostName $jd_ip' ' User root' ' IdentityFile /etc/guanghu/secrets/jd-recovery/to-jd-ed25519' ' IdentitiesOnly yes' ' PasswordAuthentication no' ' KbdInteractiveAuthentication no' ' StrictHostKeyChecking yes' ' UserKnownHostsFile /etc/guanghu/secrets/jd-recovery/known_hosts' > /etc/guanghu/jd-recovery-ssh-config; chmod 0600 /etc/guanghu/jd-recovery-ssh-config" done chmod 0600 /root/.ssh/authorized_keys /var/lib/guanghu/recovery-public-keys/*.pub for binding in "${nodes[@]}"; do node_id=${binding%%:*} alias_name=${binding#*:} ssh -F "$ssh_config" -o BatchMode=yes "$alias_name" \ "ssh -F /etc/guanghu/jd-recovery-ssh-config -o BatchMode=yes -o ConnectTimeout=10 jd-recovery health-check >/dev/null" || \ { echo "$node_id reverse health check failed" >&2; exit 72; } echo "$node_id=RECOVERY_READY" done