Summary: I use a Raspberry Pi and a cheap door sensor to restrict my internet access when I take an old landline phone off the hook. See below for a demo:
I struggle with what I think is a common issue. If you asked me how I wanted to spend my free time, I'd tell you I want to do things like read books, exercise, play chess, and work on personal projects. But when I look back on what I actually do with my free time, I spend a huge amount of it scrolling through mindless content on sites like Reddit, Instagram, and Hacker News, instead of doing something more 'productive'.
So, over the years, I’ve tried several approaches to keep myself from spending too much time on these distracting websites: installing browser extensions, editing my hosts file, using Apple's content restrictions settings on iOS, and more. However, I've struggled to find a method that works well for me.
Any method of blocking distracting content must sit somewhere on the spectrum of restrictive to flexible. It's a tradeoff: my ideal blocking system would be restrictive enough to keep me from wasting time, but flexible enough to let me access any content when I need to. After all, even the most productive version of myself would sometimes want to catch up on my friends' Instagram posts, or search Reddit for product reviews, or just relax for a little while.
As a result of this tradeoff, most of the approaches I've found to blocking specific websites fall into one of two categories:
/etc/hosts
)For a long time, my favorite approach was a Mac app called SelfControl. It works by editing your hosts file to block access to a list of domains—but only for a specified amount of time, up to a maximum of 24 hours. So if I want to spend a little time focusing on a project, I can block certain sites for an hour or two, or until tomorrow morning—but otherwise they are unrestricted.
Unfortunately, SelfControl only works on macOS, so it's pretty easy to pick up my phone or tablet and continue distracting myself there. What I really want is a solution that works seamlessly across all my devices—something that keeps me from getting distracted, not just my laptop.
I was watching an old movie the other day. The main character checked into a hotel and, not wanting to be bothered, took the phone in their room off the hook. The simplicity of this gesture stood out to me: a small, tactile action which could cut you off from the rest of the world. Today, you might have to turn off several devices to achieve the same kind of isolation, and you don’t get the same physical feedback as you do when you see the phone off the hook.
What if my internet connection had a “phone” and a “hook”? I could take it off when I didn’t want to be disturbed or distracted, just like in the old days.
As a simple approximation, I could unplug my router when I wanted to focus, and then plug it back in when I wanted to go on the internet. But that has some obvious drawbacks: what if I need the internet for my work laptop, or for a productive reason like a side project? Or what about all my spouse’s devices? Unplugging the router would be overkill.
I already use a PiHole to block certain domains. Maybe I could set something up to add and remove domains from the blocklist, depending on whether a phone is on or off the hook?
This sounded charming and interesting enough for me to make it real.
First, I’d need to find an old landline phone. This was the hardest part of the whole project. I looked at several thrift and vintage stores, but none had any old phones, except for one Polycom I found at a Goodwill (which didn't quite seem like the right aesthetic). Eventually I ordered a cheap one off Ebay. It turned out the phone I got was actually brand new, still in a box. (I added the INTERNET
label myself.)
Next, I needed some way for my Raspberry Pi to detect the phone’s state—is it on or off the hook?
It turns out door sensors are perfect for this. They’re designed to tell whether a door is open or closed, but they work just as well to sense any kind of proximity. (Thanks to Simon Prickett for writing up his use of the sensor, which inspired me to use one.) By attaching the wired half of the sensor to the base of the phone and the other half to the handset, we can easily detect whether the phone is on or off the hook.
Now, we need to tell the Pi what to do when the phone goes off the hook. At first, I struggled to make this work through PiHole, but then I found a great writeup from Brandon Rozek which gave me the solution. PiHole runs on top of dnsmasq
, a DNS service meant for small networks. Instead of bothering with PiHole to implement the blocking, we can just add a custom dnsmasq
config file to route all traffic to 0.0.0.0, with specific exceptions for the domains we want to allow.
The ultimate solution is a python script which reads the state of the phone every second. When it changes from being on the hook to off the hook, a shell script runs to load a custom config file to /etc/dnsmasq.d/
, which blocks all traffic except for a small allowed list of domains. When the phone goes back on the hook, this custom file is removed, and regular internet access is restored.
The last step was to turn the script into a service that runs constantly in the background—very easily accomplished.
This was a really fun project. It’s sort of magical to take the phone off the hook, try to load a website, and get a “no internet connection” message.
As mentioned above, it's nice to exclude certain sites from the blocking. For example, lichess always loads, even when the phone is off the hook:
I haven’t used it as much as I'd hoped—my usage so far has been mostly on weekends, for a couple of hours at a time. The truth is that an automatic schedule that toggled these DNS settings on and off at set times every day would give me more downtime overall (and would have been easier to set up). But it wouldn't have the same amount of flexibility and whimsy! Plus, having a landline phone with an INTERNET
label is a great conversation-starter.
More broadly, I've been thinking that my general approach here might be wrong, and that I should reframe the challenge. Maybe I’ll experiment with a version that only blocks a few time-waster sites, like Reddit and Hacker News, when the phone is off the hook. Then, having the phone off the hook could be the default state, and access to those distracting sites would be easily achieved by putting the phone back on the hook. This could be a more effective way to require a physical action whenever I want to browse what would otherwise be mindless content—a bit like the method Randall Munroe describes on the xkcd blag. ⧈