OpenVPN のサーバーを止めて WireGuard に完全に移行しようとしたところ、 WireGuard でつないでいるホストから家の LAN の中へのルーティングの設定をまだしていなかったことに気づいたので、 設定を追加しました。

動作確認環境

  • 外側ホスト Ubuntu 18.04.4 LTS
  • VPN から LAN 内へのルーターとなるホスト Raspbian GNU/Linux 10 (buster)

ネットワーク構成

  • 物理: 外側ホスト -(インターネット)- 家庭用ルーター -(LAN)- Raspbian
  • 論理: 外側ホスト -(wireguard 10.192.122.0/24)- Raspbian -(LAN 192.168.0.0/24)- LAN内の他のノード

外部ホスト側

LAN 内部に通信したい外部ホスト側では Peer ルーターとなるホストの Peer の AllowedIPs に LAN のサブネット (この例では 192.168.0.0/24) を追加します。

[Interface]
Address = 10.192.122.1/32
ListenPort = 51820
PostUp = wg set %i private-key <(cat /etc/wireguard/privatekey.wg0)

[Peer]
PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
AllowedIPs = 10.192.122.3/32
AllowedIPs = 192.168.0.0/24

ルーターとなる LAN 内のホスト側

LAN の他のノードは wireguard のサブネットからのパケットが届いても、 そのままだと返事をデフォルトゲートウェイの方に送ってしまうので、 Raspbian で NAT します。

sysctl の設定は /etc/sysctl.d/50-local.conf を作成して、そちらで設定しても良いのですが、 設定をまとめるために PostUpsysctl net.ipv4.ip_forward=1 を入れています。 sysctl net.ipv4.ip_forward=0 に戻す必要はないので、 PostDown の例を書いていますが、コメントアウトしています。

LAN 内の他のノードからは Raspbian との通信になるように NAT の設定をします。 eth0ens0 などの揺れをまとめるために out 側の指定は e+ にしています。 Raspberry Pi は wlan0 もあるので、そちらも設定しています。

最初に中からつないでおかないと外からの接続ができないので、 適当に ping で接続開始するようにして、 PersistentKeepAlive で維持するようにしています。

[Interface]
Address = 10.192.122.3/32
ListenPort = 51820
PostUp = wg set %i private-key <(cat /etc/wireguard/privatekey.wg0)
PostUp = sysctl net.ipv4.ip_forward=1
PostUp = iptables -A FORWARD -i %i -s 10.192.122.0/24 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -s 10.192.122.0/24 -o e+ -j MASQUERADE
PostUp = iptables -A FORWARD -i %i -s 10.192.122.0/24 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -s 10.192.122.0/24 -o wlan+ -j MASQUERADE
PostDown = iptables -A FORWARD -i %i -s 10.192.122.0/24 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -s 10.192.122.0/24 -o wlan+ -j MASQUERADE
PostDown = iptables -A FORWARD -i %i -s 10.192.122.0/24 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -s 10.192.122.0/24 -o e+ -j MASQUERADE
#PostDown = sysctl net.ipv4.ip_forward=0
PostUp = ping -c 1 10.192.122.1

[Peer]
PublicKey = TrMvSoP4jYQlY6RIzBgbssQqY3vxI2Pi+y71lOWWXX0=
Address = 10.192.122.1/32
Endpoint = peer1.example.com:51820
PersistentKeepAlive = 25

firewall での制限をしている場合は、 ufw route allow from 10.192.122.0/24 などでの許可も必要です。

動作確認

外側ホストから ping 192.168.0.1 などが通るのを確認します。

OpenVPN との違い

OpenVPN だとサーバー側の conf で

route 192.168.0.0 255.255.255.0
push "route 192.168.0.0 255.255.255.0"

と設定して、 LAN 側のノードの ccd で

iroute 192.168.0.0 255.255.255.0

と設定すれば OpenVPN に接続するノード全てから LAN 内への通信をルーティングできた (LAN 側のノードで nat 設定は同じように必要だった) のですが、 wireguard のこの設定方法だと、

  • モバイルノード -(wireguard)- VPSのホスト -(wireguard)- LAN内のホスト

という接続で、モバイルノードの Peer が「VPSのホスト」だけだと、 そこの AllowedIPs に LAN のサブネットを追加しても LAN 内のホストに転送してくれないので もうちょっと悩みそうです。

その他 (tailscale)

最近は tailscale (tailscale/talescale) という wireguard を使ったメッシュ型のネットワークをいい感じに管理してくれるサーバーがある (OSS で無料プランや有料のサーバーもある) ようなので、 用途によってはこちらを使うのも良いかもしれません。

Disqus Comments

Kazuhiro NISHIYAMA

Ruby のコミッターとかやってます。 フルスタックエンジニア(って何?)かもしれません。 About znzに主なアカウントをまとめました。

znz znz


Published