Party Gopher!

June 13, 2018 » Geek

The Go slack has a cute little dancing Gopher that appears to have come from Egon Elbre. I love it!

Dancing Gopher

This little dancing Gopher made me think of Party Parrot, so I wanted to parrot-ize him. Normally I might just open up Gimp and start editing, but this is the Go Gopher, we can do better than that!

My plan was to use Go’s image packages to edit each frame and replace the blue with the correct parrot color for that frame by walking over the pixels in each frame.

Once I got into the package docs however, I realized that since gif’s are paletted, I can just tweak the palette on each frame and be done. Much simpler. Let’s get into then, shall we?


First things first, I needed to declare the party parrot frame colors, and the light and dark blue that the dancing gopher uses. I grabbed the blues with Sip and I already had the parrot colors on hand. Sure, I could precompute these and declare, but let’s keep it interesting.

Note that I have a DarkParrotColors slice as well, this is for the corresponding dark blue replacements. I generate these with darken which I’ll show in a moment.

Also notable is the hexToColor which just unpacks an HTML hex RGB representation into a color.Color.

Here is the darken function, pretty simple.

Now I need to pull in the gif and decode it, all very boilerplate.

After that, I iterate over the frames and edit the palettes.

Lastly, more boilerplate to write it out to disk.

Party Gopher

You can grab the code on Github, and thanks again to Egon Elbre for the excellent original gif!

A New GPG Key

May 30, 2018 » Geek

It’s been 12 years since I created my first GPG key and 11 since I’ve created the one I actually use. That is far too long, so I decided to create a new pair and deprecate the old. In 2013 I started this process, but I didn’t follow through and I’ve since lost access to those keys. I know where they are, but the machine died so I need to hook up it’s HDD and pull the keys out.

Regardless, it is time for new ones, and I did some reading to get a real plan for this. I would generate a new, strong key offline, with a subkey for each capability. The subkeys would go onto a smart card, in my case a Yubikey 4. The primary key material would go to offline backup to keep it safe.


Nothing in this post is new or novel, but rather collected from many other posts. I’ve tried to link to any relevant posts below each section, and I encourage you to read these sources. Any mistakes I’ve made I would be glad if you send me an email (GPG encrypted of course ;) to point it out.

Yubikey Configuration

After I ordered my Yubikey, I had to configure it. The Yubikey docs expect a fair amount of knowledge before you start, but the steps are pretty simple when you understand it. Basically, it boils down to:

  1. Change the Admin PIN
  2. Change the PIN
  3. Set a Reset Code
  4. Fill in optional metadata

Plug in your card and proceed as follows:


Generating Keys

Next, I created my keys. Be sure you set up a clean environment for this, ideally a random directory in /tmp, better still on a ramfs of an offline, live CD machine. But that’s a bit drastic for my use case.

You’ll want a good base config file in there too.

With the directory in place, I can create a primary key, option 4. 4096-bits is as strong as GPG allows right now, and I set it not to expire because I will be keeping offline and it should be ok to revoke manually if needed.

Now it’s time to create subkeys. There are four capabilities that a PGP key can have.

C is for Certify

Your primary key will have the capability of Certification. Certify is essentially the ability to sign other keys. A key with Certify can be “parent” to subkeys, create new subkeys, and edit existing ones. You also need this capability to sign another users public key.

S is for Sign

A key with the Sign capability can sign files and messages, allowing others to verify their integrity.

E is for Encrypt

A key with the Encrypt capability is used for encrypting files. Simple.

A is for Authenticate

An Authentication key is generally used for SSH authentication.

Generating the subkeys is a bit tedious, but so it goes.

The authentication key requires E X P E R T M O D E. Git gud.

That’s it! We’re in business.



Before we do anything else, we need to back that thang up.

I’m choosing two methods: backup to a USB key that will live in a fire safe (who has a safety deposit box these days?), and a printed backup in case the USB key fails. Ideally these two articles would not be co-located.

First we export the keys and move them to the USB stick. The export-secret-subkeys output is less important than the export-secret-key output as it doesn’t contain a viable certification key, but would be useful as a “middle tier” of backup that wouldn’t expose your primary key to risk.

Now, we could take these ascii armored keys and just print them, but that’s a lot of bytes to pray for OCR to recognize. Instead, we can use a piece of software called Paperkey which strips out everything but the most secret parts of the key and gives you something much shorter to type in.

Still not fun to type it all in, but it’s better and this is a last ditch sort of thing anyway.


Backups you don’t test aren’t backups, they are hopes and dreams. So let’s try recovering from our paperkey output!


The certificate revoke you, secret key!

While not required, we can generate a revocation certificate while we still have the primary key on this machine.

Throw that onto your backup drive too while you’re at it.



Ok. Everything is generated, we have a good backup, we are ready to transition. To indicate that this key is your new key, you can sign it with your old one, then send it up to the keyservers in the sky (if you’re into that)


To The Smart Card Robin!

I'm Batman

Moving the keys onto a smart card helps protect them. They won’t exist on your filesystem anymore, only on the card. That means they can’t be read out and stolen by a malicious process, but you can still use them by providing your smart card pin and key password.

Keep in mind, this is a one way trip. Make sure your backups are really, truly in place. We want to move our Signing, Encryption and Authentication keys onto the card. The Certification key we will only store offline, as mentioned before.


Hold onto your butts.

This is it. The big moment. Take out that smart card, secure your backups, and let’s delete our primary key material.

Now you can have gpg create key stubs for all the keys on your smart card.

Now when we list keys, we see that our primary key has a # next to it, showing we don’t have access to that secret key. The subkeys have a > next to them showing they are stubs for the keys on the smart card. Success!


That’s it. There is, of course, more to do, like setting up git signing, SSH access, etc. But the new keypair is created, and it’s on the Yubikey, so that’s all for now.

Update: Git Signing

Turns out git signing is a cinch. Just throw a couple items into your git config and it’s automatic and transparent.


Tells git which key to use for signing, unset it just uses the default key.


Makes it sign all commits by default, instead of passing -S to every git commit.


By default, git won’t show you if a commit is GPG signed. You can see it with gpg log --show-signature, or you can set it as default with this config option.

It makes signed commits much chunkier, so be aware of the reduced screen real estate.


This is the only one I am not setting by default. If you have it enabled, all merges that include unsigned commits will be rejected. This really only works if everyone in your organization is signing all their commits.


Update: One-Touch Actions

By default, with the smart card in, GPG will happily sign and decrypt things after you enter your PIN the first time, with no further interaction from you. The Yubikey offers a mode where these actions require a touch on the key to complete, which I like because it makes the action more explicit without requiring me to remove the key between operations.

To enable this, you need a special script, To make it work with my GPG Tools install, I had to hard code the path to gpg-connect-agent (/usr/local/MacGPG2/bin/gpg-connect-agent) and my admin PIN, since pinentry wasn’t working and I didn’t want it in my bash history.

Now, when GPG needs to sign something, my Yubikey flashes at me until I touch it and give my permission. Neat.

Tags: , ,

Chicken Cam: Incubator Edition

March 4, 2018 » Geek, Life

It’s been over a year since we’ve had chickens and we’ve missed them, so this Christmas we got Lizzy and Charlotte an incubator so that we could try hatching some this spring.

When we went to purchase eggs, we found that you could most easily get them 10 at a time from the hatchery we have used in the past, Murray McMurray. Since the incubator we got the girls could only hold seven, we would need something for the other three. Some searching found that you could use a styrofoam cooler and a lamp to create a makeshift incubator, so I planned on that.

Once I had a plan to create an incubator, I knew I would have to overcomplicate things. Four years ago I built a webcam for our chicks so I figured I would do that this time too. Also, just setting a lamp and thermometer in and hoping for the best seemed like a potential waste of good eggs, so I wanted to monitor the temperature and humidity, and regulate them.

My initial design was a Raspberry Pi connected to a cheap DHT11 temperature and humidity sensor, controlling a relay that could turn the light on and off. All of it would be hooked up through a PID controller to keep the temperatures right where we want them. Eventually, I added a thermocouple with a MAX6675 for more accurate temperature readings.

Raspberry Pi, Relay and a mess of wires.

The server side would be designed similarly to the previous chicken cam, except written in Go. The stats would be tracked in InfluxDB and Grafana would be used for viewing them.

After I got all the parts I did a little testing, then soldered things up and tested it to see how it ran.

Initially I wrote everything in Go, but the DHT11 reading was very spotty. Sometimes it would respond once every few seconds, and sometimes it would go a minute or more failing to read. I wired on a second DHT11 and tried reading from both, but I didn’t get that much better performance.

Eventually I tried them from the Adafruit Python library and had much better luck, so I decided to just read those from Python and send them to my main Go application for consumption. I still have trouble with the DHT11’s, but I suspect it’s my fault more than the sensors fault.

My next issue was that it was extremely jittery, the readings would vary by degrees one second to another, so I collected readings in batches of 5 seconds then averaged them. That smoothed it out enough that graphs looked reasonable.

On. Off. On. Off. On. Off.

Temperature was now well regulated, but the air wasn’t humid enough. I switched to a sponge and found I could manage it much easier that way. I briefly tried a 40W bulb thinking I could spend more time with the lamp off, but temperatures still plunged at the same rate when the light was off, so I mostly just created quicker cycles.

After putting the 25W bulb back in, I still wanted a longer, smoother cycle, so I wrapped up a brick (for cleanliness) and stuck that in there. That got me longer cycles with better recovery at the bottom, it didn’t get too cold before the lamp came back on. Some slight improvements to the seal of my lid helped as well. I had trouble with condensation and too much humidity, but some vent holes and better water management took care of that.

Before the brick.

After the brick.

For the server side, I mostly duplicated the code from the previous Chicken cam, but in Go. Then I used the InfluxDB library to get the most recent temperature and humidity readings for display.

At this point, I felt ready for the eggs, which was good because they had arrived! We placed them in the incubator and we’re just waiting now. On day 8 we candled them with a homebuilt lamp i.e. a cardboard box with a hole cut in it.


Things seem to be progressing well so far, so here’s hoping something hatches!


September 14, 2017 » Geek

When Rdio shut down, I tried a few services before landing on Google Play. It’s not perfect, but it’s good enough and it’s better than Spotify. One thing that seemed lacking was a desktop application, but that need was neatly filled by the excellent GPDMP.

One lesser known feature of GPDMP is the JSON API, which manifests as a simple JSON file that the application updates with information about the playback. When Slack announced custom statuses, I though back to the days of instant messaging and the integrations that set your status to the song you were playing.


Implementing the link from GPDMP to Slack was, in all, a fairly simple matter. First, I looked at the JSON file to get a feel for the structure.

Short and sweet! Now to represent that in Go for decoding.

I didn’t need to represent all the elements, but it’s a small structure so I went ahead with it. I didn’t embed Song because I wanted to write an equality test for that struct on it’s own. That will get used later on.

Next, I needed a way to monitor that file for updates, which GPDMP does fairly often. fsnotify was the obvious choice, and an easy drop in.
I added a time based debounce so that we don’t read the file on every update, which would be excessive. This will delay updates by up to whatever debounce is set to, but I’m okay with that trade off.

Inside that debounce (at line 16) we open the file, decode it to a new struct and, if it’s playing, pass it off to a channel.

So, that’s it for getting updates from GPDMP! Less than 100 lines, formatted. Now I needed to watch that update channel and post changes in status to Slack.

I found an excellent Slack API client on a different project, so I grabbed that. I started by building a little struct to hold my client and state.

Then, during client initialization, we get the current custom status for the user and save it. This way, when you pause your music, it will revert to whatever you had set before.

Once it is initialized, we just need to range over our updates channel and post them to Slack when it changes. We set a timeout, because the GPDMP client won’t send updates when the song is paused, or if the app quits updating the file (i.e. you quit GPDMP). By putting the logic for the timeout on this side, we have less to pass over the channel, and we can revert properly if something goes awry in the api reading goroutine.

A little bit of glue in main and it’s ready!

You can browse the source and grab your copy at

MAC Randomizer Alfred Script

December 19, 2016 » Geek

A recent conversation I had dealt with free wifi that limited the amount of time you could use it before it kicked you off. Now, while I support the right of wifi providers to do as they please, it’s an interesting question. AFAIK most tracking of that sort is done based on MAC addresses, which you can easily spoof if you want.

I wrote up a quick Alfred workflow that shells out from Python to do the real work. Note that if your wifi interface isn’t called en0 this won’t work for you.

Workflow Overview

The first script shells out to ifconfig to get the current address. Which gives output like the following. We are interested in that ether f4:5c:89:b3:37:e1 line. The first three octets are of a MAC are the Organizationally Unique Identifier (OUI) and we don’t need to change those, what we have is valid already.

Our script captures the OUI, then generates three more octets for the rest of the address, and prints it out.

Next we need to actually set this new random MAC. This is a privileged operation, so it we passed it directly to ifconfig it would error out. Long story short, if we want a nice authorization dialog we have to pass through applescript, russian nesting doll style.

I also added a way to reset it to the hardware value. The networksetup command handily has that for the taking. We just shell out, capture it and pass it through to ifconfig again.

You can download this workflow, comments and improvements appreciated.