Remotely Mirroring a Disk from Linux
In Linux you can make or restore an image of a drive with the dd command. For instance, creating a disc iso of a DVD could be done by specify the block device for the dvd-rom as the input file and a new file for the output file.
dd if=/dev/sr0 of=/home/jdoe/cdrom.iso
Another frequent use would be to make a bit-for-bit copy of a disk as a backup.
dd if=/dev/sdb of=/dev/sdc
What happens if you need to make a bit-for-bit copy of a drive to a remote machine though? In the particular case that I found myself in, I wanted to make a perfect copy of a server so that I could simulate a series of potentially error-prone upgrades. The target machine was a virtual machine, so there wasn’t an actual drive that to plug in to the source machine. To make matters a little more difficult, at the time there wasn’t a network share with enough available space to hold the full disk image. For a case like this, I really needed to be able to copy the hard drive in one machine directly to another.
The goal of cloning a disk despite being on a separate machine is actually rather simple once you know a few tricks. If either ‘if’ or ‘of’ is missing, dd’s behaviour is to fall back onto standard input and standard output, respectively. On its own, that wouldn’t help matters very much, but in our case we can take advantage of ‘nc’ to tie everything together. ‘nc’ is an application that allows a user to redirect stdout across a network, or to use network traffic as the source for stdin. With this information, we can mirror a remote drive with little trouble. 1
As a quick note: though the following commands would likely still work on a mounted file system, it isn’t without some degree of unnecessary risk. If possible, I would personally recommend running each of these commands from a live cd. Also, they need to be run as root.
To start with, we need to tell the target machine to listen on a given port (e.g. 12345) and to pipe the network traffic to dd for use as input.
nc -l 12345 | dd of=/dev/sda
Once our target machine is listening, we can tell the source machine to read the disk, and to pipe it to ‘nc’ so that it can be sent across the network to our other machine.
dd if=/dev/sda | nc machineaddress.example.com 12345
At this point, just sit and wait. When the command line returns, you should have a fully mirrored disk on the target machine.
Since we’re listening to arbitrary network traffic, I obviously wouldn’t advice performing this on a hostile network. When crossing an unsecured network, I’d advise passing all of the traffic through SSH via port forwarding. ↩︎