[pve-devel] [PATCH cluster v2] add ssh command helpers

Thomas Lamprecht t.lamprecht at proxmox.com
Thu Feb 2 16:31:35 CET 2017


Add two helpers regarding ssh commands:
* get_ssh_base_cmd: returns a ssh command with various
  standard options set, useful if only the base ssh command is
  needed
* get_ssh_cmd: returns an string array for executing a command in a
  safe way on another pve node

Both function ensure that we use root as login name, use the
HostKeyAlias ssh option to ensure that host key verification uses
the provided hostname and not the IP address when checking if the
target node is a known_host, this avoids problems if we connect to a
node over another network (useful for dedicated migration network,
or if the user changes the cluster network).

Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---

changes since v1:
* as ssh option parser does no sane quote parsing just assert that we have a
  valid nodename and do no quoting at all
* to not escape host_addr as we build already the array here
* restructured comments

 data/PVE/Cluster.pm | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/data/PVE/Cluster.pm b/data/PVE/Cluster.pm
index 0edcc0a..4df4efd 100644
--- a/data/PVE/Cluster.pm
+++ b/data/PVE/Cluster.pm
@@ -1078,6 +1078,48 @@ sub get_local_migration_ip {
 
 # ssh related utility functions
 
+# a helper for getting a ssh command array with common options set.
+sub get_ssh_base_cmd {
+    my ($node, $host_addr) = @_;
+
+    my $ssh_cmd = ['/usr/bin/ssh', '-l', 'root', '-o', 'BatchMode=yes'];
+
+    # use HostKeyAlias option to identify a peer over its node name instead of
+    # its IP to allow connecting to cluster members through different networks
+    if (defined($node)) {
+	PVE::JSONSchema::pve_verify_node_name($node);
+	push @$ssh_cmd, '-o', "HostKeyAlias=$node";
+    }
+
+    push @$ssh_cmd, $host_addr if defined($host_addr);
+
+    return $ssh_cmd;
+}
+
+# prepares a command to run on a cluster member over ssh in a safe manner
+sub get_ssh_cmd {
+    my ($node, $cmd, $host_addr) = @_;
+
+    die "node parameter not defined in get_ssh_cmd\n" if (!defined($node));
+
+    if (!defined($host_addr)) {
+	$host_addr = remote_node_ip($node);
+    }
+
+    my $ssh_cmd = get_ssh_base_cmd($node, $host_addr);
+
+    if (!defined($cmd)) {
+	return $ssh_cmd;
+    } elsif (ref($cmd) && ref($cmd->[0])) {
+	die "array of arrays unsupported in ssh_command!\n";
+    }
+
+    my $cmdstr = PVE::Tools::cmd2string($cmd);
+    push @$ssh_cmd, '--', $cmdstr;
+
+    return $ssh_cmd;
+}
+
 sub ssh_merge_keys {
     # remove duplicate keys in $sshauthkeys
     # ssh-copy-id simply add keys, so the file can grow to large
-- 
2.1.4





More information about the pve-devel mailing list