Global Entry, or: How I Opened My Front Door with an SMS
Fresh from the closing, I paced around my newly purchased, completely bare condo. It was literally a blank canvas. “This space is mine,” I thought to myself, “I can customize it as I wish.”
But what to do? The first gears started spinning when I saw I could buzz people in to the building. I knew I would want to control this capability by more than having to physically press the button. (FYI, this kind of door system is called an “electric strike”)
The absolute first step before I could do anything else at all would be to tap into the ‘door’ circuit. I needed to get useful leads out that could be wired into some alternate system (TBD) that would trigger the buzzing-in.
Taking off the panel in the apartment didn’t reveal much except for satisfying some curiosity. But yes, shorting the two ends of the ‘door’ button did indeed unlock the front door.
But how would I get my leads? Hooking in here at this point would be tricky; it was just panel and wall. It would be difficult to hide any wires cleanly, let alone any other equipment I would need; a messy setup would not fly, especially as the first thing you see when entering the apartment. But more important than aesthetics is safety. Whatever controlled the door would have to be powered, and putting that kind of wiring inside a wall – particularly a DC transformer and associated waste heat – was not something I was comfortable with.
But then I realized: those wires go somewhere. They all snake through the basement to terminate at a central console. Access down there would be much easier.
For a while I debated how exactly to tap in to the wires down here, and even how to determine which wire was mine, lest I screw up somebody elses buzzer!
But then came my second realization: all these wires go to the same place. The central console would provide the most straightforward access.
The entire network of buzzers in the building reduces down to these two adjacent terminals. Just like upstairs, shorting across them unlocks the front door.
So I would wire in a parallel set of leads for my own use.
This was perhaps the most nerve-wracking portion of the project. For the few moments this step took, buzzer access was out of service for the entire building.
Phase I: Remote Control
I had the necessary electrical access. I now needed something to take advantage of it.
Trying to replicate the keyless entry fobs like you’d have for your car seemed like a good proof-of-concept project.
This led to investigating radio-activated relays (similar to a garage door opener) and tiny keychain remote controls. Funnily enough, your choice of relay ends up more than anything else being determined by your preference for the form factor of the remote that comes with it.
Phase II: Internet Control
I was already immensely pleased with the radio control, but it was mostly a novelty. Although it did save me from fishing out a key to get into the building, I still needed one to get into my apartment (no DIY Lockitron just yet). I could do more interesting things when I didn’t have to be within 50′.
More interesting things:
- I’ve locked myself out (if I don’t have my keys, I definitely don’t have the remote either).
- Melissa and I need to let someone in to check on something while we’re away. Or, we have guests staying and wanted to avoid complicated keys hand-off.
- We’re throwing a party and I don’t want to man the door buzzer for three hours.
The control device presented the same issue as before: it needed access to the physical circuit. Install a Raspberry Pi in tandem with the RF relay? I was not thrilled with the prospect of sysadmining a glorified switch-flipper in the basement on the fringe of my wifi range.
…or, wire up something that would trigger one of the wireless remotes, that in turn triggers the relay you’ve already wired up in the basement (credit Melissa for this brilliant idea).
To trigger the remote, I needed another relay, ideally controlled by USB. Apparently such a product literally does not exist in the United States. So instead I used an Arduino to control the relay while taking commands over USB, which feels utterly ridiculous.
There was one nice side-effect, though. My one main fear was that somehow the system would glitch and keep buzzing the door open perpetually. The buzzer does not actually work like an on/off light switch. Rather, you need a momentary press: on, then off, to send a signal to the control console. If the ‘on’ signal were sent but the ‘off’ never was, there would be a big problem.
By having all the relay logic on the Arduino, I could be nearly certain that an ‘on’ would always be followed by an ‘off’, excepting loss of power, which would de-activate the relay anyway.
With the hardware taken care of, I had to figure out how to grant and manage access. There are really two kinds of access: resident and guest.
Resident access is persistent. Guest access is short-lived. Guests are granted ‘leases’ for a particular entry purpose (visit, party, cat-sitting, etc.) and period of validity with a defined start and end time. Each lease has a unique URL and numeric SMS code that when visited or messaged, opens the door.
I did not want to have to deal with whitelisting email addresses or phone numbers for guest access. It would be too cumbersome and adversely affect the usability of my desired use cases. For example, an out-of-town guest’s phone might be dead. Or the party invitation gets passed around to some last-minute invitees not originally on the list. It is nice if people can still gain access from other than their usual device.
This means the lease URL and SMS code are bearer tokens. Anyone in possession of them can gain access. The short lifespan of each individual lease mitigates such a risk.
Residential access is handled differently. The security risks are greater and usability is less of a concern. The only residential use case is locking yourself out; day-to-day access would be via remote instead. Therefore, residential access requires positive authentication every time. In practice, this is outsourced to Google’s sign-in API. Residents authenticate with their Google account, and if it corresponds to a registered resident, access is granted.
The main app lives in the cloud (hosted on this very server). It receives access requests directly via URL, or from Twilio upon the receipt of an incoming SMS. The app validates the request, and if valid, the command is sent to open the door.
The cloud server cannot command the Arduino directly, as they must be connected by USB. So instead, the command is sent through our apartment media server, which is physically connected to the Arduino.
I actually would have preferred that the entire system be hosted on that one server, but there was a complication. In order for the communications from Twilio to have maximum security, Twilio must verify the SSL certificate of my web app before speaking to it. My home server does not have an SSL certificate, and you can’t verify a self-signed cert. Rather than acquire one solely for my home server to host this one thing (which might require, like, paying actual money), I’d rather just use my public server, which already has one.
Thus, the divison of responsibilites: my public server receives and validates the requests, and my home server executes them.
The bridge the gap, the public server executes a command remotely on the physical server via ssh tunnel. In order to shave off precious seconds and make the system as responsive as possible, an ssh session is actually kept open between the two computers at all times. The ephemeral session to execute the command uses the “connection sharing” feature of ssh, which allows it piggyback over the already-open session, and avoid all handshaking/authentication overhead.
But then it turns out the Arduino has a two-second delay before it will accept serial commands. Balls.
The Big Picture
When you put it all together, it all starts to look like a bit of rube-goldbergian ridiculousness. But actually the very clear separation of parts contributes to the overall reliability of the system.
Nevertheless, it’s crazy to think of the many thousands of miles travelled and numerous systems passed through when I tap a screen while standing right in front of the door.
As this thing grants physical access to your premises, security considerations are paramount.
Garage door remotes have gone through several evolutions in technology. The first generation were “fixed code” remotes – an 8–12-bit code that you set manually. This yielded ~250–4,000 possible codes; it was easy to try them all. These were not very secure.
The next generation, which this system uses, is called “learning code”, with randomly generated codes around 20 bits long (one million combinations). Remotes can ‘learn’ the code from the base station, thus making the longer codes feasible. Learning code remotes are less vulnerable to brute-forcing (guessing all combinations), but are still vulnerable to snooping, since the code never changes.
Beyond learning code is “rolling code”, in which the transmitted code changes every time. While more secure than learning code, they are also more complex to manage since the remote and base station can get out of sync regarding what code they’re expecting next. This problem becomes exacerbated in deployments with large numbers of remotes and/or remotes that are used with greatly differing frequency. (One problem is that these considerations, while surmountable, are usually just not well documented.)
The risk of snooping the learning code remotes is the one part of this system that relies on security by obscurity. People simply aren’t expecting garage door openers to open things that aren’t garage doors. I also live in a neighborhood with few garages, and the few that exist are detached and small; they are not entry points to houses nor likely to store valuables, assuming they even have openers. The odds of roving bands of RF-scanning malcontents are very small.
All communications are encrypted and authenticated.
All access to the website is forced to use HTTPS. This protects the sensitive bearer tokens from snooping.
Furthermore, incoming SMSes are authenticated to make sure they actually come from Twilio. Otherwise an attacker could pretend to be Twilio and guess all possible SMS codes (only 5–6 digits) easily.
In the event that a bearer token is compromised, they are typically short-lived, and must have an expiration date.
Residential and admin access (to create new guest leases) requires positive authentication, and relies on Google security infrastructure to do so. Once logged in, the session token is stored in a signed and secure cookie, invulnerable to sniffing and spoofing.
The remote command between the cloud and physical server is secured via ssh; it cannot be run unauthorized.
I haven’t made the code public, though I suppose I should put my money where my mouth is…
comments powered by Disqus