Ubuntu 12.04 Decrypt Drive Remotely

It’s been a while since I setup a new system, and although I had to look into decrypting a drive remotely a few months back when one of my servers refused the key, it’s pretty much been just as long since I really had to setup remote decryption from scratch.

Tonight I’m building up a new system to replace an existing server. The reason is it’s undergone several major distribution updates without a full reinstall and I think it starts getting messy after a while. Put that together with X refusing to startup and display my cctv stuff after updates a few months back (see other post), I really think it’s time for a clean server.

I’m not going to run through all the step for my install here, it’s pretty common Ubuntu 12.04 Alternative CD, Encrypted root, swap and data running on LVM and a /boot that’s the first partition on the disk.

Now I’ve got my system up and running, I want to be able to remotely access it while it’s booting to provide the decryption key and then let it continue. I do this on all my system, and although I’m sure you don’t need all the commands when it’s booting I use them just to be sure.

I’m making the following assumptions, you will need to adjust accordingly:-
Your machine is already on your network.
You have SSH access to your machine.
You have root privileges.

First thing is to install dropbear and busybox

apt-get install dropbear busybox
It says above it’s going to remove busybox-static and ubuntu-standard, I personally dont have any issues with this, but you may wish to search google for what these packages do (or any packages your system says it’s removing) before you continue.

At this point I reboot my system (you wont have any remote access yet), purely because I’d already run updates and forgotten to reboot before I started this blog.

When the system was rebooting, pressing escape when being prompted for the decryption password showed me the interface configuration.
I was able to make an SSH connection to the dropbear server, but unable to authenticate. Also as this was a DHCP ip address, it’s not really much good as a remote recovery system.

Next we need to edit initramfs.conf
nano -w /etc/initramfs-tools/initramfs.conf
Here’s how my file looks before editing:-

Locate the line DEVICE=
and adjust to be DEVICE=eth0
then add a line IP=192.168.yyy.253::192.168.yyy.1:255.255.255.0:daedalus.xxxxxxxxxx.local:eth0

Replacing the yyy with your own network value and xxxxxxx with your own domain
The IP= is separated into the following options IP ADDRESS :: GATEWAY : SUBNET : COMPUTERNAME : INTERFACE
There’s an option between IP and GATEWAY, {review} I need to add in explanation for but wont affect anything left empty.

Personally I use the address .253 as it’s outside my DHCP scope and not an address I’m using. I also have it setup on my router to forward SSH traffic to the .253 IP. Once the machine has boot it drops the .253 address so is only accessible externally while booting.

Save and Exit this file. CTRL+X. Followed by Y to save. Then ENTER to keep the same name.

Now we’re going to add an authorized key. First
cd /etc/initramfs-tools/root/.ssh
then
cat authorized_keys

As you can see it already has an entry from the dropbear installation. However we’re going to replace this with a new key. First we must generate the key. On your windows machine open PuttyGen from your start menu:-

Press the Generate button (I increased the bits to 2048 first).

You will be asked to move the mouse randomly over the blank area until the green bar completes.
Then a key is generated:-

Once your key generation has complete, save the public key. How you choose to secure this is upto you, personally I just keep it saved in my documents, it’s not decrypting the hard drive just getting me access to do so.
With that saved right click the public key and Select All, then Copy.

Now go back to your Putty SSH connection window and nano -w authorized_keys

As you can see the existing key is already in place. You can delete this line entire if you wish CTRL+K. If you didn’t delete just move to the next line. Once on a free line simply right click to Paste.

As you can see Nano has scrolled to the end of my line, so I can only see the Key comment. You can now Save and Exit this file. CTRL+X. Followed by Y to save. Then ENTER to keep the same name.

Now that we’ve made adjustments to the boot configuration you need to rebuild the boot files.

Type update-initramfs -u
UPDATE:- you may encounter the error “cp: cannot stat `/lib/x86_64-linux-gnu/libnss_*’: No such file or directory” I cover this in another post http://blog.starbyte.co.uk/cp-cannot-stat-liblibnss_-no-such-file-or-directory/
Once complete you can reboot your system ready to test.
When you system is rebooting and sat prompting for the password, press the Esc key and ensure that the network configuration is correct.

Now we need to connect to the system from our windows machine. Open Putty and start a new connection:-

Click on Data on the left hand side:-

Fill in the Auto-login username as ‘root’. Then expand SSH and select Auth:-

Browse to the private key you saved earlier.
You can either press Open to connect now, or return to the Session screen and Save the session for easy access later (I didn’t).
Once connecting you should be prompted to accept the fingerprint:-

You should now be connected to your server:-

You may wish to use the above to create new keys from each machine you may connect from (Desktop, Leptop, etc) and append them to the authorized_keys file. If one of your systems is then lost you can merely remove the key and regenerate the initramfs.

Now that we have our connection, we need to supply the password. Over the last few years I’ve come across various different methods. Some pipping the password into a hook, others killing the script currently asking for the password and manually unlocking the drive. The later method is the one I’ve always used, mainly because I have multiple encrypted drives and unlock each of them manually.
{sidenote: rebooting from within busybox did restart the machine, but left it on the grub selection screen no countdown. Encountered a halted boot before but didn’t know why. Need to ensure grub always has default countdown}

I’ve just run through a few quick tests of simply pipping the password and it still doesn’t work for me. So here goes with the 2nd longer process. I’d like to thank whoever I originally found this from, but I have no idea. Their steps were extremely well written (unlike mine).

First we need to stop the current script running looking for the password:-

Type ps | grep -i crypt
This will list the running crypt processes. We’re interested in the script in local-top. It’s process number is 227, so we issue : kill 227

Now that we’ve issued the kill, we need to wait a while for the system to drop to a prompt. Type ps | grep -i wait
As above you will see the wait-for-root script running, and it has a value of 30 (meaning 30 seconds). If you wait 30 seconds and rerun ps | grep -i wait, you will find it’s no longer running.
You can now continue to unlock your drive(s)

In the image above you can see where wait-for-root was running, then the following check it wasn’t. Followed by the command I use to unlock my drive.
Type /sbin/cryptsetup luksOpen /dev/zzzz zzzz_crypted
Replacing the zzzz with your drive and partition. If your unsure you can always double tab for suggestions.
You wont get any password feedback, so if you think you’ve made a mistake hold the backspace key for a while then type again.
If your password is accepted you will be returned to a prompt.
At this stage we tell the shell to kill itself:-

Use ps | grep -i sh to find the process number (271in the above) then kill -9 271
Follow by exit
If all has gone well I normally receive:-

Normally if I haven;t received this, I’ve done something wrong. At which point physical access is required to correct my mistake (or get someone to reset the machine and try again).

At some point I may make a script or 2 to run and see if it hasn’t been unlocked within 30 mins to reset. This may give me a bit of resilience is screwing it up. After a few times of unlocking though you really do remember the commands. I did save a text file into the root folder /etc/initramfs/root/guide.txt
(Thinking of that now I’ll just paste that below – again thanks to whoever originally wrote it. but after a few times I didn’t need it anymore.)

1) run “ps aux” and located the process id for the /scripts/local-top/cryptroot script
2) run “kill -9 pid” replacing pid with the process id you found in step 1
3) run “ps aux” again and look for a wait-for-root script and note the timeout on the command line
4) twiddle you thumbs for that many seconds – what will happen is that script will exit and start an initramfs shell
5) run “/scripts/local-top/cryptroot” and wait for it to prompt for your unlock passphrase
6) enter the unlock passphrase and wait for it to return you to the busybox shell prompt
6.5) Unlock each drive to get a clean boot, sda,sdb,sdc,sdd as sda_crypt,sdb_crypt,sdc_crypt,sdd_crypt
7) run “ps aux” again and locate the process id of “/bin/sh -i”
8) run “kill -9 pid” using the process id you found from step 7

As you can see I added 6.5 to remind me to decrypt other drives. Doing this means their mounted as the system is coming up.
That’s pretty much it. You should now be able to remotely unlock your encrypted drives.I realised towards the end my internal IP is on the top of the putty windows, but I only really masked it from the examples to highlight a change. I hope people find this somewhat helpful. Any feedback welcome, I’m now off to start copying data over. and btw I’ve changed the keys incase anyone worries for me 🙂

UPDATE:-
I’m just running through this on 12.10 and ran into a problem whereby the ip address yyy.253 wasn’t being released. Some searching suggested that network/interfaces will be ignored because of checks in the process that fail. This wasn;t the case for me, I was getting 2 addresses on the interface. The solution was to add:-

pre-up ip addr flush dev eth0

To /etc/network/interface to clear eth0 before applying the new IP.

Logwatch pam_unix unmattched entries

Ok this post will need some work to pad it out and make more sense.
I’ve been running logwatch for years and a few months back had to reconfigure some of the configuration files after splitting out syslog to multiple files to make them easier to read i.e. putting all cron stuff into cron.log bind9 into named.log etc.
After those simple changes my logwatch email went from a hundred or so lines to thousands and until now I haven’t had time to look into it.
All the unmattched entries were against the cron log and all being pam_unix stuff as cron goes off running stuff.

As I didn’t get these before I was a bit confused but looking around at the configs and services there is a pam_unix.conf in the services. So after more changing and fiddling about I was still getting over 7k lines of logwatch email and no idea why. but tonight on looking closer at the email it’s the cron service that’s marking the entries as unmattched not as I thought that pam_unix wasn’t going near the file (to be fair it probably isn’t, but that’s not why the lines are being included in the email).

I wont run through my entire process of narrowing it down, to be fair I couldn’t remember every step I’ve done tonight anyway. Bottom line was modifying the following:-

/usr/share/logwatch/scripts/services/cron

find the lines:

} elsif ($ThisLine =~ /FAILED to authorize user with PAM (User not known to the underlying authentication m$
      $PAMAUTHErr++;

underneath insert the lines:-

} elsif ($ThisLine =~ /pam_unix/) {
      $PAMUNIXAUTHErr++

then search for:-

if ($PAMAUTHErr) {
      printf "nPAM autentification error: " . $PAMAUTHErr . " time(s)n";
}

and underneath insert the lines:-

if ($PAMUNIXAUTHErr) {
      printf "nPAM_UNIX autentification error: " . $PAMUNIXAUTHErr . " time(s)n";
}

Save the file, and that’s it.
Now instead of having 7k extra lines of pam_unix stuff, I have one line summing up.

As a side problem, I’m now receiving clamav info when I wasn’t before and dont run clamav or have the logfiles mentioned. that’s something to look at tomorrow, but at least the logwatch is back down to one small scrollable window so even with the clamav annoying stuff I’m happy to be able to read the logwatch out easily again.

As the top says this needs some cleaning up on edit. hopefully get around to it in the next few days.

Ubuntu Graphics Problems

I ran into this problem a while back on my server but it’s never really affected me as I dont generally use the console.

After running updates a good few months back, my system stopped giving me any output. It wouldn’t load to X or a console and even stopped showing the splash screen and the boot info.

The way I was getting around it was to just use an earlier Kernel version during boot. But tonight while doing some work this little bugger got me again.

After hours working through numerous problems I’ve just left unresolved this one finally needed to be solved. Previously I’d just SSH’d to the machine having no console, started the xlib_shm stuff and up popped the CCTV view and I’d just leave that running, but tonight even that wouldn’t work.

I found the following info while trawling the interweb for fixes:-
The problem seems to start after Kernel 2.6.38-8 (that’s the last one I can boot without problems)
It’s related to the ATI graphics card and drivers
*ERROR* Failed to register bit i2c VGA_DDC was showing up in the syslog

I found info in several bugs saying to add this ‘i2c_algo_bit.bit_test=0’ but didn’t actually say where.
https://bugzilla.novell.com/show_bug.cgi?id=691052
http://lists.freedesktop.org/archives/dri-devel/2011-June/012061.html
http://forums.opensuse.org/english/get-technical-help-here/install-boot-login/459015-no-display-after-online-update-4.html

So I opted to add ‘i2c_algo_bit.bit_test=0’ into the grub config for the lastest kernel, so my grub line now looks like ‘linux   /vmlinuz-2.6.38-15-generic root=/dev/mapper/VG-LV_Root ro   quiet splash i2c-algo-bit.bit_test=0 vt.handoff=7’

Rebooting kept my splashscreen, and presented me with my console once again. and now my xlib_shm was also working once again.

But as I’m very likely to forget after a bunch more remote updates, I thought it best to make it a little more permanent, so I edited /etc/default/grub and amended the OPTIONS line to read ‘GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash i2c-algo-bit.bit_test=0″‘
a quick run of update-grub and my entire config is updated.
This should survive future updates and keep me with a working console should I need it.

Raspberry PI

Not sure if anyone reads these at all, but thought I’d make a comment as I go.
I’m waiting on news from Raspberry PI to know when they’re being launched. At first they’re going to have a run of just 1000 units, I have a load of ideas I’d like to try and do on it from some home automation, security system, all the way to maybe getting zoneminder running on it with a webcam.
It looks a fantastic little board and I think the idea of putting them into schools and letting kids play, program and create it a great one. I wish they’d done that kind of thing when I was in school. I wanted to do the computer control part of CDT but the teacher wouldn’t run it, or even let me do it as an extra after school in my own time.

Still I’ve done little bits and pieces as I go, but I’m really looking forward to the Raspberry PI coming out and getting to just play and experiment again. After looking on the forums yesterday I doubt very much that I’d be in with a chance of getting one of the 1st 1k, and it’s looking like a good couple of runs of 1k each are going to shift like hot cakes, but I’ll be looking out hoping the site doesn’t crash as soon as I know they’re out.

Sync Timstamp in Linux

First you have to run something along the lines of:-

find . -type f -print -exec stat -t -c '%y' {} ; > /tmp/original_dates.txt

On the first set of files, the ones with the correct time.
Once that is complete you run:-

cat /tmp/original_dates.txt | (while read FILE && read DATE; do echo $FILE; echo $DATE; DATE2=`date -d "$DATE" +%Y%m%d%H%M.%S`; touch -t $DATE2 "$FILE"; done)

On the second set of files. This will then set their date as the original.