Recover a broken disk using dd and FreeBSD

Hard drives break, that’s a fact of life. With the ever increasing size of individual disks, and people’s habit of stuffing spinning metal into USB enclosures, both the likelyhood and the impact of failures increases (read up on what a gyroscope is). This article describes a generic method of recovery that should work on a disk as long as it’s at least partially readable by an operating system. The method itself requires a UNIX-like operating system such as Linux or FreeBSD (maybe the Windows 10 Linux subsystem works nowadays, I don’t know, crazy times), the dd command and an amount of free storage at least the size of the whole disk to be recovered.

The idea behind this method is to copy every single bit off the disk into a so-called image file. This technique is often used to create full-system backups and installation images. It allows a single installation of a complete operating system and all its files to be cloned onto as many target computers as necessary without going through the lengthy installation process.

With a broken disk, creating an image gives us a verbatim copy of the disk on which we can attempt recovery using a diversity of tools without affecting the actual drive itself. This allows us to experiment, all while in the certainty that none of our actions will be irreversible.

I’m using a FreeBSD-based NAS-system as my storage array, as this is the only place big enough to hold the full contents of a broken 2TB drive I was given. Apart from the obvious need for large storage, my NAS storage system runs on ZFS which allows me to create file system snapshots. It’s this snapshotting feature that allows me to make changes to my image file and revert them whenever needed, without requiring multiple 2TB copies of the file.

Creating the image is done by using the dd command. When you attach the broken drive to your system, the operating system will assign a node to it under the /dev directory in your filesystem. This will get logged in /var/log/messages or /var/log/syslog depending on your operating system. In my case, the broken drive was assigned /dev/da0 and I’m storing the image in /backup. The dd command to create the image is:

dd if=/dev/da0 of=/backup/brokendisk.img conv=noerror,sync

What this does, is start reading the broken drive from start to finish while writing everything it reads out to the brokendisk.img file in /backup. The conv=noerror,sync part makes sure dd continues whenever it encounters errors. The sync bit puts zeroes in the place of any bits that could not be read from the broken disk.

Note: this process can take extremely long. Increasing dd’s block size speeds the process up considerably, but that also increases your potential data loss. When dd encounters an error, it replaces the entire current block with zero’s. That means that if you’re using a 1MB block size and only a single 4KB sector of your disk is bad, you’d lose 996KB’s of data to unnecessary zeroing. Just so you know what to expect: the above command takes three weeks to complete on my system cloning a 2TB drive.

Then end result of this is that you’ll have a completely virtual copy of the broken disk, exactly as your computer would see the physical device. Once the process finishes, I would urgently advise you to take a snapshot of the filesystem on which you stored the backup image before you do anything else with it.

Recovering the lost files

Now that you have a virtual copy of a broken disk, you have a number of options to recover it. Which one is best depends heavily on what was on the disk to begin with. In my case I’m working with a 2TB NTFS drive salvaged from a Windows 8.1 machine. Recovery usually works best with the native tools of the platform a drive was formatted with, so I’ll be wanting to use Windows to recover this particular drive. So now what? Because the image file is quite firmly stored on a FreeBSD server, which is mostly Windows-incompatible.

So we’re looking to trick an existing Windows system into accepting a remotely storaged disk image as if it were a locally attached, physical drive. Fortunately there’s a network protocol available to do just that and it works on both FreeBSD and recent Windows versions: enter iSCSI.

The iSCSI protocol works with initiators and targets. Targets are image files or devices that live inside a remote server, while initiators are the clients that consume these targets af if they were local drives. So to get what we want, we need to set up an iSCSI target on our FreeBSD box and prepare a Windows system to act as an initiator.

FreeBSD as an iSCSI target

On the FreeBSD side of things, you’ll need to set up the ctld service to have it act as an iSCSI target. Create a file named /etc/ctl.conf and fill it with something like this:

portal-group pg0 {
  discovery-auth-group no-authentication
  listen 0.0.0.0
}

target iqn.2017-02.com.area536.istgt:broken {
  auth-group no-authentication
  portal-group pg0
  lun 0 {
    path /backup/brokendisk.img
  }
}

Note that the above is an insecure setup and you should only deploy ctld like this from within a fully trusted network. I’ll assume you’re doing this from either an isolated lab environment or the privacy of your home, but don’t deploy iSCSI like this in production environments. Add a line to /etc/rc.conf to enable the ctld service:

ctld_enable="YES"

Now you can start the iSCSI target by starting the ctld service:

/etc/rc.d/ctld start

This starts your service and makes the drive image available for use over the network.

Connect Windows to the iSCSI target by starting the iscsictl.exe Control Panel applet. Upon first start it’ll ask if you want to start and enable the iSCSI service. You’ll need to do so, or this whole trick won’t work. Once the applet loads, it’ll show you a window with a bunch of tabs. In the ‘Target’ tab, fill in the IP-address of your FreeBSD box and hit Quick Connect. The rest of this should be mostly self-explanatory: you’ll see any iSCSI targets available on the FreeBSD box and can pick one to connect to.

Once you’re connected, you’ll be able to use just about any hard drive recovery tool under the sun from within your Windows environment just as if you were using a real physical drive. These tools themselves are a bit beyond the scope of this article, as is the generic process of recovering the plethora of things that could be wrong with any random hard drive.

One important thing to note, though, is the rollback procedure in case you do something less-than-clever in the recovery process. Remember that filesystem snapshot you made earlier on the FreeBSD box? Turn off your Windows machine completely. Stop the ctld service on FreeBSD. Once the ctld services is completely done, roll back the filesystem snapshot to its previous state and start again. Fire up the ctld service, reconnect to iSCSI from your Windows box and try a new recovery strategy.

By using this method you’ll have a non-destructive way of using multiple avenues to recover lost data. It also prevents your recovery tools from choking on physical hardware errors because those simply aren’t there anymore. They just got replaced with zero’s, which still means you lost data but at least you have some hope of recovering the bits that were actually salvageable.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.