Use Google Authenticator / OATH for two-factor SSH access with SSH-Keys

I wanted to use two factor auth combined with ssh keys to restrict access to some of the production machines at work, however this wasn’t entirely straight forward as google authenticator pam module would be entirely bypassed with ssh-keys, and only supports one key per account, (so shared accounts like root would be a problem)

I’ve discovered a lovely little simple tool that lets you work around it ssh-opt

+ You can use a different OATH token for each ssh key!
+ You can choose to not require tokens for some keys, eg. for automated systems
+ You can use it along with google authenticator pam for single password + single token access
+ You can install it on machines you don’t have root access to

– It doesn’t support scratch emergency codes or replay protection [yet, it wouldnt be that hard to add]
– It leaks your token key to other users via ps [easily fixable]
– It breaks scp! not sure why yet, it just hangs for me.

Its dead simple to use too, just prefix the key in .ssh/authorized_keys:

command="/usr/bin/ssh-otp OATHTOKEN" ssh-dss AAAAB3...

No Comments

Fix Linux Flash Player “Error #2046” on iceweasel / debian

This error had plagued me for some time, but the chrome plugin worked… so I didnt mind until I updated to a full 64bit OS, and the chrome plugin does not exist for 64bit

Turns out that the plugin was trying to read the firefox preferences but fails on two accounts, it apparently doesnt handle spaces or relative paths..

Change ~/.mozilla/firefox/profiles.ini something like this:






and then

ln -s ~/.firefox/default/187x6ax2.slt ~/.mozilla/firefox/

1 Comment

How to add an additional Google Authenticator Device

You will need a rooted device to do this!

I’ve obtained more than one android device, and I was looking at installing the google authenticator app on it as well, however, google wanted me to delete my existing key and create a new one if I was going to configure other devices. This means disabling 2 factor authentication, and I’m not sure if that would mean recreating all of my application specific passwords…but I didnt fancy that..

$ adb shell
# sqlite3 /data/data/
sqlite> select * from accounts;
sqlite> .quit

Now open google authenticator on your new device and choose manually add account, put in your email and key as read above. bish bash bosh, done. Validate this is working by running authenticator on both devices, they should have the same id.

If you dont have a rooted device, you will probably just need to disable and re-setup two-factor authentication to discover your new key.

As a side note, I enjoyed discovering the existence of the following packages:
– for adding google two factor auth to your webserver, not sure that this supports scratch codes.
– for adding google two factor auth to your linux machine/services, available on debian as libpam-google-authenticator. It has terminal based ascii-art QR-codes, cool! You can probably just update your ~/.google_authenticator with your key you extracted and also manually enter your scratch codes into this file.


Stenaline Public Wifi Very Insecure – SSL MITM Attacks

Update: Stenaline have responded and disabled email inspection

Fabulous, they have disabled the configuration that was causing me the most problems, within 24hrs of my original post. Congratulations stena line and I look forward to my return journey!

As a direct action on your mail we immediately notified our service provider regarding this issue and the problem is now located and solved.

IMAP protocol inspection is now disabled. The previous setting was an unintentional mistake by our service provider. .

Original Post:

Stena Line provide free wifi, which is awesome, however, their egregious content filtering system massively compromises the passengers online safety far more than normal public wifi hotspots.

They claim on their captive portal login screen on their on-ship wifi:


Privacy protection
All open wireless networks are by nature insecure. Please, take the necessary precautions to protect your privacy and data communications.

What kind of security, does the network provide?
The network security level is basically the same as you find on public hotspots.

However, this is clearly not the case, because they go out of their way to invalidate “the necessary precautions” that I normally take which is checking my email over SSL protected connections..

It appears stenaline think that its OK for them to snoop on my SSL secured private and work emails some fortinet/fortigate snooping appliance they seem to have. This appliance proxies SSL connections and re-signs the certificates with its own keys, effectively performing an SSL MITM (Man In The Middle) Attack. SSL is designed to prevent this sort of thing, which is why your browser throws up an error message when somethings gone wrong. All in all, this however means nobody can tell if its them “protecting” me or if it is infact a rogue hacker running a fake access point, a so called “Evil Twin” network, collecting peoples google, and corporate credentials, or snooping on my emails.. Thanks very much guys.

Update: It appears that It’s not limited to email or non-https web ports, lots of websites that have https connections blow up too, even common ones like google plus which loads content from (a google owned site). They appear to whitelist certain popular websites to allow https directly, but this is unmanageable and unmaintainable, and wholly ridiculous. I cant safely sign into my work SSL VPN with this either.

Heres an example where they have stripped the regular CA and added the Self-Signed Fortinet CA Certificate for

$ openssl s_client -connect
depth=1 C = US, ST = California, L = Sunnyvale, O = Fortinet, OU = Certificate Authority, CN = FortiGate CA, emailAddress =
verify error:num=19:self signed certificate in certificate chain
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/
i:/C=US/ST=California/L=Sunnyvale/O=Fortinet/OU=Certificate Authority/CN=FortiGate CA/
1 s:/C=US/ST=California/L=Sunnyvale/O=Fortinet/OU=Certificate Authority/CN=FortiGate CA/
i:/C=US/ST=California/L=Sunnyvale/O=Fortinet/OU=Certificate Authority/CN=FortiGate CA/
Server certificate
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/
issuer=/C=US/ST=California/L=Sunnyvale/O=Fortinet/OU=Certificate Authority/CN=FortiGate CA/

it should look like

$ openssl s_client -connect -showcerts
depth=1 C = US, O = Google Inc, CN = Google Internet Authority
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/
   i:/C=US/O=Google Inc/CN=Google Internet Authority
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
Server certificate
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/
issuer=/C=US/O=Google Inc/CN=Google Internet Authority

All in all, the standard advice of when using a public wifi connection, use a VPN still stands…

As most regular folk dont have a VPN (and even SSL VPNs are compromised here), the best you can hope for is that the sites you use will use SSL, and that you dont just willy-nilly click “OK” on Browser SSL Warning Pages, sadly, this standard web-safety advice means you just cant browse the web safely on stena line ferries.

Google take a very dim view on this sort of thing: Google security blog: Attempted man in the middle attacks

Another interesting thing is that this may also be illegal in the UK within the terms of the computer misuse act or telecommunication acts, as they are attempting to decrypt an encrypted communication, though I’m not a lawyer. If anyone can shed any light on this I’d like to know.

I’ve emailed stena a link to this post to see if they respond, and hopefully set a timeframe for removing this egregious device/configuration from their network.

No Comments

Automating Debian preseed installs with raid and LVM

There are few problems I needed to address with debian preseeding to install onto multiple different machines

  • Testing my preseed in virtualbox lead to it pulling in half of X as it detected I needed virtualbox client extensions, when i wanted a clean small base install.
  • Support installing onto all machines including to boot from USB hdd and slow raid controllers that take a few seconds to initialise
  • For some reason the debian preseed file for requires you to specify /dev/sda or /dev/hda and does not allow you to specify in the devfs independent formats /dev/discs/disc0/disc
  • I wanted to always set up software raid mirror, even if there was just one hard disk (so later a second hdd could be added to mirror quickly)
  • They should be able to install with any debian installer, but the system should default to using network install for updates afterwards

Full sample config and example usage

Sample Config:

Boot Debian Squeeze Install CD/DVD/Netinst/etc

Choose Advanced, Automated Install

Answer keyboard / network setup prompts

Realise that after typing the next line in your VM or Computer will be fully erased without warning:

Preseed Location:

The full location is of that above, but d-i/squeeze/preseed.cfg path is added automatically by the installer if none is specified.

Make a cup of strong tea.

login as root/changemenow


#For some reason lvremove hangs when I invoked it from the preseed script, so tidy up now.
lvremove /dev/vg0/dummy

Relevant Config Snippets

Stop debian preseed from installing virtualbox stuff

# Disable Debian installer from installing hardware specific packages
# Warning: This could break preseeding to some hardware I dont know or care about.
d-i preseed/early_command string rm /usr/lib/pre-pkgsel.d/20install-hwpackages

Use network install for updates, but cd/dvd for install

d-i preseed/early_command string anna-install net-retriever;
### Mirror settings
# If you select ftp, the mirror/country string does not need to be set.
#d-i mirror/protocol string ftp
d-i mirror/country string manual
d-i mirror/http/hostname string
d-i mirror/http/hostname seen true
d-i mirror/http/directory string /debian
d-i mirror/http/directory seen true
d-i mirror/http/proxy string

# Suite to install.
d-i mirror/suite string squeeze
# Suite to use for loading installer components (optional).
d-i mirror/udeb/suite string squeeze

# disable the cdrom path from the apt soruces.list automatically
d-i preseed/late_command in-target sed -i 's/^deb cdrom/# DISABLED deb/' /etc/apt/sources.list

Work around USB boot drives and slow controllers

# Work around for slow raid controllers on some machines
# and usb bootable hdds
d-i debian-installer/add-kernel-opts string rootdelay=7

Automatic Debian raid and LVM Setup

### Partitioning
# has moved to:

# Next you need to specify the physical partitions that will be used.
# The numbers aren't pretty as I experimented till
# I got something approaching what i wanted
# This example creates:
# /dev/md0 - 100 to 256Mb - /boot
# /dev/md1 - 900 to 4000Mb(ignored rest of disk used) - LVM vg0
# /dev/vg0/root - 700 to 5000Mb - / ext4
# /dev/vg0/swap_1 - 300% of RAM size - swap
# /dev/vg0/home - 64 to 4096Mb - /home ext4
# /dev/vg0/var+log - 64 to 4096Mb - /var/log ext4
# /dev/vg0/dummy - rest of space - to be deleted and others resized.

d-i partman-auto/expert_recipe string \
multiraid :: \
100 512 256 raid \
$lvmignore{ } \
$primary{ } \
method{ raid } \
. \
900 5000 4000 raid \
$lvmignore{ } \
method{ raid } \
. \
700 5000 5000 ext4 \
$defaultignore{ } \
$lvmok{ } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
mountpoint{ / } \
. \
64 512 300% linux-swap \
$defaultignore{ } \
$lvmok{ } \
method{ swap } \
format{ } \
. \
64 1024 4096 ext4 \
$defaultignore{ } \
$lvmok{ } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
mountpoint{ /home } \
. \
64 1024 4096 ext4 \
$defaultignore{ } \
$lvmok{ } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
mountpoint{ /var/log } \
. \
64 2048 1000000000 ext3 \
$defaultignore{ } \
$lvmok{ } \
lv_name{ dummy } \
use_filesystem{ } \
filesystem{ ext3 } \
method{ keep } \
d-i partman-auto/method string regular

# If one of the disks that are going to be automatically partitioned
# contains an old LVM configuration, the user will normally receive a
# warning. This can be preseeded away...
d-i partman-lvm/device_remove_lvm boolean true
# The same applies to pre-existing software RAID array:
d-i partman-md/device_remove_md boolean true
# And the same goes for the confirmation to write the lvm partitions.
d-i partman-lvm/confirm boolean true

#Name default volume group vg0
d-i partman-auto-lvm/new_vg_name string vg0

# You can choose one of the three predefined partitioning recipes:
# - atomic: all files in one partition
# - home: separate /home partition
# - multi: separate /home, /usr, /var, and /tmp partitions
d-i partman-auto/choose_recipe select expert_recipe

# This command is run immediately before the partitioner starts. It may be
# useful to apply dynamic partitioner preseeding that depends on the state
# of the disks (which may not be visible when preseed/early_command runs).
d-i partman/early_command string \
DISKA=$(list-devices disk|head -n1);\
DISKB=$(list-devices disk|head -n2|tail -1);\
if [ "${DISKA#/dev/cciss}" != "$DISKA" ]; then DISKAP="p"; fi;\
if [ "${DISKB#/dev/cciss}" != "$DISKB" ]; then DISKBP="p"; fi;\
if [ "$DISKA" = "$DISKB" ]; then\
debconf-set partman-auto/disk "$DISKA";\
debconf-set partman-auto-raid/recipe "1 2 0 ext3 /boot ${DISKA}${DISKAP}1 . 1 2 0 lvm - ${DISKA}${DISKAP}5 .";\
debconf-set grub-installer/bootdev "$DISKA";\
debconf-set partman-auto/disk "$DISKA $DISKB";\
debconf-set partman-auto-raid/recipe "1 2 0 ext3 /boot ${DISKA}${DISKAP}1#${DISKB}${DISKBP}1 . 1 2 0 lvm - ${DISKA}${DISKAP}5#${DISKB}${DISKBP}5 .";\
debconf-set grub-installer/bootdev "$DISKA $DISKB";\

# lvremove hangs.. weird
#d-i preseed/late_command string in-target lvremove -f /dev/vg0/dummy

## Partitioning using RAID
# The method should be set to "raid".
d-i partman-auto/method string raid
# This makes partman automatically repartition without confirmation.
d-i partman-md/confirm boolean true
d-i partman-md/confirm_nooverwrite boolean true
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman-basicfilesystems/no_mount_point yes

## Controlling how partitions are mounted
# The default is to mount by UUID, but you can also choose "traditional" to
# use traditional device names, or "label" to try filesystem labels before
# falling back to UUIDs.
d-i partman/mount_style select label



Creating a debian native package from scratch with git-buildpackage

A missing snippet from the manual of was how to create a debian native package from scratch, I did something like this:

mkdir newdeb
cd newdeb
git init
git commit --allow-blank -m "Empty upstream, native Debian package"
# or with newer git (thanks marco)
git commit --allow-empty -m "Empty upstream, native Debian package"
git branch upstream
dh_make -p newdeb_1.0 -n -e -s
git add debian
git commit -m "Initial blank Debian package template"

1 Comment


RE: Anysharp emails.

You’ve sent me emails promoting the LIMITED AVAILABILITY SPECIAL OFFER anysharp on:

12th Aug 2010
21st Aug 2010
12th Oct 2010
16th Nov 2010
4th Jan 2011
25th Jan 2011
29th Jan 2011

And its always, and currently still is, cheaper direct from the manufacturers site than from you.

Please find a better offer.

Also the submit comment on your site was broken, “error ‘8004020e’ /Scripts/email/sendMail.asp, line 119” so i posted this on my blog 🙂

No Comments

How to reduce the threshold for “Low on Space” Android Warnings

Low on Space – Phone storage space is getting low.

Its a cursed message on my Android HTC Hero, but there is 16MB free on /data partition! I want my email to sync a bit more and I want to receive text messages and I dont want to delete any apps.

You need to have rooted your android device and have the android sdk installed and debugging enabled on your phone. I might package this recipe up into an apk for easy installation.

The default limit is 10% of free space, i’ve reduced mine to 5%, I don’t know if there are any terrible side effects. As you’ve already rooted your phone you’ve already probably voided your warranty 🙂

To reduce from 10% to 5% warning from your “adb shell”:

sqlite3 /data/data/
insert into secure (name, value) VALUES('sys_storage_threshold_percentage','5');
insert into gservices (name, value) VALUES('sys_storage_threshold_percentage','5');

Then reboot your phone.

Some firmwares seem to look for the setting in gservices but the latest android source looks like it looks for it in the secure settings, so i’ve included both for good measure.


How to get rid of GPG NO_PUBKEY errors when doing apt-get update

When doing apt-get update you might see a lot of errors like

W: GPG error: lenny Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY DA4420ED288995C8
W: GPG error: Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 85753AA5EEFEFDE9
W: GPG error: karmic Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 28577FE31F882273
W: GPG error: lenny Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 54422A4B98AB5139

For the best part you should install the apropriate keyrings

apt-cache search keyring$

should list most of them, sometimes they dont exist for some third party repositories, so try this one liner, split for (a little) clarity

for KEY in `apt-get update 2>&1 |grep NO_PUBKEY|awk  '{print $NF}'`; do
 gpg --keyserver --recv $KEY; gpg --export --armor $KEY|apt-key add -;

Caveat, this is insecure, but more secure than disabling validation. Please be aware for full security you should validate the key signatures you are importing via private quantumly secured links to the originator obtained at your own cost, etc etc.


1 Comment

How to generate an svn-authors-for-git file automatically

If you are using git-svn to interoperate or migrate to git from an svn repository it is a bit irritating having your long git svn fetch repeatedly interrupted by unknown users in your svn repo.

This bash script one liner will get you started with a template file with every user in it already, just tweak their names if you wish.

svn log svn://svnserver -q|grep -v -- ---|cut -d\| -f 2|sort|tr -d ' '|uniq|
   xargs -i echo '{} = {} <{}>' > /pathto/svn-authors-for-git

git config --global --replace-all svn.authorsfile /pathto/svn-authors-for-git

1 Comment