Tuesday, February 23, 2016

Unpack a debian .deb package

When you are building .deb's it's handy to be able to unpack them to check the contents, especially postinst and similar scripts. This command gives you all the package contents:

dpkg-deb -R google-chrome-stable_current_amd64.deb .

The postinst and other package-related scripts will be in the DEBIAN directory:

$ ls DEBIAN/
control  postinst  postrm  prerm

Creating a debian package that can run with System V, Upstart, or Systemd

We now have a gaggle of ways daemons can be run on linux, and ubuntu in particular. I want my .deb to be installable on a wide range of ubuntu and debian systems, some of them quite old, so here's my solution.

The general idea is to provide files for all three systems, and pick the right one to use at post-install time as described here, but with the added complication that we need systemd as well (for Ubuntu after 15.10, which uses systemd by default).

My postinstall file looks like this:

case "$1" in
    ${DAEMON} ${DAEMON_ARGS} "--install"

    if [ -x /sbin/initctl ] && /sbin/initctl version | /bin/grep -q upstart; then
      # Early versions of upstart didn't support restarting a service that
      # wasn't already running:
      # https://bugs.launchpad.net/ubuntu/+source/upstart/+bug/430883
      /usr/sbin/service myservice stop 2>/dev/null || true
      /usr/sbin/service myservice start 2>/dev/null
    elif [ -x /bin/systemctl ]; then
      # Systemd
      /bin/systemctl enable myservice
      /bin/systemctl restart myservice
    elif [ -x "/etc/init.d/myservice" ]; then
      update-rc.d myservice defaults >/dev/null
      invoke-rc.d myservice start || exit $?


    echo "postinst called with unknown argument \`$1'" >&2
    exit 1

If you're using debhelper you need to make sure you're using at least version 9.20130504, when systemd support was added. Then, just like you do for Upstart and System V you need to put your systemd unit file in:


and it will be copied into


in the package build directory as described here.

Friday, February 19, 2016

Storing and using GPG keys on the Yubikey

I wanted to move to using GPG keys for encryption and signing stored on a Yubikey 4. There's a bunch of HOWTOs out there, I'll put a pile of links at the end.

I started out making a bootable Ubuntu USB drive with the intention of generating the master key on there while offline, putting the subkeys on the Yubikey, and only importing the public key of the master onto the laptops I would use for day-to-day sign/decrypt. This way the master secret key is never on an internet connected machine. This approach is described in more detail here.

I basically gave up on trying to make the yubikey talk to gpg correctly on linux and used a mac (you can read the whole saga after this). So I followed Trammel's excellent instructions with the following modifications:
  1. Disconnect from the network.
  2. Follow Trammel's instructions. If you have the Yubikey 4 you can use 4096 bit keys. ykpersonalize didn't work ("no yubikey present"), so I had to install the Yubikey NEO Manager, which for some reason requires a reboot.
  3. Using the GUI export the key a second time into a file that is just the public key.
  4. Copy pub/private exported key and revocation cert onto USB key.
  5. Use "srm -sz" to remove the exported key and cert, leave the exported public key.
  6. Delete the key (public and secret) from the GPG keychain using the GUI. The only copy of the master secret key is now on the USB.
  7. Import the public key using the GUI.
The command:
gpg --card-status
Should now show "sec#" as described here, to indicate the master secret key isn't present. Now your key is ready to use. I seem to be having similar problems as described here:
I'll update this post when I know more.

The Linux GPG2 and yubkiey saga

Installing gpg2 (required for yubikey "card" support) turned out to be really painful. Ubuntu ships with gpg 1.4, so I ended up downloading a ton of packages off the gpg ftp server, verifying the signature of each one and doing the configure, make, make install dance. It took ages. Update: I didn't think to look for a gpg2 package, turns out there is one, so this was a big waste of time :)

Then I still had to download and install the yubico tools for interacting with the card. I got ykpersonalize installed, but all the tool ever gave me was this error:
Yubikey core error: no yubikey present
This bug pointed me to the Yubikey NEO manager, which has a PPA! Hooray! Except I couldn't get it to work on trusty, my errors are below. However, I just re-tried in a clean trusty docker container and it seemed to succeed, so I'm not going to file a bug:
ubuntu@ubuntu:~$ sudo apt-get install yubikey-neo-manager
Reading package lists... Done
Building dependency tree      
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
 yubikey-neo-manager : Depends: libu2f-host0 (>= 0.0) but it is not going to be installed
                       Depends: python-pyside.qtwebkit but it is not installable
                       Recommends: pcscd but it is not installable
E: Unable to correct problems, you have held broken packages.
ubuntu@ubuntu:~$ sudo apt-get install python-pyside.qtwebkit
Reading package lists... Done
Building dependency tree      
Reading state information... Done
Package python-pyside.qtwebkit is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
So at this point I gave up on linux and used a Mac, which was waaay easier.

Once I had the keys on the card, to use them on linux I had to do this dance to stop gnome-keyring from ruining everything. On trusty if you use gpg2 you get this error:
$ gpg2 --card-status
gpg: OpenPGP card not available: No SmartCard daemon
but gpg 1.4 works fine. This appears to be caused by differences in how gpg 1 and 2 are packaged, gpg2 needs more packages to work.

Links to other HOWTOs

Here's a big pile of useful links: