Making WireGuard from Homebrew Work on an M1 Mac
Published on 22 Jun 2021 · Filed in Tutorial · 641 words (estimated 4 minutes to read)After writing the post on using WireGuard on macOS (using the official WireGuard GUI app from the Mac App Store), I found the GUI app’s behavior to be less than ideal. For example, tunnels marked as on-demand would later show up as no longer configured as an on-demand tunnel. When I decided to set up WireGuard on my M1-based MacBook Pro (see my review of the M1 MacBook Pro), I didn’t want to use the GUI app. Fortunately, Homebrew has formulas for WireGuard. Unfortunately, the WireGuard tools as installed by Homebrew on an M1-based Mac won’t work. Here’s how to fix that.
The key issues with WireGuard as installed by Homebrew on an M1-based Mac are:
- On an M1-based Mac, Homebrew installs (by default) to the
/opt/homebrewprefix. By comparison, Homebrew uses/usr/localon Intel-based Macs. Some of the WireGuard-related scripts are hard-coded to use/usr/localas the Homebrew prefix. Because the prefix has changed, though, these scripts now don’t work on an M1-based Mac. - WireGuard has a dependency on Bash. Unfortunately, the version of Bash supplied by macOS isn’t supported by WireGuard (it’s too old). Without a very specific PATH configuration, even installing the Homebrew version of Bash—which is supported by WireGuard—won’t help. (You’ll have to install it anyway; Homebrew requires it to satisfy a dependency.)
Fortunately, there is a way to work around these issues. The following steps should enable you to use Homebrew’s WireGuard on your M1-based Mac:
- Go ahead and use
brew installto install the “wireguard-go”, “wireguard-tools”, and “bash” packages. - Edit your shell startup file(s) to modify your PATH variable in such a way so that a personal directory—like
$HOME/binor similar—is listed first, followed by the/opt/homebrew/bindirectory. (I think the order of the/opt/homebrew/bindirectory in the PATH may not matter, but I need to do more testing before I’ll know for certain.) - Copy the
wg-quickscript installed by Homebrew into the personal directory specified in the previous step. This is necessary because the script is read-only in the location where Homebrew installs it. - Edit the shebang line of the
wg-quickscript to say#!/usr/bin/env -P/opt/homebrew/bin bash. Basically, you’re adding-P/opt/homebrew/binto the shebang line, right beforebash. (You can checkman envto understand what the-Pparameter does, but the “TL;DR” is that you’re limiting whereenvwill search to find abashbinary.) - On or about line 44, the script defines a variable named
CONFIG_SEARCH_PATHS. Edit this line to add/opt/homebrew/etc/wireguardto the existing list of directories that the script will search for the WireGuard configuration files.
Once you’ve done these steps, you can proceed with configuring WireGuard as outlined in a variety of articles and posts (such as this one I wrote on configuring WireGuard on macOS via the CLI). Replace any references to /usr/local/etc/wireguard in these posts with /opt/homebrew/etc/wireguard.
When you run sudo wg-quick up wg0 to activate the VPN, your shell will find your modified version of this script first (because of step 2 above). This means your changes to the script will be in effect. Your modified version of this script will find the Homebrew-installed version of Bash (because of the change made in step 4, limiting where env will look to find the bash binary), which is compatible with WireGuard and will allow the script to complete properly. Finally, because you added the /opt/homebrew/etc/wireguard directory to the list of paths that wg-quick will search for WireGuard configuration files, it will find your configuration files and appropriately configure the interface(s).
The steps described above should get you a working WireGuard installation on an M1-based Mac. Hopefully, I can contribute these changes (or improved versions of these changes) back to the Homebrew project. If you have questions, or if I have made a mistake in my recommendations, please contact me on Twitter. I hope you find this useful!