はじめに
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
終わりに
おわり!
コメント