netwrokVPN自宅Lab

VPSと自宅のSite-to-SiteなVPNをWireGuardのDockerで構築 (ついでにOSPFでつなぐ)

はじめに

Xserverでブログ用のVPSを契約しているが,VPSに対してPrometheusのExporterでの監視やsyslog監視をやりたい.だが,暗号化の設定がめんどくさい.なので,VPSと自宅の環境をSite-to-Site VPNでつないで簡単にVPSへ接続できる環境をつくりたい.VPNといえば,IPSecやOpenVPNなどがありますが,構築のしやすさからWireGuardを使用します.

概要

自宅環境にはProxmox上で動いているVM上にWireGuard Cilientを用意して,XServerのVPS上のWireGuard Serverとつなぎます.VPSをWireguard Serverしているのは,マンションのインターネット回線を利用しているため,自宅環境にグローバルIPがないからです...(グローバルIPほしい)

別にWireGuardでつなぐだけでも良かったのですが,VPS上から自宅環境のすべてのサブネットとの疎通性がほしかったのでFRRoutingでOSPFのネイバーを張ってます.

サーバ側 (VPS側)

まずは,サーバ側の構成から説明していきます.
ディレクトリ構成は以下の通り.

$ tree --gitignore --dirsfirst -CF -L 3
./
├── frr/
│   └── etc/
│       └── frr/
├── wireguard/
│   ├── config/
│   │   ├── coredns/
│   │   ├── peer1/
│   │   ├── peer2/
│   │   ├── peer3/
│   │   ├── server/
│   │   ├── templates/
│   │   └── wg_confs/
│   └── env
└── docker-compose.yml

12 directories, 2 files

docker-compose.yml

wireguardのコンテナとfrrのコンテナを設定しています.networkはhostで.

version: "3"

services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wiregurad_server
    restart: unless-stopped
    network_mode: host
    env_file:
      - ./wireguard/env
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
      - LOG_CONFS=true
    volumes:
      - ./wireguard/config/:/config/
      - /lib/modules:/lib/modules
    cap_add:
      - NET_ADMIN
      - SYS_MODULE  # for iptables

  frr:
    image: frrouting/frr
    container_name: wiregurad_frr
    restart: unless-stopped
    network_mode: host
    privileged: true
    volumes:
      - ./frr/etc/frr/daemons:/etc/frr/daemons
      - ./frr/etc/frr/frr.conf:/etc/frr/frr.conf
      - ./frr/etc/frr/vtysh.conf:/etc/frr/vtysh.conf
      # - ./frr/var/run/frr/:/var/run/frr/
      - ./frr/var/log/:/var/log/
    environment:
      TZ: Asia/Tokyo

wireguard/env

WireGuardの設定は,環境変数で渡します.私の環境だと以下の通り.SERVERPORT,PEERSはお好みで.

SERVERURL=<VPSのIPアドレス or ドメイン名>
SERVERPORT=5188
PEERS=3
PEERDNS=<DNSサーバのアドレス>
INTERNAL_SUBNET=172.16.200.0/24
ALLOWEDIPS=0.0.0.0/0

wg0.confの編集

wg0.confはenvから自動生成されますが一部編集します.私はdocker runして生成されたwg0.confを以下のように編集しています.ens3は自分の環境に合わせてください.AllowedIPsも編集します.AllowedIPsには,OPSFのマルチキャストのためのサブネットを含めておきます.

[Interface]
Address = 172.16.200.1/24
ListenPort = 5188
PrivateKey = <生成された鍵>
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE

[Peer]
# peer1 (自宅のサーバからつなぐ用)
PublicKey = <生成された鍵>
PresharedKey = <生成された鍵>
AllowedIPs = 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,224.0.0.0/24

[Peer]
# peer2
PublicKey = <生成された鍵>
PresharedKey = <生成された鍵>
AllowedIPs = 172.16.200.3/32

[Peer]
# peer3
PublicKey = <生成された鍵>
PresharedKey = <生成された鍵>
AllowedIPs = 172.16.200.4/32

ホストの設定

wireguardでは,以下の設定が必要なので入れておきます.

$ cat << EOS | sudo tee -a /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.src_valid_mark=1
EOS
$ sudo sysctl -p

FRRoutingの設定

daemonやvtysh.confに特に特殊な設定はないので割愛します.
frr.confの設定は以下のとおりで,OSPFを有効にしているだけです.AllowedIPsにマルチキャストを設定しているので必要ないかもしれませんが,一応neighborを静的に指定してマルチキャストなしの設定にしておきます.

!
interface wg0
  ip ospf area 0.0.0.0
  ip ospf network point-to-point
  ip ospf mtu-ignore
  ip ospf cost 100
!
interface lo
  ip address 192.168.255.250/32
  ip ospf area 0.0.0.0
  ip ospf passive
!
router ospf
  ospf router-id 192.168.255.250
  neighbor 172.16.200.2
exit

実行

$ docker compose up -d

クライアント側 (自宅サーバ側)

続いて,クライアント側を設定していきます.

$ tree --gitignore --dirsfirst -CF -L 3
./
├── frr/
│   ├── etc/
│   │   └── frr/
│   └── var/
│       └── log/
├── wireguard/
│   └── config/
│       └── wg_confs/
└── docker-compose.yml

8 directories, 1 file

docker-compose.yml

サーバ側と同じく,wireguardとfrrのコンテナを設定しています.クライアントモードで実行するので,PEERといった変数は渡しません.

version: "3"

services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wiregurad_client
    restart: unless-stopped
    network_mode: host
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
      - LOG_CONFS=true
    volumes:
      - ./wireguard/config/wg_confs:/config/wg_confs/
      - /lib/modules:/lib/modules
    cap_add:
      - NET_ADMIN
      - SYS_MODULE  # for iptables

  frr:
    image: frrouting/frr
    container_name: wiregurad_frr
    restart: unless-stopped
    network_mode: host
    privileged: true
    volumes:
      - ./frr/etc/frr/daemons:/etc/frr/daemons
      - ./frr/etc/frr/frr.conf:/etc/frr/frr.conf
      - ./frr/etc/frr/vtysh.conf:/etc/frr/vtysh.conf
      - ./frr/var/log/:/var/log/
    environment:
      TZ: Asia/Tokyo

peer1.conf

サーバ側でpeer1/にpeer1.confが生成されているので以下のように編集し,クライアントの./wireguard/config/wg_confs/に置きます.iptablesは,パケットを転送するために必要なので設定します.

[Interface]
Address = 172.16.200.2/24
PrivateKey = <生成された鍵>
Table = off
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT

[Peer]
PublicKey = <生成された鍵>
PresharedKey = <生成された鍵>
Endpoint = <サーバのアドレスorドメイン>:5188
AllowedIPs = 0.0.0.0/0

ホストの設定

クライアント側にもサーバと同じ設定を入れておきます.

$ cat << EOS | sudo tee -a /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.src_valid_mark=1
EOS
$ sudo sysctl -p

FRRoutingの設定

サーバ側とほとんど同じです.ens19は環境に合わせて変更してください.

!
interface ens19
  ip ospf area 0.0.0.0
  ip ospf mtu-ignore
  ip ospf cost 100
!
interface peer1
  ip ospf area 0.0.0.0
  ip ospf network point-to-point
  ip ospf mtu-ignore
  ip ospf cost 100
!
interface lo
  ip address 192.168.255.221/32
  ip ospf area 0.0.0.0
!
!
router ospf
  ospf router-id 192.168.3.55
  neighbor 172.16.200.1
exit
!

実行

$ docker compose up -d

動作確認

サーバ側

wg show でpeerの状態を確認します.接続できている場合,handshakeの情報などが表示されます.

$ docker compose exec wireguard wg show
interface: wg0
  public key: sbyahmG66VXRCvbCZvb8QHM9UiYP+xzcVxv4bxXbxRA=
  private key: (hidden)
  listening port: 5182

peer: 9l7wZ2xQ0eMu9nn9NtgLqD+aKrKsiEqTofkL2vCBNGs=
  preshared key: (hidden)
  endpoint: <自宅サーバのアドレス>
  allowed ips: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/24
  latest handshake: 18 seconds ago
  transfer: 131.23 MiB received, 912.49 MiB sent

(略)

続いて,OSPFの状態を確認します.ネイバーがFull stateであればOKです.

$ docker compose exec frr vtysh

Hello, this is FRRouting (version 8.4_git).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

xvpsu24n01.frr# show ip ospf neighbor 

Neighbor ID     Pri State           Up Time         Dead Time Address         Interface                        RXmtL RqstL DBsmL
192.168.3.55      1 Full/-          6d23h28m          31.696s 172.16.200.2    wg0:172.16.200.1                     0     0     0

pingでクライアントへ疎通性があることを確認しておきます.

$ ping 192.168.255.221
PING 192.168.255.221 (192.168.255.221) 56(84) bytes of data.
64 bytes from 192.168.255.221: icmp_seq=1 ttl=64 time=11.2 ms
64 bytes from 192.168.255.221: icmp_seq=2 ttl=64 time=12.6 ms
64 bytes from 192.168.255.221: icmp_seq=3 ttl=64 time=11.2 ms
^C
--- 192.168.255.221 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 11.191/11.678/12.644/0.682 ms

クライアント側

wg showで接続できていることを確認する.

$ docker compose exec wireguard wg show
interface: peer1
  public key: 9l7wZ2xQ0eMu9nn9NtgLqD+aKrKsiEqTofkL2vCBNGs=
  private key: (hidden)
  listening port: 37863

peer: sbyahmG66VXRCvbCZvb8QHM9UiYP+xzcVxv4bxXbxRA=
  preshared key: (hidden)
  endpoint: <サーバ側のアドレス>:5182
  allowed ips: 0.0.0.0/0
  latest handshake: 1 minute, 11 seconds ago
  transfer: 341.10 MiB received, 53.03 MiB sent

サーバのloへの疎通性があればOKです.

$ ping 192.168.255.250
PING 192.168.255.250 (192.168.255.250) 56(84) bytes of data.
64 bytes from 192.168.255.250: icmp_seq=1 ttl=64 time=10.9 ms
64 bytes from 192.168.255.250: icmp_seq=2 ttl=64 time=11.4 ms
64 bytes from 192.168.255.250: icmp_seq=3 ttl=64 time=11.3 ms
^C
--- 192.168.255.250 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 10.929/11.191/11.394/0.194 ms

終わりに

おわり!

コメント

タイトルとURLをコピーしました