Apple siliconなMacでWireGuard構築してみた

# はじめに
M1のMac miniを買ったのに合わせてWireguardでVPNを構築してみました。

#### 環境
* ホスト
M1 Mac Mini
* クライアント
Mac book Air
になります

## 目次
<!-- タイトルとアンカー名を編集 -->
1. [Mac Miniの基本設定](#Chapter1)
1. [ルータの設定](#Chapter2)
1. [Wireguardの設定](#Chapter3)
1. [各クライアントの設定](#Chapter4)
1. [自動起動設定](#Chapter5)
1. [終わり](#Chapter6)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
## Mac Miniの基本設定
Mac miniのIPアドレスがDHCP取得になっている場合、固定IPを設定して下さい。
やり方については以下のappleのサポートページを参考にして下さい。

https://support.apple.com/ja-jp/guide/mac-help/mchlp2718/mac

今回は192.168.3.22/25と設定しています。

![スクリーンショット 2024-05-17 0.00.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1084345/e9361189-0e3b-4861-3fdc-69c120e551e8.png)

つづいて、設定から省エネルギー設定に移動し以下の通りに設定して下さい。

![スクリーンショット 2024-05-17 0.01.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1084345/7ede209a-e771-8654-0013-3ca61e3cdab0.png)

またスリープしないように

```zsh
sudo pmset -a disablesleep 1
```

とターミナルから実行して下さい。

続いてファイアウォールが有効になっている場合、ネットワーク設定から無効に変更して下さい。

![スクリーンショット 2024-05-17 0.07.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1084345/a7dac7d9-f20e-ee57-a3ed-f58bc3176797.png)

<a id="#Chapter2"></a>
## ルータの設定
Wireguardは標準で51820ポートを使用するためルータでポートを塞いでいる場合解放して下さい。
また、ポートフォワーディングを設定し51820ポートが今回の場合だと192.168.3.22へ向かうようにして下さい。

詳しい手順は各ルータの設定方法を調べて下さい。

<a id="#Chapter3"></a>
## Wireguardの設定
LAN内の他の端末にルーティングできるようにするためにpfctlコマンドを使ってファイアウォールの設定を変更します。
普通に実行するとMacのアップデートなどがあると設定がリセットされるため、スクリプトを作成しWireguard実行時に自動で設定されるようにします。

以下の内容を/usr/local/etc/wireguard/postup.shとして作成して下さい。
ネットワークデバイスen0が使用されていることを想定しているため他のネットワークデバイスを使用している場合は書き換えて下さい。

```zsh
#!/bin/sh

/usr/sbin/sysctl -w net.inet.ip.forwarding=1
/usr/sbin/sysctl -w net.inet6.ip6.forwarding=1

mkdir -p /usr/local/var/run/wireguard
chmod 700 /usr/local/var/run/wireguard

echo 'nat on en0 from 10.0.10.1/24 to any -> (en0)' | \
        pfctl -a com.apple/wireguard_ipv4 -Ef - 2>&1 | \
        grep 'Token' | \
        sed 's%Token : \(.*\)%\1%' > /usr/local/var/run/wireguard/pf_wireguard_ipv4_token.txt
IPV4_TOKEN=`sudo cat /usr/local/var/run/wireguard/pf_wireguard_ipv4_token.txt`
echo "Added PF IPv4 NAT traffic routing rule with token: ${IPV4_TOKEN}"

```

Wireguard終了時用のスクリプトを以下の内容で/usr/local/etc/wireguard/postdown.shに作成して下さい。

```zsh
#!/bin/sh

# 1) Reverting our previously set IP forwarding overrides
/usr/sbin/sysctl -w net.inet.ip.forwarding=0
/usr/sbin/sysctl -w net.inet6.ip6.forwarding=0

# 2) Remove the IPv4 filter rule by reference. Adding and
#    removing rules by references like this will automatically
#    disable the packet filter firewall if there are no other
#    references left, but will leave it up if there are.
ANCHOR="com.apple/wireguard_ipv4"
pfctl -a ${ANCHOR} -F all || exit 1
echo "Removed IPv4 rule with anchor: ${ANCHOR}"
IPV4_TOKEN=`sudo cat /usr/local/var/run/wireguard/pf_wireguard_ipv4_token.txt`
pfctl -X ${IPV4_TOKEN} || exit 1
echo "Removed reference for token: ${IPV4_TOKEN}"
rm -rf /usr/local/var/run/wireguard/pf_wireguard_ipv4_token.txt
echo "Deleted IPv4 token file"
```
両方のスクリプトに実行権限を与えます。

```zsh
chmod u+x /usr/local/etc/wireguard/*.sh
```

Homebrewを使用してWireguard-toolsをインストールして下さい。

```zsh
brew install wireguard-tools
```

次のコマンドでWireguardが使用するプライベートキーとパブリックキーのペアを生成してください。
接続するデバイスの数(サーバ含む)だけキーが必要になるので注意してください。
また同じディレクトリでコマンドを実行すると上書きされる可能性があるためディレクトリは分けて下さい。

```zsh
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
```

Wireguardサーバー設定ファイルを/usr/local/etc/wireguard/coordinates.confとして以下の内容で作成して下さい。

```zsh
[Interface]
Address = 10.0.10.1/24
PrivateKey = VPNサーバ用PrivateKey
ListenPort = 51820
DNS = 1.1.1.1, 1.0.0.1
PostUp = /usr/local/etc/wireguard/postup.sh
PostDown = /usr/local/etc/wireguard/postdown.sh

[Peer]
PublicKey = クライアント用のPublicKey
AllowedIPs = 10.0.10.2/32
```
最後に

```zsh
wg-quick up /usr/local/etc/wireguard/coordinates.conf
```

コマンドを実行してwireguardを起動して下さい。

<a id="#Chapter4"></a>
## 各クライアントの設定

https://www.wireguard.com/install/

から各クライアント用のソフトをダウンロードして以下のテンプレートを元に設定して下さい。

```zsh
[Interface]
PrivateKey = クライアント用PrivateKey
DNS = 1.1.1.1, 1.0.0.1

[Peer]
PublicKey = VPNサーバー用のPublicKey
Endpoint = XXX.XXX.XXX.XXX:51820
AllowedIPs = 10.0.10.1/24,192.168.3.1/25
PersistentKeepalive = 25
```

Endpointの設定ですがmac miniが接続しているグローバルIPを設定して下さい。
以下のサイト等で確認できます。

https://www.cman.jp/network/support/go_access.cgi

また、グローバルIPはルータが再起動する際に変更されるためDDNS等のサービスを使用するのもいいかもしれません。

AllowedIPsの設定ではVPNを経由するIPを設定します。
上の設定の場合ですと、10.0.10.1/24と192.168.3.1/25がVPNを経由することになります。
全ての通信をVPN経由させるには0.0.0.0/0に変更して下さい。

<a id="#Chapter5"></a>
## 自動起動設定
上記までの設定が終わっていればVPNがつながるはずですが、Mac Miniを再起動した場合に自動でWireguardが起動しません。
そのため自動で起動するように設定を変更します。

以下の内容で/Library/LaunchDaemons/com.wireguard.server.plistを作成して下さい。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//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/coordinates.conf</string>
        </array>
        <key>KeepAlive</key>
        <true/>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/usr/local/var/log/wireguard.err</string>
        <key>EnvironmentVariables</key>
        <dict>
            <key>PATH</key>
            <string>/usr/local/sbin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
        </dict>
    </dict>
</plist>
```

つぎにユーザとグループを変更します。

```zsh
sudo chown root:wheel 
/Library/LaunchDaemons/com.wireguard.server.plist
```

最後にlaunchctlに登録します。

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

<a id="#Chapter6"></a>
## 終わり
以上で全部の設定が完了です。
自分もWireguardに詳しくないので設定が間違っていたりするかもしれないです。
その際は指摘して下さい🙇