WireGuard の設定ファイルジェネレーターを作った

# 概要
　[WireGuard](https://www.wireguard.com/ "WireGuard")は処理速度・安全性・柔軟性の観点から見てとても優れたVPNソフトウェアですが、Peer to Peer接続を前提としているため、1対多の環境を作ろうとすると設定ファイルの作成が結構面倒です。そこで、設定ファイルを自動的に生成する[Bashスクリプトを作りました](https://github.com/pitchblende-pub/wges)。1対多はもちろん、1対1で使用する場合でもかなり設定が楽になるのではないかと思います。

#### [wges WireGuard Easy Setup](https://github.com/pitchblende-pub/wges "Wireguard Easy Setup")

特徴は
- 9999個までのクライアントに対応。
- サーバー・クライアントの公開鍵・秘密鍵を自動生成。
- 事前共有鍵も生成するので、量子コンピューター時代になっても安心。
- IPv6にも対応。時刻とmachine-idからIPv6プレフィックスも生成。
- 設定次第でIPv4 over IPv6、IPv6 over IPv4も可能。
- クライアント設定ファイルのQRコードも生成するので、スマホでの設定に便利。（要[qrencode](https://fukuchi.org/works/qrencode/index.html.ja "libqrencode")）
- シェルスクリプトなのでプログラム修正・改変が容易。
- BashとGitHubの勉強になった。(私が)

などです。WireGuardの起動にはwg-quickを利用することを想定しています。


# 使用法
　wges.shを直接編集した上で実行してください。修正箇所は、大抵はスクリプト冒頭↓の部分だけで済むかと思います。
~~~

Peers=10 # 設定するクライアントの数。1〜9999の範囲。
ServerPort=51820 # WireGuardが使用する実ポート
Endpoint=example.ddns.jp:51820 # 外部から見た場合のサーバーアドレスとポート番号
EthernetInterface=eth0 # サーバーから外部にアクセスするための実インターフェイス
DNS='1.1.1.1, 2606:4700:4700::1111' # トンネル開通後に参照するネームサーバー（デフォルトはCloudflare）

# クライアントがどこ向けのアクセスをトンネルに流す（かつ受け入れる）かの設定
# $iはクライアント番号、$IPv6Prefixは生成した48bitプレフィックスに置き換えられる。
# 192.〜の部分は環境に合わせて修正
ClientAllowedIPs='192.168.XX.XX/24' # サーバー側LAN向けアクセスのみをトンネル
#ClientAllowedIPs='192.168.XX.XX/24, 10.0.0.0/16, $IPv6Prefix::/96' # 上に加えて、Wireguardでつながる全コンピューターを対象
#ClientAllowedIPs='0.0.0.0/0, ::/0' # 全アクセスをトンネルさせてサーバー経由にする場合
~~~
詳しくは[README.md](https://github.com/pitchblende-pub/wges/blob/main/README.md)を読んでもらうとして、スクリプトを実行すると各種設定ファイルがwges-outputフォルダ以下に作られます。
## 生成ファイル：サーバー設定ファイル(wg0.conf)
~~~
$ cat wges-output/wg0.conf
[Interface]
Address = 10.0.100.1/16, fd6f:31bf:8c5::a000/96
PostUp   = iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = iMQ/8ESOCfh+bDMiCafxtJ7ohpgSce4rhgGh8WbwoFI=

[Peer] #1
PublicKey = wy7ea5uHiBllNb1Bl3N88/QmYIXzkwEpkPdVyVhTv20=
AllowedIPs = 10.0.0.1/32, fd6f:31bf:8c5::1/128
PresharedKey = MgiCqyz3ViFMTMnnz9bzSFnNfRsXwmw3HWcfEQy8ldQ=

[Peer] #2
PublicKey = WZpeglschDIK8SvbTGXE9wLfA+XeJJyHSlPOKVXLsAA=
AllowedIPs = 10.0.0.2/32, fd6f:31bf:8c5::2/128
PresharedKey = cvzdcCYfVeM+loRDRxKmqiZW+eK1YxYrdEIHBb4lE/E=

[Peer] #3
PublicKey = YR2BnPGpjmfzJfeEwXW2dnyJvoZ8sjACooXhcsGaNmQ=
AllowedIPs = 10.0.0.3/32, fd6f:31bf:8c5::3/128
PresharedKey = RPxK7/PYJFW2jyulTIEjCeL4T8nw6O5QPLJkWR72FQo=
（以下略）
~~~
## 生成ファイル：クライアント設定ファイル(c0001.conf, c0002.conf, ...)
~~~
$ cat wges-output/c0001.conf
[Interface]
PrivateKey = OArUav07hujw4Cqhg/jESlT6YyeSKqLgutk394deQkk=
Address = 10.0.0.1/16, fd6f:31bf:8c5::1/96
DNS = 192.168.1.1

[Peer]
PublicKey = h5O+Gbr4YV5v9XZ8ZVZDhYnq60yclUmpuqo8OCcT8BA=
Endpoint = example.ddns.jp:51820
AllowedIPs = 10.0.0.0/16, fd6f:31bf:8c5::/96, 192.168.1.0/24
PresharedKey = MgiCqyz3ViFMTMnnz9bzSFnNfRsXwmw3HWcfEQy8ldQ=
~~~
## 生成ファイル：クライアント設定ファイルのQRコード画像(qr0001.png, pr0002.png, ...)
![qr0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117634/d570086d-117f-d56c-5af0-9b21436d6b8b.png)

## 生成ファイル：クライアント設定ファイルのQRコードテキスト(qr0001.txt, qqr0002.txt, ...)
~~~
$cat wges-output/qr0001.txt


    █▀▀▀▀▀█ ▀▄█▄▀ ▀▀▀█ ▀▄▀▀█▀  █▄ █▀▀▄▄▄ █  ▀  ▀▄▀ ██▄█ ██ ▀▄ █▀▀▀▀▀█
    █ ███ █ █ ▀▀▀▄▀▄█▀▄▄ ▄▀ █▀█▄  ██▀ ▄▀▄█▄▄▀▀▄ ▄ ▀▀▄█▀▄▀▄█▄▀ █ ███ █
    █ ▀▀▀ █ ▀█▀▄▀█▄ ▀   ▄ ▄▀█▄█ █▀█▀▀▀█ ▄██▄   █▄█ █▄▄██  ▄ ▀ █ ▀▀▀ █
    ▀▀▀▀▀▀▀ ▀▄█▄▀▄▀ ▀▄▀ ▀▄█ ▀▄▀▄█▄█ ▀ █ ▀▄▀▄▀▄▀ █ █▄█ █▄▀▄█ █ ▀▀▀▀▀▀▀
    █▀▀▀▄ ▀ █ ▀▀  ▄██  ▄ ▀████▄  ████▀▀▀ ▀▄▀▀ ▄█    █▀▀█▀▀ ███ ▄▀██▄▀
     █ ▄▄ ▀▄  ▄▄▀ █▄  ▀█▀▀▀▄ ▀ ▀▀█▀▄ ▀▀▀▀█▀▄█ ▄▀▄ ▀ █▄▄▄ ▀▀█▀▀▄█▀▀▀▄▄
    ▀ ▀  ▄▀█▄▀▀  █▀ ▄█▀▄ █ ▀▀▄▄▀▀▄▄ ▄█▄▀█ ▀▄ ▄▄▄  ▀▀▀ ▄▄ ▀▀▀ ▄ █ █ ▀
    ▀▀▀▀▀▀▀  ▄█ █▀█   ▄███    ▄▄ ▀▀▀▀█▀▄   ▀█▀ ▄ █▀▀ ▀ █▀▀ ▀▀▄▄▄█ ▀▀█
     ▄ ██▀▀▄█▀██▄ █▄▀ ▀▀ ▀██▄██ █ ▀▀█▄█▄▄▀▄█ ▀█▀▄▄█▄▀█ ▄ █ █▀▀ █▀▄▄▄▀
    ▀ ▀▄█▄▀█▀▀█▄▀██ ██▄▄  █ █▄▀▀ █ ▀▀   ▀█ ▀▀█  ██▀ ▀ ██ ██▀██ ▄██▄▀
    █ ▄█▀ ▀   ▀▀█▀█ █▀█▄ █ ▀▄ ▀██▀▀  █ █▄█ ▄ ██ ▀▄ █ ▀  ▄█▄▄▀█▀▀ ▀▀ ▀
    █▀▄▀ █▀▀ ▀▄█ ██▄▀▀█  ▄ █▀▀   ▀▀▀█▀██▀▀▀██ ██ ██▀▀█ ▄▀ █▄▀▄ ▄▄█  ▄
    █▄  ▀ ▀█ ▄█ ▀ ██▀▄▀▄▄▀▄   ▄█▀ ▀▄▀▄  ███▄ ▀▄▄█▄▄█ ▄██▀▀█ ▄▄▀  █▀ █
    █▀▀█▀▀▀▄█▄█ ▀█▄▄ ██▄ ██ █ ▄█▀█▄▀ ▄▀▄█▀ ▄ ▄ ▄██▄▄▄▄█▄▄▀ ▀ ▄ █▄█ ▀▀
     ████▀▀  ▀█▀ █ ▀▄▀▀█▀▄███▀▀▀█ ▄▀█▄▀▄  ▀▀ ▀ ███▄ ▄▀ █  █ ▀██ ▀██▄█
     ▄█▀█▀▀▀██▀ ▀██  ██▀▄ ▀██ █ █ █▀▀▀█▀█▀▄▀█▄▀ █▀▄▄▀  ▀▀█▀██▀▀▀█ ▀▄▄
    ▄ ▀▄█ ▀ ██▄▄▄█ ▀ ▀ █▄▀█▄ ▀ ▀▀▀█ ▀ █  ▄▄████▄██ ▄▄ ▀▀█ ▀▄█ ▀ █▄▄█
     █▀▄▀█▀██ ▄█ █▀▄▀█  ▀▄▄▀   ▀▄██▀████▀ ▀ ▄▀   ▀██▀ ▄▄██ ▄█▀▀▀▀  ▀▄
    █▀▄██▀▀▄  ██▀▄▄   ▀▀▄█ ▀▀▀█▄▄▄█ ▄  ▀  ▄▀▄▀▀▄▀▀ █▀▀▄ ▄  ▀███▀█▀██▀
     ██ ▀█▀▄█ ███▀▄█▄█▄▀█▄▀▄▀▀██▀█ ▀▄ ▀██ ▀▀  ████▄ █▀▀▄  █▀█ ▀▀▄ ▀▀█
    ██ █▄ ▀▀▄▄ ▀▄▄  ▀  ██▄ ▄▀█▀█▄▀█▀   ▀▀▄▄ ▄▀██▀▀██ ▄▄██▄▄ ▀▀▀█▀▄▄▄█
     ▄▀ █▄▀▀█▀ ▄█▄▀ ▄█ ▀ ▄  ▀█▄▄ ▄▄█▄█▀▄▄▀  ▄ █▀▀ ▄ ▄▀ ▀▀███▄█ ▄ █▀ ▀
    ██▄ ▀█▀█▀█▄ ▀   █▄▄█▄    ▀▀█▀ ▄█▄█ █▄ ▀▀█ ▀▄ █▄█▄▀ ▀▀▀▄█ ▄█▄▄▀▄▄▀
    ▄▄█▄▀▄▀█▄  █ █▀▄▀▀█ ▄▀▄▀▀▄▀▀▀██▄▄▀ █▀██▀▀▀▄█▀▀ ▀ █▀█▄  ▄██▀█▀▀▀▀▄
    ▀ ▄  ▀▀▄▄▀▄▀▀█▀▄ ▀█▄  ▄ ▀  ▀▄█▀ ▄█▀▄▄▀█▀█▄ ▄▀▄▀▀▄▄████▄ ▄▄ ▀████
     █▄█▀▀▀▀▄▀▄▄▀█  ▀▀▀▀▀█▄  █▄▄▄ █▀▄▀▀▄▄▄ ▄ ▀▀█▀ ▀▄█    ▀▄▀█▀▀▀██ █▀
    ▄▀█▀ ▀▀██ █ ▄███  ▀█▀▀█▀▄███ ▀▀ ▀▀█▄█  ▀▄█  ▀██▀▄ ▀█▀▄ █ ▄  ▀▄ ██
    ▄ ▀█ ▀▀▀▀▄▄▄ █▄▀▄ ▀▀▄▄▀▀█▄▄▀██ ▄▀ ▀  █▄▄▀▄  ▀▀██▄  ███  ▄█▄█ ▀ ▄
     ▀▀ ▀ ▀ █ ▄▀▀ ▄█▀▀   ▄█▄█ ▄  ▄█▀▀▀██▄▀ █▄ ▀ ██▀██  ▀▀▀ ██▀▀▀█▄██▀
    █▀▀▀▀▀█  █▄ ▀ █ ▄ █▄▀▀ █ ▀ ▄▄▄█ ▀ █▄███▀ ▄▄▀█▀ ▀ ▄█ ▀█▄ █ ▀ █▄  ▄
    █ ███ █ ▄ ▀ █▄█  ▀▀▀▄█▀▄ █▄ ██▀█▀▀▀▀▀▀██▄▀▀▀▄  ▀██▄  ▄▀▀▀▀▀▀██ ▀
    █ ▀▀▀ █ █▄▄▄█▄ █▀▀▄  ██▀█▀█▄ ▀▄▄▄█▄▄█  ██ ▄█▀██▀▀ ▄██▀▄▀▄▄██▄██▄▀
    ▀▀▀▀▀▀▀ ▀▀▀   ▀▀▀    ▀   ▀▀  ▀ ▀▀▀  ▀▀ ▀ ▀▀ ▀ ▀▀ ▀    ▀ ▀▀    ▀▀
~~~
端末によっては、QRコードテキストの表示は上手く行かないかもしれません。qrencodeコマンドのオプションを調整してみてください。

# お願い
こう改良してほしい、バグがある、ここはこう書くんだよ！等がありましたら連絡願います。[Twitter](https://twitter.com/p_gotcha)、[Qiita](https://qiita.com/p_gotcha)、[GithubのIssues](https://github.com/pitchblende-pub/wges/issues)等にお寄せください。