IPv6 通信も WireGuard で自宅経由の VPN にする
目次
はじめに
前回の記事 にて、自宅の Linux ルータと Android スマートフォンとの間で WireGuard で VPN 接続するという内容を記載しました。
その記事では IPv4 通信しか自宅経由にしていなかったため、IPv6 インターネットとの疎通性のあるネットワークに接続している場合、IPv6 通信は自宅経由にならないという課題がありました。
そこで、本記事では IPv6 通信も自宅経由にし、VPN として安全に利用できるようにします。
どの IPv6 アドレスを利用するか
Android の WireGaurd アプリでは、IPv6 通信を VPN 側に向けるには、WireGuard アプリで何らかの IPv6 アドレスを設定する必要があります。
VPN 経由で IPv6 インターネットと通信したいので、当然グローバルアドレスを利用すべきところです。 しかし、Temporary アドレスを設定できないため、固定のグローバルアドレスを付けることになり、それはちょっと避けたい気持ちが少しだけあります。
他の選択肢として、ユニークローカルアドレスを利用するという方法も考えられます。 この場合、VPN 接続先であるルータではIPマスカレードする必要が出てきますが、ルータの Temporary アドレスを使わせることができます。 しかし、ユニークローカルアドレスをそのような目的で利用するのは適切ではありません。
少し検討した結果、グローバルアドレスを利用することにしました。 ただ、考え直す可能性もあり、動作検証もしたので、本記事ではユニークローカルアドレスを利用する方法についても併記します。
Android スマートフォンの設定
利用する IPv6 アドレス決め
まず、Android スマートフォンで利用する IPv6 アドレスを決めましょう。
私の自宅のインターネット回線の契約では /64 のプレフィックスのグローバルアドレスしか利用できないため、その範囲内でアドレスを1つ決めました。
本記事では例として 2400:X:X:X::92
としています。
ユニークローカルアドレスを利用するのであれば、RFC 4193 に従ってランダムなプレフィックスを生成し、その範囲でアドレスを決めましょう。
WireGuard アプリの設定
決めたアドレスを WireGuard アプリに設定しましょう。
アドレスの入力欄にカンマ区切りで複数記載できますので、IPv4 アドレスと併記します。
また、Allowed IPs (実質的に VPN に転送する経路と同じ) に ::/0
も追加します。
その他設定はお好みで良いです。
自宅側 Linux ルータの設定
前回の記事 や Linux ルータの構築記事 で行った設定をベースに、自宅側 Linux ルータの設定変更を行っていきます。
systemd-networkd の設定
systemd-networkd の設定としては、次の2つの変更を加えましょう。
- Android スマートフォン側に設定した IPv6 アドレスを送信元とする通信を WireGaurd トンネルで許可する
- 上記 IPv6 アドレスへの経路を WireGuard トンネルに向ける
1## トンネルインターフェースの設定を変更
2$ sudo vim /etc/systemd/network/31-tun-android.netdev
3$ cat /etc/systemd/network/31-tun-android.netdev
4----------
5[NetDev]
6Name=tun-android
7Kind=wireguard
8
9[WireGuard]
10PrivateKeyFile={自宅側 Linux ルータの秘密鍵ファイルのパス}
11ListenPort=30001
12
13[WireGuardPeer]
14PublicKey={スマートフォンの公開鍵の文字列}
15AllowedIPs=192.168.9.2/32,2400:X:X:X::92/128 # Android に設定する IPv6 アドレスを追加
16----------
17
18
19## トンネルインターフェースのネットワーク設定を変更
20$ sudo vim /etc/systemd/network/31-tun-android.network
21$ cat /etc/systemd/network/31-tun-android.network
22----------
23[Match]
24Name=tun-android
25
26[Route]
27Destination=192.168.9.2/32
28
29# 以下の Route セクションを追加
30[Route]
31Destination=2400:X:X:X::92/128
32----------
33
34
35## 設定変更を反映
36$ sudo systemctl restart systemd-networkd.service
設定変更後の WireGuard トンネルのステータスやルートテーブルは次のような感じです。
1## WireGuard のステータス確認
2$ sudo wg show tun-android
3----------
4interface: tun-android
5 public key: {自宅側 Linux ルータの公開鍵}
6 private key: (hidden)
7 listening port: 30001
8
9peer: {スマートフォンの公開鍵}
10 allowed ips: 2400:X:X:X::92/128, 192.168.9.2/32
11----------
12
13
14## IPv6 ルートテーブルの確認
15$ ip -6 route
16----------
172400:X:X:X::92 dev tun-android proto static metric 1024 pref medium
18(その他経路は省略)
19----------
ユニークローカルアドレスを利用する場合でも、systemd-networkd の設定変更内容はアドレス以外は上記と違いはありません。
IPv6 インターネットへの転送許可設定
Android スマートフォンから WireGuard 経由での IPv6 インターネットへのアクセスは想定していなかったため、そのような通信は ip6tables
で DROP するようにしていました。
FORWARD チェインの DROP ルールより前に、次のような許可設定を入れましょう。
1$ sudo ip6tables -A FORWARD -i tun-android -o enp2s0 -j ACCEPT
ユニークローカルアドレスを利用する場合も同様です。
IPマスカレードの設定 (ユニークローカルアドレスを利用する場合のみ)
ユニークローカルアドレスを利用する場合、そのままではインターネットと通信できないため、Linux ルータのグローバルアドレスに SNAT (IPマスカレード) する必要があります。
ip6tables
の nat テーブルに MASQUERADE ルールを追加しましょう。
ソースで指定するユニークローカルアドレスは、将来に備えて /48 のプレフィックスを指定しても良いと思います。
1$ sudo ip6tables -t nat -A POSTROUTING -s fdXX:XXXX:XXXX::/48 -o enp2s0 -j MASQUERADE
ndppd の設定変更
フレッツ網側から Android スマートフォンのグローバルアドレスにパケットを返す際、私の自宅のインターネット回線の契約では、フレッツ網側に NDP でMACアドレスを解決できるようにする必要があります。
ndppd の設定を変更し、Android スマートフォンのグローバルアドレスの NS 要求に対して、Linux ルータのMACアドレスを NA で返すようにしましょう。
1$ sudo vim /etc/ndppd.conf
2$ cat /etc/ndppd.conf
3----------
4proxy enp2s0 {
5 router no
6 rule 2400:X:X:X::/64 {
7 iface enp3s0
8 }
9 # 以下の rule セクションを追加
10 rule 2400:X:X:X::92/128 {
11 static
12 }
13}
14----------
15
16
17$ sudo systemctl restart ndppd.service
ユニークローカルアドレスを利用する場合は上記の設定変更は不要です。
動作確認
IPv4 しか利用できないモバイル回線を使って動作確認してみます。
自宅と WireGuard 接続を行い、test-ipv6.com のサイトで確認してみました。
十分な結果ですね。
ユニークローカルアドレスを利用した場合も確認しましたが、上記と同様に十分な結果でした。
IPv4 / IPv6 のデュアルスタックな自宅 Wi-Fi 上で WireGuard 接続した場合も、WireGuard で設定した IPv6 アドレスが利用されていましたので、これで良いでしょう。
備考
IPv4 しか利用できないネットワークに接続しているのであれば、本記事のように IPv6 通信を利用できるようにする必要はないです。
ただ、IPv6 通信を利用できるようにすると、MAP-E の SNAT や IPv4 over IP6 のカプセル化を行わなくて済みますので、インターネット的には望ましい姿かもしれません。