diff --git a/migrator.py b/migrator.py index 618258c..80b8090 100644 --- a/migrator.py +++ b/migrator.py @@ -164,51 +164,97 @@ class Migrator: return True def _preserve_ssh_keys(self, nodes: list, dry_run: bool) -> bool: - """Copy /etc/pve/priv/authorized_keys to ~/.ssh/ on all nodes. + """Ensure SSH keeps working after pve-cluster stop. When pve-cluster (pmxcfs) is stopped, /etc/pve gets unmounted and - the cluster SSH keys disappear. This breaks SSH between nodes. - We temporarily copy them to ~/.ssh/authorized_keys so SSH keeps working. + the cluster SSH keys in /etc/pve/priv/authorized_keys disappear. + This breaks SSH between nodes. + + Fix: Copy PVE keys to ~/.ssh/authorized_keys AND ensure sshd is + configured to actually check that file (Proxmox may only check /etc/pve/). """ for node in nodes: if dry_run: print(f" [{node.name}] Würde SSH-Keys sichern") continue - # Append pve keys to ~/.ssh/authorized_keys (avoid duplicates) - cmd = ( + # Step 1: Copy PVE keys to ~/.ssh/authorized_keys + copy_cmd = ( + "mkdir -p /root/.ssh && " + "cp /root/.ssh/authorized_keys /root/.ssh/authorized_keys.pre_migration 2>/dev/null; " "if [ -f /etc/pve/priv/authorized_keys ]; then " - " mkdir -p /root/.ssh && " - " cp /root/.ssh/authorized_keys /root/.ssh/authorized_keys.pre_migration 2>/dev/null; " " cat /etc/pve/priv/authorized_keys >> /root/.ssh/authorized_keys && " - " sort -u -o /root/.ssh/authorized_keys /root/.ssh/authorized_keys && " + " sort -u /root/.ssh/authorized_keys > /root/.ssh/authorized_keys.tmp && " + " mv /root/.ssh/authorized_keys.tmp /root/.ssh/authorized_keys && " " chmod 600 /root/.ssh/authorized_keys && " - " echo ok; " + " echo keys_copied; " "else " " echo no_pve_keys; " "fi" ) rc, stdout, err = self.ssh.run_on_node( - node.ssh_host, cmd, node.is_local + node.ssh_host, copy_cmd, node.is_local ) - if rc == 0 and "ok" in stdout: - print(f" [{node.name}] SSH-Keys gesichert") + if "keys_copied" in stdout: + print(f" [{node.name}] PVE-Keys nach ~/.ssh/authorized_keys kopiert") elif "no_pve_keys" in stdout: print(f" [{node.name}] Keine PVE-Keys gefunden (übersprungen)") else: - print(f" [{node.name}] WARNUNG SSH-Keys: {err}") + print(f" [{node.name}] WARNUNG Key-Kopie: rc={rc} {err}") + + # Step 2: Ensure sshd checks ~/.ssh/authorized_keys + # Proxmox sshd_config may only list /etc/pve/priv/authorized_keys + sshd_cmd = ( + "cp /etc/ssh/sshd_config /etc/ssh/sshd_config.pre_migration && " + "if grep -q '^AuthorizedKeysFile' /etc/ssh/sshd_config; then " + " if grep '^AuthorizedKeysFile' /etc/ssh/sshd_config | grep -q '.ssh/authorized_keys'; then " + " echo sshd_already_ok; " + " else " + " sed -i '/^AuthorizedKeysFile/s|$| .ssh/authorized_keys|' /etc/ssh/sshd_config && " + " systemctl reload sshd && " + " echo sshd_modified; " + " fi; " + "else " + " echo sshd_already_ok; " + "fi" + ) + rc2, stdout2, err2 = self.ssh.run_on_node( + node.ssh_host, sshd_cmd, node.is_local + ) + if "sshd_modified" in stdout2: + print(f" [{node.name}] sshd_config angepasst (.ssh/authorized_keys hinzugefügt)") + elif "sshd_already_ok" in stdout2: + print(f" [{node.name}] sshd_config OK") + else: + print(f" [{node.name}] WARNUNG sshd: {err2}") + + # Step 3: Verify SSH will still work after pve-cluster stop + # Test that ~/.ssh/authorized_keys is readable on all remote nodes + print(" [Verifikation] Prüfe ob SSH-Keys korrekt gesichert sind...") + for node in nodes: + if node.is_local: + continue + rc, stdout, _ = self.ssh.run_on_node( + node.ssh_host, + "wc -l /root/.ssh/authorized_keys 2>/dev/null || echo 0", + False, + ) + key_count = stdout.strip().split()[0] if stdout.strip() else "0" + print(f" [{node.name}] authorized_keys: {key_count} Zeilen") + return True def _restore_ssh_keys(self, nodes: list): - """Restore original ~/.ssh/authorized_keys after migration.""" + """Restore original ~/.ssh/authorized_keys and sshd_config after migration.""" for node in nodes: new_host = node.new_ip if not node.is_local else node.ssh_host cmd = ( "if [ -f /root/.ssh/authorized_keys.pre_migration ]; then " - " mv /root/.ssh/authorized_keys.pre_migration /root/.ssh/authorized_keys && " - " echo restored; " - "else " - " echo no_backup; " + " mv /root/.ssh/authorized_keys.pre_migration /root/.ssh/authorized_keys; " + "fi; " + "if [ -f /etc/ssh/sshd_config.pre_migration ]; then " + " mv /etc/ssh/sshd_config.pre_migration /etc/ssh/sshd_config && " + " systemctl reload sshd 2>/dev/null; " "fi" ) self.ssh.run_on_node(new_host, cmd, node.is_local)