[Libguestfs] [PATCH] v2v: Implement SSH password authentication for Xen and VMX over SSH.

Richard W.M. Jones rjones at redhat.com
Wed Apr 17 11:28:21 UTC 2019


For example:
$ virt-v2v -i vmx -it ssh -ip /tmp/passwd \
    'ssh://root@esxi/vmfs/volumes/datastore1/Windows/Windows.vmx' -o null
---
 v2v/cmdline.ml                |  2 +-
 v2v/input_libvirt_xen_ssh.ml  |  6 +++++-
 v2v/input_vmx.ml              | 30 +++++++++++++++++-------------
 v2v/input_vmx.mli             |  4 ++--
 v2v/virt-v2v-input-vmware.pod | 19 ++++++++++---------
 v2v/virt-v2v-input-xen.pod    | 25 ++++++++++++-------------
 6 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index ae7d80284..77700393f 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -556,7 +556,7 @@ read the man page virt-v2v(1).
         | Some `SSH -> Some `SSH
         | Some (`VDDK _) ->
            error (f_"only ‘-it ssh’ can be used here") in
-      Input_vmx.input_vmx input_transport arg in
+      Input_vmx.input_vmx input_password input_transport arg in
 
   (* Common error message. *)
   let error_option_cannot_be_used_in_output_mode mode opt =
diff --git a/v2v/input_libvirt_xen_ssh.ml b/v2v/input_libvirt_xen_ssh.ml
index 36ef5ea04..b68b5899d 100644
--- a/v2v/input_libvirt_xen_ssh.ml
+++ b/v2v/input_libvirt_xen_ssh.ml
@@ -66,7 +66,11 @@ object
         disk
       | { p_source_disk = disk; p_source = P_source_dev path }
       | { p_source_disk = disk; p_source = P_source_file path } ->
-         let nbdkit = Nbdkit.create_ssh ?bandwidth ~password:NoPassword
+         let password =
+           match input_password with
+           | None -> Nbdkit.NoPassword
+           | Some ip -> Nbdkit.PasswordFile ip in
+         let nbdkit = Nbdkit.create_ssh ?bandwidth ~password
                                         ?port ~server ?user path in
          let qemu_uri = Nbdkit.run nbdkit in
         { disk with s_qemu_uri = qemu_uri }
diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml
index 925d80ba8..5441bccb9 100644
--- a/v2v/input_vmx.ml
+++ b/v2v/input_vmx.ml
@@ -106,9 +106,9 @@ let remote_file_exists uri path =
     eprintf "%s\n%!" cmd;
   Sys.command cmd = 0
 
-let rec find_disks ?bandwidth vmx vmx_source =
-  find_scsi_disks ?bandwidth vmx vmx_source
-  @ find_ide_disks ?bandwidth vmx vmx_source
+let rec find_disks ?bandwidth input_password vmx vmx_source =
+  find_scsi_disks ?bandwidth input_password vmx vmx_source
+  @ find_ide_disks ?bandwidth input_password vmx vmx_source
 
 (* Find all SCSI hard disks.
  *
@@ -118,7 +118,7 @@ let rec find_disks ?bandwidth vmx vmx_source =
  *                        | omitted
  *   scsi0:0.fileName = "guest.vmdk"
  *)
-and find_scsi_disks ?bandwidth vmx vmx_source =
+and find_scsi_disks ?bandwidth input_password vmx vmx_source =
   let get_scsi_controller_target ns =
     sscanf ns "scsi%d:%d" (fun c t -> c, t)
   in
@@ -130,7 +130,7 @@ and find_scsi_disks ?bandwidth vmx vmx_source =
                             Some "scsi-harddisk"; None ] in
   let scsi_controller = Source_SCSI in
 
-  find_hdds ?bandwidth vmx vmx_source
+  find_hdds ?bandwidth input_password vmx vmx_source
             get_scsi_controller_target is_scsi_controller_target
             scsi_device_types scsi_controller
 
@@ -140,7 +140,7 @@ and find_scsi_disks ?bandwidth vmx vmx_source =
  *   ide0:0.deviceType = "ata-hardDisk"
  *   ide0:0.fileName = "guest.vmdk"
  *)
-and find_ide_disks ?bandwidth vmx vmx_source =
+and find_ide_disks ?bandwidth input_password vmx vmx_source =
   let get_ide_controller_target ns =
     sscanf ns "ide%d:%d" (fun c t -> c, t)
   in
@@ -151,11 +151,11 @@ and find_ide_disks ?bandwidth vmx vmx_source =
   let ide_device_types = [ Some "ata-harddisk" ] in
   let ide_controller = Source_IDE in
 
-  find_hdds ?bandwidth vmx vmx_source
+  find_hdds ?bandwidth input_password vmx vmx_source
             get_ide_controller_target is_ide_controller_target
             ide_device_types ide_controller
 
-and find_hdds ?bandwidth vmx vmx_source
+and find_hdds ?bandwidth input_password vmx vmx_source
               get_controller_target is_controller_target
               device_types controller =
   (* Find namespaces matching '(ide|scsi)X:Y' with suitable deviceType. *)
@@ -181,7 +181,7 @@ and find_hdds ?bandwidth vmx vmx_source
         match path, v with
         | [ns; "filename"], Some filename ->
            let c, t = get_controller_target ns in
-           let uri, format = qemu_uri_of_filename ?bandwidth
+           let uri, format = qemu_uri_of_filename ?bandwidth input_password
                                                   vmx_source filename in
            let s = { s_disk_id = (-1);
                      s_qemu_uri = uri; s_format = Some format;
@@ -209,7 +209,7 @@ and find_hdds ?bandwidth vmx vmx_source
  * This constructs a QEMU URI of the filename relative to the
  * vmx file (which might be remote over SSH).
  *)
-and qemu_uri_of_filename ?bandwidth vmx_source filename =
+and qemu_uri_of_filename ?bandwidth input_password vmx_source filename =
   match vmx_source with
   | File vmx_filename ->
      (* Always ensure this returns an absolute path to avoid
@@ -235,8 +235,12 @@ and qemu_uri_of_filename ?bandwidth vmx_source filename =
      let server = server_of_uri uri in
      let port = Option.map string_of_int (port_of_uri uri) in
      let user = uri.Xml.uri_user in
+     let password =
+       match input_password with
+       | None -> Nbdkit.NoPassword
+       | Some ip -> Nbdkit.PasswordFile ip in
 
-     let nbdkit = Nbdkit.create_ssh ?bandwidth ~password:NoPassword ~server
+     let nbdkit = Nbdkit.create_ssh ?bandwidth ~password ~server
                                     ?port ?user abs_path in
      let qemu_uri = Nbdkit.run nbdkit in
      qemu_uri, format
@@ -377,7 +381,7 @@ and find_nics vmx =
   let nics = List.map (fun (_, source) -> source) nics in
   nics
 
-class input_vmx input_transport arg =
+class input_vmx input_password input_transport arg =
   let tmpdir =
     let base_dir = (open_guestfs ())#get_cachedir () in
     let t = Mkdtemp.temp_dir ~base_dir "vmx." in
@@ -482,7 +486,7 @@ object
          None
       | None -> None in
 
-    let disks = find_disks ?bandwidth vmx vmx_source in
+    let disks = find_disks ?bandwidth input_password vmx vmx_source in
     let removables = find_removables vmx in
     let nics = find_nics vmx in
 
diff --git a/v2v/input_vmx.mli b/v2v/input_vmx.mli
index 34ec2a5c6..1570a2a93 100644
--- a/v2v/input_vmx.mli
+++ b/v2v/input_vmx.mli
@@ -18,6 +18,6 @@
 
 (** [-i vmx] source. *)
 
-val input_vmx : [`SSH] option -> string -> Types.input
-(** [input_vmx input_transport arg] sets up an input
+val input_vmx : string option -> [`SSH] option -> string -> Types.input
+(** [input_vmx input_password input_transport arg] sets up an input
     from vmware vmx file. *)
diff --git a/v2v/virt-v2v-input-vmware.pod b/v2v/virt-v2v-input-vmware.pod
index b3ebda182..3f9a0bc61 100644
--- a/v2v/virt-v2v-input-vmware.pod
+++ b/v2v/virt-v2v-input-vmware.pod
@@ -8,6 +8,7 @@ virt-v2v-input-vmware - Using virt-v2v to convert guests from VMware
 
  virt-v2v -i vmx
     -it ssh
+    -ip passwordfile
     'ssh://root@esxi.example.com/vmfs/volumes/datastore1/guest/guest.vmx'
     [-o* options]
 
@@ -132,21 +133,21 @@ If the vmx and vmdk files aren't available locally then you must
 I<either> mount the NFS storage on the conversion server I<or> enable
 passwordless SSH on the ESXi hypervisor.
 
-=head3 VMX: Passwordless SSH using ssh-agent
+=head3 VMX: SSH authentication
 
-You must also use ssh-agent, and add your ssh public key to
-F</etc/ssh/keys-root/authorized_keys> (on the ESXi hypervisor).
+You can use SSH password authentication, by supplying the name of a
+file containing the password to the I<-ip> option (note this option
+does I<not> take the password directly).
 
-After doing this, you should check that passwordless access works from
-the virt-v2v server to the ESXi hypervisor.  For example:
+If you are not using password authentication, an alternative is to use
+ssh-agent, and add your ssh public key to
+F</etc/ssh/keys-root/authorized_keys> (on the ESXi hypervisor).  After
+doing this, you should check that passwordless access works from the
+virt-v2v server to the ESXi hypervisor.  For example:
 
  $ ssh root at esxi.example.com
  [ logs straight into the shell, no password is requested ]
 
-Note that password-interactive and Kerberos access are B<not>
-supported.  You B<have> to set up ssh access using ssh-agent and
-authorized_keys.
-
 =head3 VMX: Construct the SSH URI
 
 When using the SSH input transport you must specify a remote
diff --git a/v2v/virt-v2v-input-xen.pod b/v2v/virt-v2v-input-xen.pod
index 4bb5d2dc2..bafeabf62 100644
--- a/v2v/virt-v2v-input-xen.pod
+++ b/v2v/virt-v2v-input-xen.pod
@@ -5,7 +5,9 @@ virt-v2v-input-xen - Using virt-v2v to convert guests from Xen
 =head1 SYNOPSIS
 
  export LIBGUESTFS_BACKEND=direct
- virt-v2v -ic 'xen+ssh://root@xen.example.com' GUEST_NAME [-o* options]
+ virt-v2v -ic 'xen+ssh://root@xen.example.com'
+          -ip passwordfile
+          GUEST_NAME [-o* options]
 
 =head1 DESCRIPTION
 
@@ -14,24 +16,21 @@ RHEL 5 Xen, or SLES and OpenSUSE Xen hosts.
 
 =head1 INPUT FROM XEN
 
-=head2 Set up ssh-agent access to Xen host
+=head2 SSH authentication
 
-Currently you must enable passwordless SSH access to the remote Xen host
-from the virt-v2v conversion server.
+You can use SSH password authentication, by supplying the name of a
+file containing the password to the I<-ip> option (note this option
+does I<not> take the password directly).
 
-You must also use ssh-agent, and add your ssh public key to
-F</root/.ssh/authorized_keys> (on the Xen host).
-
-After doing this, you should check that passwordless access works
-from the virt-v2v server to the Xen host.  For example:
+If you are not using password authentication, an alternative is to use
+ssh-agent, and add your ssh public key to
+F</root/.ssh/authorized_keys> (on the Xen host).  After doing this,
+you should check that passwordless access works from the virt-v2v
+server to the Xen host.  For example:
 
  $ ssh root at xen.example.com
  [ logs straight into the shell, no password is requested ]
 
-Note that password-interactive and Kerberos access are B<not>
-supported.  You B<have> to set up ssh access using ssh-agent and
-authorized_keys.
-
 With some modern ssh implementations, legacy crypto policies required
 to interoperate with RHEL 5 sshd are disabled.  To enable them you may
 need to run this command on the conversion server (ie. ssh client),
-- 
2.20.1




More information about the Libguestfs mailing list