Stop asking your students to write command line UIs

How often have you used a UI like this?

| 1. List files            |
| 2. Show the current time |
| 3. Show Top              |
| 4. Quit                  |

Enter your selection: 

Even if you are a banker, travel agent or a medical doctor I would argue never. These groups are unfortunate enough to still have to use arcane command line interfaces to do unspeakably complex things like recording last week’s hours or reserve a ticket to your home town. But none of these systems are razor thin wrappers for simple shell tools – they are that way because they are really hard to replace. And more importantly, no employer is ever going to ask anyone to make a menu based command line UI for their shell script. It just doesn’t happen anymore. It is not a valuable skill. ASCII art is recreation, not work. So the time spent fiddling with echo and read is wasted, and could be put to better use.

There are many generally applicable skills you can teach shell newbies:

  • The Unix philosophy: writing programs that do one thing, that work with other programs, and that handle text streams. An hour of cobbling together a pipeline of grep, cut and a light sprinkling of sed can save days or weeks of data processing which might take a week to write in Python or six months in a spreadsheet.
  • On the flip side, they should know the limitations of the shell. Why while read is several orders of magnitude slower than other language equivalents. Why writing secure shell scripts is basically impossible. Or why big shell scripts are a maintenance nightmare compared to other languages.
  • Which tools are available to do what. There are so many useful tools you could probably spend a week full time just touching briefly on each of them. Check out for example BusyBox for a set of generally available tools.
  • Where to look for answers and how to ask good questions.

Firefox add-on to highlight insecure links

Insecure Links Highlighter does what it says on the tin. On a web page like

it adds a bright red border around any insecure links, turning it into

It supports HTTP, FTP and (by default) links with event handlers which may or may not be doing bad things. Useful for security and privacy-oriented users and web devs alike.

How to recover password after shortening

Writing secure software is hard. At the same time, some things are so fundamental that failing to implement them is just inexcusable. One of these is that you must not limit the password length. (At least below some crazy limit like a thousand characters. Long before that your password is no longer the weakest link in even the most secure systems in the world.) Enter my new router, ironically named the Orcon Genius. It’s a bog standard consumer router, and like most routers it came with an insecure admin password. I promptly replaced it with a long, generated password, but afterwards I could no longer log in. I suspected a shoddy implementation, so I cobbled together a script to try logging in using every substring of the password. After about half a second it spat out the correct password, verifying that this router only saves the first 15 characters of the password. The script is very simple:

 password='your_secure_password' # the line starts with a space
for start in $(seq 0 $password_length)
    for length in $(seq 1 $(($password_length - start)))
        if curl --basic --fail --silent --user "admin:${substring}" > /dev/null
            echo "$substring"
            break 2

The space before the variable assignment is to avoid storing the password in the shell history. Your shell may not support this feature, in which case you need to figure out how to securely erase the password from your history. Consider yourself warned.

I’ve reported this issue to Orcon. Hopefully they will fix the firmware.

How broken is Samsung UK support?

This is how broken:

  • There are two “types” of requests, both of which link to the same page. This wastes customers’ time.
  • Can’t find my hardware by browsing or searching for the model. I tried three different ones – the long name from the order, the short name from the shop, and the name that shows up in the “about” screen on the device itself.
  • After continuing with the wrong model, I had to fill in my contact details even though I had already registered them.
  • When I tried to submit the form I got a “Tried to send data without session.” error. Resubmitting didn’t work.
  • Intermission: at this point I tried to use the built-in support request functionality on the device itself. After filling in the forms using arrow keys (and reminiscing about the NES days), I was simply told that all available support slots were taken. At this point I could no longer progress in the form. Fuck.
  • Re-opening the form in another tab did work. The experience so far did not exactly inspire confidence, but I still hope someone will reply.

The HTTPS-only experience

EFF recently announced that We’re Halfway to Encrypting the Entire Web.” As a celebration of this achievement I’ve started an experiment: as of yesterday, no unencrypted HTTP traffic reaches this machine*.


Even though securing your web site is easier than ever it will take some time before everybody encrypts. But there are a bunch of sites which support both secure and insecure HTTP transfer, and there are a few tricks to tilt the scales and make the current experience better:

  • The HTTPS Everywhere browser extension ensures that you use HTTPS whenever possible on thousands of sites.
  • Editing the URL to add “https://” at the start works for some sites. If you get the dreaded certificate error page make sure to report them, and only add an exception if … well, that subject is too big to get into here. Just don’t.

Many sites have excellent HTTPS support, and have enabled HTTP Strict Transport Security (HSTS). In short, if your browser knows that the domain supports HTTPS (by visiting it or the browser being installed with it) you can simply type the domain name in the URL field and the browser will default to fetching the secure version of the site. On the other end of the spectrum I can still visit sites which have no HTTPS support at all if I really need to by using Tor, which provides privacy but not integrity or authenticity.

pacman stopped working after setting this up. It turns out the package database is fetched using unencrypted HTTP by default, but it was easy to generate a new list of only HTTPS mirrors.

Some sites have a strange HTTPS setup. The BBC only support HTTPS for the front page, which is just weird. Why go to all that trouble for 1% of the gain? Other sites require authentication to access using HTTPS, possibly not realising that setting up HTTPS for everyone would be easier.

My home router runs DD-WRT, and the web interface for it is only accessible by HTTP by default. This is easy to configure though.

OCSP uses HTTP (at least in Firefox), since the returned file signature has to be checked separately anyway. So if I go to about:config, change security.OCSP.require to true, and visit a site I haven’t seen for a while, I get an error message like this:

An error occurred during a connection to The OCSP server experienced an internal error. Error code: SEC_ERROR_OCSP_SERVER_ERROR

The solution is to either allow OCSP queries specifically or to allow HTTP to specific hosts. Let’s see what can be done…

The Steam client uses insecure HTTP for both game updates and the store pages. There doesn’t seem to be any way to force it to use HTTPS, so I have submitted suggestion to Valve using the official channel.

These have been the only major hassles so far. The only other sites I really can’t get to work over HTTPS are various hold-outs like Wikia and BBC.


The change was a simple addition to my Puppet manifest:

firewall { '100 drop insecure outgoing HTTP traffic':
  chain  => 'OUTPUT',
  dport  => 80,
  proto  => tcp,
  action => reject,

The resulting rule:

$ sudo iptables --list-rules OUTPUT | grep ^-A
-A OUTPUT -p tcp -m multiport --dports 80 -m comment --comment "100 drop insecure outgoing HTTP traffic" -j REJECT --reject-with icmp-port-unreachable

* Technical readers will of course notice that the configuration simply blocks port 80, while HTTP can of course be served on any port. The configuration wasn’t meant as a safeguard against absolutely every way unencrypted HTTP content could be fetched, but rather focused on the >99.9% of the web which serves unencrypted content (if any) on port 80. I would be interested in any easy solutions for blocking unencrypted HTTP across the board.

When MFA is not enough

I hope you’ll excuse the format of this post. Coffee does strange things to my brain.

In the beginning, there was the username. And it was deemed good enough, because everybody on the machine was a trusted colleague. Then came machines shared by strangers, and with them the password. And it was deemed good enough, because the resources to crack it were beyond most. Then came the Internet, and the world flourished and grew. But the world contains more villains than the password, in its myriad implementations, could withstand. And thus came multi-factor authentication. And it was deemed good enough, because only someone in possession of the authenticated device could gain access.

But they were all deceived, because the service providers foretold that their users would lose their authenticated device, and lock themselves out of their accounts, and would blame them rather than their own misfortune. And so it was that, fearing their users’ wroth, the service providers gave their support personnel unfettered access to override MFA at the behest of a phone call.

Some service providers were wiser, and gave out backup codes after authenticating, thus allowing users to regain access by themselves, and promised not to give access to anybody with a honeyed voice, and reminded their users ever and anon that they should be mindful of their backup codes, and even gave them the option to be told when their account was logged into. And their users were at peace, trusting that their service providers knew what the fuck they were doing, that their files were safe, and being forever loyal to them.

Full disk encryption with Arch Linux footnotes

Pavel Kogan has an excellent guide to install Arch Linux with full disk encryption. I’ve taken the liberty of copying the instructions, adding a couple tweaks:

  1. Boot the Arch Linux installation medium.
  2. Run these commands (You may want to use different sizes for swap and root volumes):
    parted -s /dev/sda mklabel msdos
    parted -s /dev/sda mkpart primary 2048s 100%
    parted -s /dev/sda set 1 boot on
    cryptsetup luksFormat /dev/sda1
    cryptsetup luksOpen /dev/sda1 lvm
    pvcreate /dev/mapper/lvm
    vgcreate vg /dev/mapper/lvm
    lvcreate -L 4G vg -n swap
    lvcreate -L 15G vg -n root
    lvcreate -l +100%FREE vg -n home
    mkswap -L swap /dev/mapper/vg-swap
    mkfs.ext4 /dev/mapper/vg-root
    mkfs.ext4 /dev/mapper/vg-home
    mount /dev/mapper/vg-root /mnt
    mkdir /mnt/home
    mount /dev/mapper/vg-home /mnt/home
  3. Go through the software installation steps of the installation guide, skipping the Initramfs and Boot loader steps.
  4. Install GRUB: pacman --sync --noconfirm grub
  5. In /etc/mkinitcpio.conf:
    • Change the line starting with FILES= to FILES="/crypto_keyfile.bin"
    • On the line starting with HOOKS= add lvm2 encrypt just before filesystems.
  6. Find the UUID of /dev/sda1 by running basename "$(find -L /dev/disk/by-uuid -samefile /dev/sda1)"
  7. In /etc/default/grub:
    • Change the line starting with GRUB_CMDLINE_LINUX= to GRUB_CMDLINE_LINUX="cryptdevice=UUID=[UUID]:lvm", replacing [UUID] with your own.
    • Add a line with GRUB_ENABLE_CRYPTODISK=y
  8. Run these commands:
    dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin
    cryptsetup luksAddKey /dev/sda1 /crypto_keyfile.bin
    chmod 000 /crypto_keyfile.bin
    chmod -R 700 /boot
    mkinitcpio -p linux
    grub-mkconfig -o /boot/grub/grub.cfg
    grub-install --target=i386-pc /dev/sda
  9. If necessary, set up your BIOS to allow booting in CSM mode.

It also required me to enter the password using a QWERTY keymap. The instructions to add an alternative keymap to GRUB are rather involved, but I’ll try to write them up if I go through with it.