Hardening distraction blockers like freedom.to on macOS against sophisticated deactivation strategies
A short guide for blocking content blockers like Freedom.to for Engineers.
Quite some time ago I was able to get a great lifetime deal, maybe even the best lifetime deal I ever got, on freedom.to.
Freedom is a strong content blocker that allows you to set all kinds of restrictions for accessing websites and applications like X, YouTube, Netflix, and LinkedIn.
I've had my fair share of troubles over the years to stay away from the constant dopamine hits of these platforms, which cost me a theoretical fortune in productivity and life quality.
Distraction blockers like Freedom are exactly what I needed to stay away from these distractions and addicting platforms.
The only problem was that applications like Freedom aren't built for engineers. As a software engineer, it was only a matter of time until I found ways to hack around the limitations that Freedom brings.
Theoretically, the locked mode shouldn't allow you to stop sessions and restrictions, but I found over 10 ways to go around them. And over time, the previously hard way to unblock got easier and easier, as I got more used to hacking around the limitations.
—
I think I now have found a way to at least stop me from the end boss sudo pkill Freedom
on macOS, which was unfortunately the single point of failure that I've used for a long time now.
So here is a guide on how to harden your Freedom process.
Last tested on macOS 14 (Sonoma) · Freedom v2.13
Why not just remove root privileges or block terminals?
As software engineers we need access the terminal and also sudo.
sudo pkill Freedom
immediately kills it, as well as killall Freedom etc.
The goal of this guide is to raise that bar to “Recovery-mode”-level while keeping full admin rights and development workflow intact.
1 Root daemons (proxy + helper)
These root daemons restart the background processes for Freedom constantly so that you can't stop them.
# FreedomProxy – auto-respawn
sudo tee /Library/LaunchDaemons/com.selflock.freedom-proxy.plist <<'PL'
<?xml version="1.0"?>
<plist><dict>
<key>Label</key><string>com.selflock.freedom-proxy</string>
<key>ProgramArguments</key><array>
<string>/Applications/Freedom.app/Contents/MacOS/FreedomProxy</string>
<string>-port</string><string>7769</string>
<string>-rpcport</string><string>7770</string>
</array>
<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
</dict></plist>
PL
# FreedomHelper – flips macOS proxy flags
sudo tee /Library/LaunchDaemons/com.selflock.freedom-helper.plist <<'PL'
<?xml version="1.0"?>
<plist><dict>
<key>Label</key><string>com.selflock.freedom-helper</string>
<key>ProgramArguments</key><array>
<string>/Library/PrivilegedHelperTools/com.80pct.FreedomHelper</string>
</array>
<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
</dict></plist>
PL
sudo chown root:wheel /Library/LaunchDaemons/com.selflock.freedom-*.plist
sudo chmod 644 /Library/LaunchDaemons/com.selflock.freedom-*.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/com.selflock.freedom-proxy.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/com.selflock.freedom-helper.plist
I suggest freezing the files (which you can only undo from the macOS recovery mode and is exactly the headache needed to stop killing the process):
sudo chflags schg /Library/LaunchDaemons/com.selflock.freedom-*.plist
Now, we also want to make sure that the Freedom GUI application is restarted in case it gets shut down, as the GUI App is responsible for the initial sync with the Freedom server. That's why we check for freedom every 30 seconds.
Before I implemented it like this, I did the mistake of just starting the app every 30s without a check if it runs. That was a mistake as the script basically de-focused my active windows every 30 seconds.
mkdir -p ~/bin ~/Library/LaunchAgents
# start GUI only if missing (not defocusing active windows)
cat > ~/bin/freedom-keeper.sh <<'SH'
#!/bin/zsh
pgrep -qx Freedom || /usr/bin/open -g -a Freedom
SH
chmod 755 ~/bin/freedom-keeper.sh
cat > ~/Library/LaunchAgents/com.selflock.freedom-keeper.plist <<'PL'
<?xml version="1.0"?>
<plist><dict>
<key>Label</key><string>com.selflock.freedom-keeper</string>
<key>ProgramArguments</key><array>
<string>/bin/zsh</string><string>-c</string>
<string>$HOME/bin/freedom-keeper.sh</string>
</array>
<key>StartInterval</key><integer>30</integer>
<key>RunAtLoad</key><true/>
</dict></plist>
PL
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.selflock.freedom-keeper.plist
Try stopping it now via sudo pkill Freedom
it will spawn again shortly after.
Have fun being productive.