The earliest memory I have of ‘programming’ is in the early/mid 90s when my father brought home a computer from work. We could play games on it … so of course I took the spreadsheet program he used (LOTUS 123, did I date myself with that?) and tried to modify it to print out a helpful message for him. It … halfway worked? At least I could undo it so he could get back to work…

After that, I picked up programming for real in QBASIC (I still have a few of those programs lying around), got my own (junky) Linux desktop from my cousin, tried to learn VBasic (without a Windows machine), and eventually made it to high school… In college, I studied computer science and mathematics, mostly programming in Java/.NET, although with a bit of everything in the mix. A few of my oldest programming posts on this blog are from that time.

After that, on to grad school! Originally, I was going to study computational linguistics, but that fell through. Then programming languages (the school’s specialty). And finally I ended up studying censorship and computer security. That’s about where I am today!

But really, I still have a habit of doing a little bit of everything. Whatever seems interesting at the time!

Extending my EC2 script

Another quick post.

What feels like a lifetime ago, I wrote a post about finding ec2 instances by name. I honestly use that script just about every day, mostly for automatically finding instances to SSH to (a la SSH config tricks). But there are a few other quick things I’ve done with it:

  • ec2-script - Run a script on all instances of a given name
  • ec2-disk - A specialization of ec2-script to check main disk usage
  • terminate - A script that I use with ec2 to terminate instances from the command line
  • ec2-cycle - Slow cycle a given set of ec2 instances by terminating so many per minute

All of which are included in my dotfiles.


Docker Magic - Arbitrary docker runtimes in place

A quick post today.

I find myself working with a surprising number of different languages/environments day to day. In the last week, I’ve worked with PHP, Python, Go, Ruby, and Javascript. And different versions of several of those. While I could install something like virtualenv for Python / rbenv for Ruby / etc, I already have a tool exactly designed for this sort of thing: Docker!


An SPF DNS Server

The Sender Policy Framework is one of those things that’s really powerful and useful to help prevent phishing and email spam, but can be a royal pain to work with. Specifically, SPF is a series of DNS TXT records1 with a specific format that can be looked up by any email service to verify that an email was sent by a server that should be authorized to send email on your behalf. For example

"v=spf1 ip4: ip4: a -all"
  • v=spf1 - tells the client this is an SPF record and should always start the record
  • {key}[:{value}]? - one of many different key/value pairs that can define the record
    • in the case above a ip4 key species an IPv4 address range that can send emails on your behalf (the value can be optional)
    • the a above is another special case where if the sender domain ( would be resolves via a DNS A record to the server that sent the email, it’s allows
  • -all is a fallthrough case meaning ‘fail all that didn’t match a previous case

There are a number of other cases, but we’ll get to the other interesting ones in a bit.


Directly monitoring Sidekiq in Redis

Another thing that came up recently: we have many (many) sidekiq queues. Each has their own admin interface, but sometimes you just want all of the information in one place. Of course, you could bookmark all of the pages. Or make a single page with a lot of frames (remember HTML frames?). Or use their API. But where’s the fun in that? Instead, let’s dig straight into the redis backend and see what we can see!


A Smart MySQL Wrapper

One thing that I often need to do is deal with a large collection of database servers in different clusters and in different environments. On top of that, sometimes, I want a UI, sometime I want a CLI to script. And sometimes I’m on a VPN and sometimes I’m not. All together, it’s a rather complicated number of saved connections and CLI switches and everything else. All together, I want:

  • Specify the cluster, environment, and mode (read/write/adhoc)
  • Specify if I want to run via CLI or via UI
  • Specify an optional user with safely stored and used passwords
  • Automatically connected via SSH tunnel if I’m not on VPN, but not if I am (for CLI or VPN)

Let’s do it!


SSRF Protection in Rails

One of the more subtle bugs that a lot of companies miss is Server Side Request Forgery (SSRF). Like it’s cousin CSRF (cross-site request forgery), SSRF involves carefully crafting a request that runs in a way that the original developers didn’t expect to do things that shouldn’t be done. In the case of CSRF, one site is making a request on behalf of another in a user’s browser (cross-site), but in SSRF, a request is being made by a server on behalf of a client, but you can trick it into making a request that wasn’t intended.

For a perhaps more obvious example, consider a website with a service that will render webpages as preview images–consider sharing links on a social network. A user makes a request such as /render?url= This goes to the server, which will then fetch, render the page to a screenshot, and then return that as a thumbnail.

This seems like rather useful functionality, but what if instead, the user gives the url: /render?url= Normally, would be an internal only domain that cannot be viewed by users, but in this case–the server is within the corporate network. Off the server goes, helpfully taking and returning a screenshot. Another option–if you’re hosted on AWS–is the AWS metadata endpoint: All sorts of interesting private things there. Or even more insidious, /render?url=file:///etc/password. That shouldn’t work in most cases, since most libraries know better than to rener file:// protocol URLs, but… not always!


Observation Server

For a number of years now, I’ve been writing down my ‘observations’. Essentially, it’s a semi-structured set of text files that I keep in Dropbox. One for each day, in a folder by month. I record interesting people I see, things I did worth doing, and things my children did which were adorable.

After a while, I started wanting to look back, so first, I wrote a relatively simple script that would go back through my archives and send me everything I did 1/2/3/4/etc years ago. That worked well enough, but it ended up generating a lot of emails to go through some days. So the second generation is a server that can format those pages and display them as a nice webpage.

The most interesting part perhaps was dealing with the tarballs that I keep the archives in (they’re plain text, so they compress very well). I wanted to keep them compressed, so I had to decompress them in memory on the fly.


LD46: Tetris Life Scoring

And so it ends.


Category Place Score Ratings
Overal 282nd 3.688 26
Fun 408th 3.438 26
Innovation 17th 4.28 27
Theme 290th 3.917 26
Graphics 608th 3.313 26
Audio 436th 3.182 24
Humor 761st 2.205 24
Mood 529th 3.208 26


LD46: Tetris Life v1.0


  • Left and right to move the block and forth
  • Z and X to rotate it (or crash into things)
  • If a block gets stuck, you can hit ENTER to lock it in place
  • ESC to quit the current level


  • To win: Get the plants to the top of the level
  • To lose: Kill off all of the plants #keepitalive

EDIT: I have included a v1.1 update that fixes a few minor bugs. Feel free to play either the official v1.0 build or the slightly updated (~10 minutes) v1.1 build with:

  • Add a ceiling
  • Correctly scale target
  • Scale control speed by difficulty

And there you have it. This page will serve as the main entry for Ludum Dare. If you’d rather download an executable for Windows/OSX/Linux, you can do so on the GitHub release page:

Speaking of which, per the Ludum Dare rules (and because I would have anyways), the full source code:

MIT Licensed. I would appreciate a comment if you do anything cool with it.

Ludum Dare page, if you’d like to see my entry:

Some updates since last time:

  • Music!
  • More elements!
  • Polish!