この記事はLinuxで作るL2TP/WireGuardネットワークの一部です。

ここまでLinuxのl2tp_ethモジュールを使ってL2ネットワークを作るWireGuardでL3VPNを作るを行ってきました。 最後にこれらを組み合わせて、L2TP/WireGuardによる拠点間で共通のセグメントを持つL2ネットワークを作ってみます。

L2TP/WireGuard ネットワーク図

WireGuardの設定

WireGuardの設定は、WireGuardでL3VPNを作ると完全に同じです。 特に変更する必要はありません。

vpn01側の設定

L2TPによる通信をWireGuard上で行うようにします。これによりL2TPの通信が暗号化され、WireGuardの利用者以外は盗聴できなくなります。 設定は特に難しいものではなく、以前設定したL2TPのネットワークの l2tp用ローカルIPアドレスとリモートIPアドレスをWireGuard上のものに変更し、MTUを調整するだけです。 (おそらくMTUの調整が最難関)

  • ローカルトンネルID: 3939
  • リモートトンネルID: 3940
  • ローカルセッションID: 3941
  • リモートセッションID: 3942
  • ローカルIPアドレス: 10.0.2.11
  • リモートIPアドレス: 10.0.2.21
  • ローカルポート: 1701
  • リモートポート: 1701

ip l2tp add tunnelのオプションlocalremoteのIPv4アドレスと、l2tpeth0のMTUの値のみ変更しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/sh

# WireGuardを開始
wg-quick up wg0

# L2TPを設定
ip l2tp add tunnel \
        tunnel_id 3939 \
        peer_tunnel_id 3940 \
        encap udp \
        local 10.0.1.11 \
        remote 10.0.1.21 \
        udp_sport 1701 \
        udp_dport 1701
ip l2tp add session \
        tunnel_id 3939 \
        session_id 3941 \
        peer_session_id 3942
ip link set dev l2tpeth0 up mtu 1386

# Bridgeを設定
ip link add br-l2tp0 type bridge
ip addr add 10.0.2.11/24 dev br-l2tp0
ip link set dev br-l2tp0 up
ip link set dev l2tpeth0 master br-l2tp0
ip link set dev eth1 master br-l2tp0
ip link set dev eth1 up

vpn02側の設定

vpn01と同様に、ip l2tp add tunnelのオプションlocalremoteのIPv4アドレスと、l2tpeth0のMTUの値のみ変更しました。

  • ローカルトンネルID: 3940
  • リモートトンネルID: 3939
  • ローカルセッションID: 3942
  • リモートセッションID: 3941
  • ローカルIPアドレス: 10.0.2.21
  • リモートIPアドレス: 10.0.2.11
  • ローカルポート: 1701
  • リモートポート: 1701
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/sh

# WireGuardを開始
wg-quick up wg0

# L2TPを設定
ip l2tp add tunnel \
        tunnel_id 3940 \
        peer_tunnel_id 3939 \
        encap udp \
        local 10.0.1.21 \
        remote 10.0.1.11 \
        udp_sport 1701 \
        udp_dport 1701
ip l2tp add session \
        tunnel_id 3940 \
        session_id 3942 \
        peer_session_id 3941
ip link set dev l2tpeth0 up mtu 1386

# Bridgeを設定
ip link add br-l2tp0 type bridge
ip addr add 10.0.2.21/24 dev br-l2tp0
ip link set dev br-l2tp0 up
ip link set dev l2tpeth0 master br-l2tp0
ip link set dev eth1 master br-l2tp0
ip link set dev eth1 up

member01の設定

member01のeth0は、vpn01のeth1と同じL2セグメントに接続し、 MTUをL2TPインタフェースのものと同じにした上で、IPアドレスを設定します。 (これをやっておかないと、vpn01のブリッジインタフェースで詰まります。)

1
2
3
member01% sudo ip addr add 10.0.2.12/24 dev eth0
member01% sudo ip link set mtu 1386
member01% sudo ip link set dev eth0 up

member02の設定

member02はmember01と同様です。

1
2
3
member02% sudo ip addr add 10.0.2.22/24 dev eth0
member01% sudo ip link set mtu 1386
member02% sudo ip link set dev eth0 up

疎通確認

手順は以前設定したL2TPのネットワークと同じです。

1
2
3
4
5
6
7
8
9
member01% ping -c 3 10.0.2.22
PING 10.0.2.22 (10.0.2.22): 56 data bytes
64 bytes from 10.0.2.22: seq=0 ttl=64 time=2.789 ms
64 bytes from 10.0.2.22: seq=1 ttl=64 time=2.405 ms
64 bytes from 10.0.2.22: seq=2 ttl=64 time=2.689 ms

--- 10.0.2.22 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 2.405/2.627/2.789 ms
1
2
3
4
5
6
7
8
9
member02% ping -c 3 10.0.2.11
PING 10.0.2.11 (10.0.2.11): 56 data bytes
64 bytes from 10.0.2.11: seq=0 ttl=64 time=2.209 ms
64 bytes from 10.0.2.11: seq=1 ttl=64 time=1.456 ms
64 bytes from 10.0.2.11: seq=2 ttl=64 time=1.787 ms

--- 10.0.2.11 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.456/1.817/2.209 ms

member01-member02間でも問題無く通信できていることが確認できました。 ついでにtcpdumpでキャプチャするなどして、想定しない経路で通信していないかも確認しておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vpn01% sudo tcpdump -i wg0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
02:52:12.470063 IP 10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:12.470222 IP 10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:13.471020 IP 10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:13.471179 IP 10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:14.471534 IP 10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:14.471569 IP 10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:17.486126 IP 10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:17.487443 IP 10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:17.523958 IP 10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:52:17.523975 IP 10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

MTUサイズの計算

利用するネットワークのMTUが1500の場合、下記のように計算します。

  • WireGuardネットワークに流せる最大値: 1500 - 20(IPv4) - 40(WireGuard) = 1440
  • L2TP/WireGuardネットワークのMTU: 1440 - 20(WireGuardのIPv4) - 8(UDP) - 8(L2TP) - 4(HDLC) - 14(L2TP上のEthernet) = 1386
  • L2TP/WireGuardネットワーク上で送信できるIPv4パケットの最大値: 1386 - 20(L2TP上のIPv4) = 1366

もしフレッツ光などのPPPoEネットワークを用いてL2TP/WireGuardを行いたい場合、フレッツのMTUは1454なので、上記の計算から46引いた値を用いることになります。

MTUの検証

pingに-M doオプションを付けフラグメントを禁止し、-s 1358でL2TP/WireGuardネットワークで送信できるICMPパケットの最大サイズ(1366 - 8)を指定します。

1
2
3
4
5
6
7
vpn02:~# ping -c 1 -M do -s 1358 10.0.2.11
PING 10.0.2.11 (10.0.2.11) 1358(1386) bytes of data.
1366 bytes from 10.0.2.11: icmp_seq=1 ttl=64 time=1.05 ms

--- 10.0.2.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.046/1.046/1.046/0.000 ms

L2TPで用いられているwg0インタフェースの通信をキャプチャし、フラグメントしていない事を確認します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vpn01% sudo tcpdump -i wg0 -v -n udp dst port 1701
tcpdump: listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
02:38:55.804536 IP (tos 0x0, ttl 64, id 42369, offset 0, flags [none], proto UDP (17), length 1440)
    10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:38:55.804745 IP (tos 0x0, ttl 64, id 11444, offset 0, flags [none], proto UDP (17), length 1440)
    10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:39:00.820853 IP (tos 0x0, ttl 64, id 42370, offset 0, flags [none], proto UDP (17), length 82)
    10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:39:00.820983 IP (tos 0x0, ttl 64, id 11445, offset 0, flags [none], proto UDP (17), length 82)
    10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:39:00.845357 IP (tos 0x0, ttl 64, id 11446, offset 0, flags [none], proto UDP (17), length 82)
    10.0.1.11.1701 > 10.0.1.21.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
02:39:00.845690 IP (tos 0x0, ttl 64, id 42371, offset 0, flags [none], proto UDP (17), length 82)
    10.0.1.21.1701 > 10.0.1.11.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
^C
6 packets captured
6 packets received by filter
0 packets dropped by kernel

同様にWireGuardで用いられているeth0インタフェースの通信状況をキャプチャし、フラグメントしていない事を確認します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vpn01% sudo tcpdump -i eth0 -v -n udp dst port 8172
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
02:36:05.311775 IP (tos 0x0, ttl 64, id 26301, offset 0, flags [none], proto UDP (17), length 1500)
    192.168.122.32.47374 > 192.168.122.24.8172: UDP, length 1472
02:36:05.311926 IP (tos 0x88, ttl 64, id 26302, offset 0, flags [none], proto UDP (17), length 176)
    192.168.122.32.47374 > 192.168.122.24.8172: UDP, length 148
02:36:05.312961 IP (tos 0x0, ttl 64, id 26303, offset 0, flags [none], proto UDP (17), length 60)
    192.168.122.32.47374 > 192.168.122.24.8172: UDP, length 32
02:36:10.340634 IP (tos 0x0, ttl 64, id 26572, offset 0, flags [none], proto UDP (17), length 156)
    192.168.122.32.47374 > 192.168.122.24.8172: UDP, length 128
02:36:10.368506 IP (tos 0x0, ttl 64, id 26573, offset 0, flags [none], proto UDP (17), length 156)
    192.168.122.32.47374 > 192.168.122.24.8172: UDP, length 128
^C
5 packets captured
5 packets received by filter
0 packets dropped by kernel

これでL2TP/WireGuardによる拠点間で共通のセグメントを持つL2ネットワークを作ることができました。 最後にiperf3でパフォーマンスを確認しておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
member01% iperf3 -s
-----------------------------------------------------------
Server listening on 5201 (test #1)
-----------------------------------------------------------
Accepted connection from 10.0.2.22, port 53624
[  5] local 10.0.2.12 port 5201 connected to 10.0.2.22 port 53626
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  78.4 MBytes   658 Mbits/sec                  
[  5]   1.00-2.00   sec  91.0 MBytes   763 Mbits/sec                  
[  5]   2.00-3.00   sec  87.4 MBytes   733 Mbits/sec                  
[  5]   3.00-4.00   sec  89.0 MBytes   747 Mbits/sec                  
[  5]   4.00-5.00   sec  94.5 MBytes   793 Mbits/sec                  
[  5]   5.00-6.00   sec  94.5 MBytes   792 Mbits/sec                  
[  5]   6.00-7.00   sec  92.5 MBytes   776 Mbits/sec                  
[  5]   7.00-8.00   sec  90.7 MBytes   761 Mbits/sec                  
[  5]   8.00-9.00   sec  90.5 MBytes   759 Mbits/sec                  
[  5]   9.00-10.00  sec  93.5 MBytes   785 Mbits/sec                  
[  5]  10.00-10.01  sec  1.22 MBytes   741 Mbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.01  sec   903 MBytes   757 Mbits/sec                  receiver
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
member02% iperf3 -c 10.0.2.12
Connecting to host 10.0.2.12, port 5201
[  5] local 10.0.2.22 port 53626 connected to 10.0.2.12 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  81.5 MBytes   684 Mbits/sec   63   1.05 MBytes       
[  5]   1.00-2.00   sec  91.2 MBytes   765 Mbits/sec    0   1.16 MBytes       
[  5]   2.00-3.00   sec  87.5 MBytes   734 Mbits/sec    0   1.24 MBytes       
[  5]   3.00-4.00   sec  88.8 MBytes   744 Mbits/sec    0   1.30 MBytes       
[  5]   4.00-5.00   sec  95.0 MBytes   797 Mbits/sec    3    998 KBytes       
[  5]   5.00-6.00   sec  93.8 MBytes   786 Mbits/sec    0   1.03 MBytes       
[  5]   6.00-7.00   sec  92.5 MBytes   776 Mbits/sec    0   1.09 MBytes       
[  5]   7.00-8.00   sec  91.2 MBytes   765 Mbits/sec    0   1.15 MBytes       
[  5]   8.00-9.00   sec  90.0 MBytes   755 Mbits/sec    0   1.20 MBytes       
[  5]   9.00-10.00  sec  93.8 MBytes   786 Mbits/sec    0   1.25 MBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec   905 MBytes   759 Mbits/sec   66             sender
[  5]   0.00-10.01  sec   903 MBytes   757 Mbits/sec                  receiver

iperf Done.

残された課題

  • MTU設定これでいいの?
    • 半分のうみそが寝てる状態でやったので自信がない
  • member側でのMTU設定
    • MTU設定できない端末はどうする?
    • 設定しなくてもいいようにしたい
      • フラグメントするのは諦めてvpn01・02で ip link set dev l2tpeth0 up mtu 1500 でよい?