wireguardの使い方
概要
- Linux Kernel 5.6から導入されたVPN
- Endpointとしてipv6を用いることもでき、このとき実質的にipv4 over ipv6(IPoE)接続になり、高速化が期待できることもある
- 類似のソフトウェアに/tailscale/がある
- tailscaleは通信が安定しない場合、公開relayサーバを経由して通信を継続することができるがネットワークパフォーマンスが低い
- wireguardはrelayサーバを経由することができないが、通信が安定するという特徴がある
- 手動でセットアップを行うと複雑だが、/pivpn/を用いると簡単にセットアップできる
よく使うコマンド
sudo wg show
: 接続状況を確認sudo wg-quick up wg0
: 設定ファイルを読み込んで起動sudo wg-quick down wg0
: 設定ファイルを読み込んで停止systemctl start wg-quick@wg0
: 設定ファイルを読み込んで起動systemctl restart wg-quick@wg0
: 設定ファイルを読み込んで再起動
注意
- AMD Ryzenの乱数発生が正しく動作しないという問題の影響を受ける
- mainboardのUEFIの最新化で正常化することができる
- 殆どの操作が
root
を期待している PostUp
で記すscriptは正常に動作しないことがある。その場合、別途、そのスクリプトは実行する必要がある
install
debian
$ echo "deb http://deb.debian.org/debian buster-backports main" | sudo tee /etc/apt/sources.list.d/buster-backports.list
$ sudo apt install update
$ sudo apt install wireguard
ubuntu
$ sudo apt install wireguard
key generate
- 秘密鍵、公開鍵を作る
秘密鍵
# wg genkey > privatekey
公開鍵
# wg pubkey < privatekey > publickey
設定ファイルを作成する
# cd /etc/wireguard
# touch wg0.conf
すべてのIPをトンネリングするVPNの設定例
example server wg0.conf
[Interface]
Address = 192.168.0.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o mellanox0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o mellanox0 -j MASQUERADE
ListenPort = 41194
PrivateKey = 6LHnxqrlI/La9/jU*******ufUaGg=
[Peer]
PublicKey = VRu+7scEAwQinRwlOiGvZili5AlIghdcmAF1KkRWryk=
AllowedIPs = 192.168.0.4/32
Endpoint = 126.133.200.64:1900
[Peer]
PublicKey = H/mcwTJnYM5VgR2J+DqTnLOq7Wj/fl4v1nt2XQidXm8=
AllowedIPs = 192.168.0.5/32, 2a03:b0c0:2:f0::2c:2005/128
Endpoint = 126.133.200.64:1395
- この設定は
wg-quick down wg0
するたびに、プログラムによって上書きされるので、wg-quick down wg0
してから編集する PostUp
はIFのアップ時に走るスクリプト。この例ではIP 4, IP 6をmellanox0
デバイス側に向けてnatで転送する- 一部の環境ではこの転送ルールは動かないので、別途スクリプトを分けて実行する必要がある
PostDown
でiptables
コマンドで解除しているスクリプトもあるが、適応すると何度もコマンドが打たれることになり、serverサイドが不安定になった[Peer]のPublicKey
はクライアントのMacOSXやiPhoneから発行される公開鍵。いちいちコピペするのが大変[Peer]のAllowdIPs
はクライアントが接続してきたらどのIPアドレスならば許可するかを示すもの。クライアント側の設定と食い違うと通信できないEndpoint
は設定しなくても自動で生成される。また、これでアクセス元を制限できる等のものでもない
enable server side ip forwarding
- debian, ubuntu系では以下の設定を入れないとIPのフォワードをしない
- この設定は再起動すると消えてしまうので、起動スクリプトに入れるなどの工夫が必要
- より詳細な設定については/sysctl/を参照
# sysctl -w net.ipv4.ip_forward=1
# sysctl -w net.ipv6.conf.all.forwarding=1
example up/donw wg0
# wg-quick up wg0 # 起動
# wg-quick down wg0 # 停止
# wg # ステータス表示
wg
コマンドでどのピアが接続しているかがわかる- サーバ側の
PublicKey
はwg
コマンドで確認することができる
wgコマンドで通信状況を確認した例
transferで通信量が見えるので、疎通は行われていることがわかる
systemdでサービス登録する
# wg-quick down wg0
# systemctl start wg-quick@wg0
# systemctl enable wg-quick@wg0
example client conf
[Interface]
PrivateKey = 2CYUPIwWR*******4vrUVOxDeyxm7EDq7m+l38=
Address = 192.168.0.5/32, 2a03:b0c0:2:f0::2c:2005/64
DNS = 1.1.1.1
[Peer]
PublicKey = a0nUQiZOtAbpsX7l1VLpA5TOQlKcL9yPCA47QXo5hDw=
AllowedIPs = 0.0.0.0/0, ::0/0
Endpoint = 192.168.40.23:41194 # IPv4で接続するとき
Endpoint = [2001:19f0:7002:dcd:5400:3ff:fe86:a14f]:41194 # IPv6で接続するとき
PersistentKeepalive = 1
[Interface]のAddress
のネットマスクは32のプレフィックスで与えないと他のノードが繋げなくなる[Peer]のPublicKey
はサーバの公開鍵を設定する[Peer]のAllowdIPs
は0.0.0.0/0
とすると全ての通信をwireguard経由で通信することになる::0/0
はすべてのIPv6パケットもトンネリングする、ということ
MacOSXでの設定
AppStore
にWireGuardのクライアントソフトがある- ソフトウェに
example client conf
の設定を記入して設定を行う
iPhoneでの設定
AppStore
にWireGuardのクライアントソフトがある- コピペしづらいので設定が大変である
グローバルIPを持たないクライアントをVPNサーバ兼踏み台サーバ(bastion)に接続する例
- UDPの仕組みから片方のpeerがポートがNATの内側の場合でもネットワークの構築が可能
サーバの設定例
[Interface]
Address = 192.168.200.1/24
SaveConfig = false
ListenPort = 41194
PrivateKey = 0**********ya9o1d1FZiw/tnTeSavmuG3JmjdQtpNUE=
[Peer]
PublicKey = a0nUQiZOtAbpsX7l1VLpA5TOQlKcL9yPCA47QXo5hDw=
AllowedIPs = 192.168.200.23/32
Endpoint = 126.133.200.64:1900
クライアントの設定例
[Interface]
Address = 192.168.200.23/32 # アサインされるIPに設定する
SaveConfig = false
ListenPort = 41194
PrivateKey = 6**********U3PY0X3Zs8e5rlQRELO8dLufUaGg=
DNS = 1.1.1.1
[Peer]
PublicKey = 1DP3DtZd8jLo9PvSiLTY2KZlaYbTdvsQI5jdbfHlh0g=
# AllowedIPs = 0.0.0.0/0, ::0/0
AllowedIPs = 192.168.200.23/24 # ここが正しく設定されていないと疎通できない
Endpoint = 138.2.4.109:41194 # IPv4で接続するとき
# Endpoint = [2001:19f0:7002:dcd:5400:3ff:fe86:a14f]:41194 # IPv6で接続するとき
PersistentKeepalive = 1
AllowdIPs
でip routeで優先されるサブネットを適切に設定する必要がある
トラブルシューティング
- macOSでドメインが解決できない
- 原因
- wireguardのDNSがIPの範囲を超えて反映される
- 挙動的にはバグと思われる
- 対応
- macOS + wireguardの場合、wireguard側でDNSを設定しない
- 原因