WireGuardはシンプルなVPNソフトウェア。解説が簡潔すぎてよく分からないところなどがあったので、設定方法をメモしておく。
0.インストール
WireGuardは様々なOS上で使用できるが、ここではLinuxを前提とする。wireguard-toolsをインストールする。
Debian系なら
sudo apt install wireguard-tools
1.Peer to Peer構成での設定
ここでは、接続する端末がすべて同一のプライベートネットワーク内にいることを想定する。つまり、NATなどを使わなくてもお互いにIPアドレスでアクセスできる環境を考える。- 端末A
もとのアドレス…192.168.10.1/24
WireGuard上で使用するアドレス…10.0.10.1/24
- 端末B
もとのアドレス…192.168.10.2/24
WireGuard上で使用するアドレス…10.0.10.2/24
1.1コマンドでの設定
(端末A側)umask077 wg genkey > privatekey cat privatekey | wg pubkey > publickey sudo ip link add dev wg0 type wireguard sudo ip address add 10.0.10.1/24 dev wg0 sudo wg set wg0 listen-port 58372 private-key ./privatekey
(端末B側)
umask077 wg genkey > privatekey cat privatekey | wg pubkey > publickey sudo ip link add dev wg0 type wireguard sudo ip address add 10.0.10.2/24 dev wg0 sudo wg set wg0 listen-port 49582 private-key ./privatekey
上のコマンドでここまでを行った。リッスンポートは未使用ポートなら何でもいい。
次にpeerを設定して、デバイスを有効にする。
(端末A側)
sudo wg set wg0 peer [端末Bの公開鍵] allowed-ips 10.0.10.2/32 endpoint 192.168.10.2:49582 sudo ip link set wg0 up
(端末B側)
sudo wg set wg0 peer [端末Aの公開鍵] allowed-ips 10.0.10.1/32 endpoint 192.168.10.1:58372 sudo ip link set wg0 up
endpointは接続先の(wireguard外の)アドレスとポートを指定する。
allowed-ipsは接続先のwireguardアドレスを指定するパラメータではない(最初勘違いしていた)。allowed-ipsは、wireguardデバイスにルーティングするアドレスの範囲を指定するパラメータだと考えておけばいいと思う。つまり、宛先がallowed-ipsの範囲になっているパケットを送信したときだけ、wireguardを使用して通信することになる。
ここまでのコマンドで、端末Aと端末Bの間でwireguardによる通信ができるようになっているはず。うまくいかない場合は、ファイアウォールの設定やルーティングテーブルを確かめてみるといいかもしれない。
ルーティングテーブルは自動で追加されるはずだが、ファイアウォールの設定は自分で変更する必要がある。sudo wg
と打つとwireguardの設定が確認できる。
1.2 設定ファイルとwg-quickによる設定
上記のコマンドを実行後、sudo wg showconf wg0
を実行するとwg0デバイスの設定を出力できる。(端末A側)
[Interface] ListenPort =58372 PrivateKey = GBgUVWu18mmsGsXuHF2ALhCcp5ujxP/bYQfLiMnetE0= [Peer] PublicKey = aObOVpHOJz02ooyP/Q/I/rvZ34N+tDBOaDj0IVRkSTE= AllowedIPs =10.0.10.2/32 Endpoint =192.168.10.2:49582
この出力を/etc/wireguard/wg0.conf
に保存する。wg showconf
コマンドはなぜかIPアドレスの設定は出力してくれないので、ここだけ書き足す必要があるらしい。
(端末A側、以下を/etc/wireguard/wg0.confに保存する)
[Interface] Address =10.0.10.1/24 ListenPort =58372 PrivateKey = GBgUVWu18mmsGsXuHF2ALhCcp5ujxP/bYQfLiMnetE0= [Peer] PublicKey = aObOVpHOJz02ooyP/Q/I/rvZ34N+tDBOaDj0IVRkSTE= AllowedIPs =10.0.10.2/32 Endpoint =192.168.10.2:49582
/etc/wireguard/wg0.conf
を保存すると、wg-quick
コマンドを使って1.1でやった設定がコマンド一つでできるようになる。sudo wg-quick up wg0
でwg0を立ち上げ、sudo wg-quick down wg0
で終了する。
ネットワークマネージャを使用している場合、wireguardのインターフェースを管理外にしておくとよい。また、NetworkManagerやsystemd-neworkdの場合、ネットワークマネージャの中でwireguardの設定をすることもできる。
2.クライアントサーバー構成での設定
ここでは、片方がパブリックIPアドレスを持っていて、もう片方が持っていない(NATの後ろにいる)場合を考える。- サーバー側
パブリックIPアドレス…xxx.xxx.xx.xx
WireGuard上で使用するアドレス…10.0.10.1/24
- クライアント側
WireGuard上で使用するアドレス…10.0.10.2/24
(サーバー側の設定ファイル)
[Interface] Address =10.0.10.1/24 ListenPort =37592 PrivateKey = gJzMdvIYtjQK4F4ByX7+VAr6Jwdvc0aM569mGoAZbWc= [Peer] PublicKey = xBDPrj9tImfkq9cik3DD4bYh58vZLFOyX2qrDJ+h2wg= AllowedIPs =10.0.10.2/32
(クライアント側の設定ファイル)
[Interface] Address =10.0.10.2/24 PrivateKey =AIjLmFtepSUCsR2DGQyxwlvZvApYUqEhx5XFxc9bzWI= [Peer] PublicKey =mCkiZWb2XhnaWzzR9wzg0aCwAAsKy4Nvy8wUVNiWyTY= Endpoint = xxx.xxx.xx.xx:37592 PersistentKeepalive =25 AllowedIPs =10.0.10.2/32
Enspointの設定は片方だけでも接続できる(wireguardはピアをIPアドレスではなくPublicKeyで識別する)ので、クライアント側だけEndpointを設定する。
この場合、接続を安定させるためにPersistentKeepaliveを設定しておいたほうがよい(指定した秒数おきに接続を確認するパケットを送ることで、切断されないようにする)。
3.クライアントの全パケットをwireguard経由にする
クライアント →(wireguard)→ サーバー → 出口(外部インターネット)クライアント ←(wireguard)← サーバー ← 出口(外部インターネット)
このように、クライアントから外部への通信をwireguard経由にする。
3.1 wireguardの設定
wireguardの設定は、上の設定のAllowedIPsを変更するだけでよい。(サーバー側の設定ファイル)
[Interface] Address =10.0.10.1/24 ListenPort =37592 PrivateKey = gJzMdvIYtjQK4F4ByX7+VAr6Jwdvc0aM569mGoAZbWc= [Peer] PublicKey = xBDPrj9tImfkq9cik3DD4bYh58vZLFOyX2qrDJ+h2wg= AllowedIPs =10.0.10.2/32
(クライアント側の設定ファイル)
[Interface] Address =10.0.10.2/24 PrivateKey =AIjLmFtepSUCsR2DGQyxwlvZvApYUqEhx5XFxc9bzWI= [Peer] PublicKey =mCkiZWb2XhnaWzzR9wzg0aCwAAsKy4Nvy8wUVNiWyTY= Endpoint = xxx.xxx.xx.xx:37592 PersistentKeepalive =25 AllowedIPs =0.0.0.0/0
これでクライアントが送信するパケットはすべてwireguardサーバーにルーティングされるようになる。
wireguardの設定はこれで終わりだが、サーバー側ではファイアウォールでNATの設定をする必要がある。(やることはルーターと同じ)
3.2 ファイアウォールの設定の一例
ここではnftablesを使ってみる。sudo sysctl -w net.ipv4.ip_forward=1 sudo nft add table ip nat sudo nft add chain ip nat postrouting {type nat hook postrouting priority srcnat \; policy accept \;} sudo nft add rule ip nat postrouting ip saddr 10.0.10.0/24 oifname eth1 masquerade
(eth1は適切なインターフェース名に置き換えること)
また、/etc/wireguard/wg0.conf
の[Interface]でPostUp
やPreDown
を設定すると、wg-quick
で立ち上げるときや落とすときにコマンドを実行することができる。ファイアウォールの設定はPostUpやPreDownで設定すると便利。
3.3 DNSの設定
上記の設定でほとんどうまくいくのだが、まだDNSの問題が残っている。DNSはデフォルトだとルーターのプライベートIPアドレス(192.168.1.1)になっていることが多いが、これがサーバー側に転送されると失敗する可能性が高い。
DNS設定を変更し、パブリックDNSのアドレス(1.1.1.1や8.8.8.8など)を設定するのが分かりやすいと思う。
たとえばNetworkManagerを使用している場合、まず
/etc/NetworkManager/NetworkManager.conf
の[main]
でdns=none
を設定し、NetworkManagerのDNS管理を無効にしてから、/etc/resolv.conf
でnameserver 1.1.1.1
を設定する。参考リンク
https://www.wireguard.com/quickstart/https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
https://wiki.archlinux.jp/index.php/WireGuard