Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A suggestion about “Wireguard Server on macOS” #1

Open
lifepillar opened this issue Mar 7, 2020 · 4 comments
Open

A suggestion about “Wireguard Server on macOS” #1

lifepillar opened this issue Mar 7, 2020 · 4 comments
Labels

Comments

@lifepillar
Copy link

@lifepillar lifepillar commented Mar 7, 2020

Hi, I'm among the dozen people who run a Wireguard server on macOS. I have a couple of remarks about setting up the firewall rules.

  1. I think that the two NAT rules you suggest are conflicting with each other. I was noticing dropped pings (first ping ok, then the rest times out)—usually a symptom of different devices using the same IP—which I resolved by removing the utun NAT rule. The following rule is enough to let me access my LAN through Wireguard:
nat on en0 from 10.0.10.0/24 to any -> (en0)

(where en0 is the active interface on my computer, of course, and 10.0.10.0/24 is Wireguard's subnet).

  1. Modifying /etc/pf.conf (or any other system's file in macOS) is never a good idea. It will be most likely overwritten on updates. I use Wireguard's PostUp and PostDown to dynamically add/remove the above firewall rule. Specifically:
  • create /usr/local/etc/wireguard/postup.sh with the following content:
#!/bin/sh
mkdir -p /usr/local/var/run/wireguard
chmod 700 /usr/local/var/run/wireguard
echo 'nat on en0 from 10.0.10.0/24 to any -> (en0)' | \
  pfctl -a com.apple/wireguard -Ef - 2>&1 | \
  grep 'Token' | \
  sed 's%Token : \(.*\)%\1%' >/usr/local/var/run/wireguard/pf_wireguard_token.txt

This will create a directory to store the token generated by pfctl; set its permissions so that it will be accessible only by root; dynamically add the NAT rule to the com.apple/wireguard anchor; enable the firewall and increase its reference count (-E); filter pfctl output to extract the reference token and store it into pf_wireguard_token.txt.

  • Create /usr/local/etc/wireguard/postdown.sh with the following content:
#!/bin/sh
TOKEN=`cat /usr/local/var/run/wireguard/pf_wireguard_token.txt`
pfctl -X ${TOKEN} || exit 1
rm -f /usr/local/var/run/wireguard/pf_wireguard_token.txt

This will get the reference from the file created before and it will release it (-X), disabling the firewall if there are no other references (otherwise the firewall will remain enabled).

  • Make the two scripts executable!

  • Add PostUp and PostDown directives to the server's configuration, e.g.:

[Interface]
Address = 10.0.10.0/24
PrivateKey = XXX
ListenPort = 51820
DNS = 1.1.1.1, 1.0.0.1, 2606:4700:4700::1111
PostUp = /usr/sbin/sysctl -w net.inet.ip.forwarding=1
PostUp = /usr/sbin/sysctl -w net.inet6.ip6.forwarding=1
PostUp = /usr/local/etc/wireguard/postup.sh
PostDown = /usr/local/etc/wireguard/postdown.sh

You don't need a launchd plist to start the firewall any longer. Rather, you should define a launchd plist to bring up Wireguard at boot time:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd";>
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.wireguard.server</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/bin/wg-quick</string>
      <string>up</string>
      <string>/usr/local/etc/wireguard/server.conf</string>
    </array>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
    <key>LaunchOnlyOnce</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/usr/local/var/log/wireguard.err</string>
    <key>EnvironmentVariables</key>
    <dict>
      <key>PATH</key>
      <string>/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
    </dict>
  </dict>
</plist>

(The above assumes that Wireguard configuration is saved at /usr/local/etc/wireguard/server.conf; also, make sure that /usr/local/var/log/ exists). Enable with:

sudo launchctl enable system/com.wireguard.server
sudo launchctl bootstrap system /Library/LaunchDaemons/com.wireguard.server.plist

You may want to test this and update your nice blog post accordingly ;-)

@barrowclift

This comment has been minimized.

Copy link
Owner

@barrowclift barrowclift commented Mar 10, 2020

@lifepillar, thank you so much for taking the time to write in such fantastic and comprehensive feedback, I really appreciate it! Learned a lot of new things from this.

I'm working through integrating your improvements to my own setup now and hope to get an update to the post out within the week. I promise to include proper credit and a link to your site in the update.

Thanks again! 😁🙏

@lifepillar

This comment has been minimized.

Copy link
Author

@lifepillar lifepillar commented Mar 12, 2020

Thank you. One caveat is that I am using an old iMac with High Sierra. Tightened security and fresh bugs in more recent macOS releases might break something. Catalina, in particular, is not known for being a… cough cough… an especially good release: “no route to host” errors have been reported; also, there seems to be a bug related to interfaces visibility when wifi is off.

@barrowclift

This comment has been minimized.

Copy link
Owner

@barrowclift barrowclift commented Mar 15, 2020

Noted; I'm running Catalina over here, so I'll keep an eye out for packet losses and other strange behavior going forward. However, things seem to be thankfully working fine so far on my end with the suggested changes, so it's possible I either haven't noticed or there's unknown, additional criteria required to expose those bugs.

Also, I'm happy to report the new and improved guide is now live at the original address. Thanks so much again for your feedback!

@lifepillar

This comment has been minimized.

Copy link
Author

@lifepillar lifepillar commented Mar 15, 2020

Great, thanks!

The only issue I have had with this setup is with my laptop (on Catalina) in my working environment, where both wireless and wired connections are available. Using wi-fi everything works perfectly (as a Wireguard client), but the wired connection doesn't work most of the times, and I haven't been able to debug it yet. I don't think it's an OS problem with utun interfaces, though, because I also use OpenVPN in the same environment without any issue. I doubt it's firewall problem, for the same reason (and also because I have tried Wireguard with different ports, including OpenVPN's).

What I find puzzling is that the handshake appears to succeed when I am on Ethernet, but I cannot establish any connection through Wireguard. I have to take a closer look at the routing tables…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.