RPi Garage-door Controller

I had always wanted to design some method for wireless garage-door control that didn’t involve an ad hoc “clicker” device like most systems use. Those devices are vulnerable to theft, duplication, replay attacks, etc. My particular garage-door opener is over twenty years old, and uses the least secure means of radio control – a static code set with a few DIP switches. Attacks against this system are well-documented and trivial. Samy Kamkar used a kids’ texting toy to brute force this type of opener quickly and easily. To disable this side-channel attack, I was able to remove the radio module of my garage-door opener so it has no way of receiving radio input by itself.

Radio module assembled to opener main board
Radio module assembled to opener main board
Garage-door opener radio module
Garage-door opener radio module

Most newer garage-door openers use more secure point-to-point radio communication or use Wi-Fi to allow control through an app. I don’t trust proprietary systems that use an app though. Most of those apps are written just fast enough to get it working with little thought put into security. They typically involve routing your phone and the door controller’s signal exchanges through the manufacturer’s server, which is unnecessary, gives an opportunity for unwanted data collection, and opens up an attack vector. So-called IoT appliances and their associated services have notoriously terrible security and privacy and should be kept off the internet as much as possible.

I wanted to make my own remote-control system that allowed the door to be opened using a smartphone, but that didn’t require routing through the internet – just the local network. Thus, authentication is taken care of when the phone connects to the Wi-Fi network, which is a well-studied and hardened attack surface. To accomplish this, I built a web server on a Raspberry Pi 3B, which is essentially a small Linux computer with built-in Wi-Fi.

Raspberry Pi 3B single-board computer
Raspberry Pi 3B

The server consists of a simple Python backend and an HTML/CSS frontend that provides a button for opening or closing the garage door. When the webpage button is pressed on the client (my phone), it communicates over the local network to the RPi server, and the Raspberry Pi energizes one of its GPIO pins that connects to an external relay board (the ModMyPi PiOT Relay board).

PiOT Relay Board
PiOT Relay Board

The relay closes for a fraction of a second, closing the same DC circuit that the garage wall button closes (the two are wired in parallel). Once I learned about Siri Shortcuts, I realized the client didn’t need to use a web page anymore. I made an iPhone Shortcut that just sends the proper request to the server, so the browser doesn’t need to be opened and closed anymore. Then I set it up so the garage door Siri shortcut runs just by passing my phone over an NFC tag in my car.

Garage door iOS shortcut

A few other recent additions to the project:

  • cron job automatically restarts RPi and Python web server to keep things running correctly.
  • Pi-Hole DNS sinkhole running alongside the Python web server.
  • Control over the light using a second relay on the PiOT board (note separate “LIGHT”) terminal on back of opener below. My program turns the light on for 30 minutes, creating and terminating a child process so the program returns to the ready state as the timer runs down.

Click here to view my server’s source code on GitHub.

Raspberry Pi and relay board installed
Raspberry Pi control server in place

Before tackling this project, I read the (lengthy) book Exploring Raspberry Pi by Derek Malloy. I found it very informative about the Raspberry Pi, Linux in general, Git, embedded electronics, sensors, etc. It was my first introduction to both Linux and Git, both of which I use extensively now.

Exploring Raspberry Pi book cover
Exploring Raspberry Pi