Linux Network Namespace（その６：L2TP）

# Network NamespaceにてL2TP
Network Namespaceにて、L2TP（両端ネットワークが同一ネットワークセグメント）を実現する。

## ケース１
Namespaceの使い方の関係から、NGな設定を数回繰り返したこともあり、意図せず、２つのケースを紹介することとなった。まずは下記ネットワーク構成。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9cdabd66-bd4c-a037-b328-12c6f083b3d3.png", width=75%>

L2TPトンネル側でないルーターのインターフェース間の同一ネットワークセグメントのケースである。

### NGだったもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3ffb7398-af47-c08c-08c5-11579cfc2fde.png)

- Namespace ns1およびns2作成
- 仮想ネットワークインターフェースPairであるns1-veth0およびns2-veth0作成
- ns1-veth0をns1へ、ns2-veth0をns2へ配置
- ns1およびns2にて、L2TPインターフェースを作成
- ns1およびns2にて、dummyインターフェースns1-vethおよびns2-vethを作成
- ns1およびns2にて、L2TPインターフェースとdummyインターフェースをブリッジ化

これはNGであった。

### OK
さきほどのネットワーク構成で、動作したケースの説明。Namespace的には下記となる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3c29fe29-43ff-c776-3de2-69f3b23c7bf4.png", width=80%>

```shell
sudo ip netns add ns1
sudo ip netns add ns2
sudo ip link add name ns1-veth0 type veth peer name ns2-veth0
sudo ip link set ns1-veth0 netns ns1
sudo ip link set ns2-veth0 netns ns2
sudo ip netns exec ns1 ip link set lo up
sudo ip netns exec ns1 ip link set ns1-veth0 up
sudo ip netns exec ns1 ip addr add 172.16.1.1/24 dev ns1-veth0
sudo ip netns exec ns2 ip link set lo up
sudo ip netns exec ns2 ip link set ns2-veth0 up
sudo ip netns exec ns2 ip addr add 172.16.1.2/24 dev ns2-veth0
```

- Namespace ns1およびns2作成
- 仮想ネットワークインターフェースPairであるns1-veth0およびns2-veth0作成
- ns1-veth0をns1へ、ns2-veth0をns2へ配置
- ns1およびns2にて、L2TPインターフェースを作成
- ns1にて、ループバックおよびns1-veth0をUpし、ns1-veth0にIPアドレスアサイン
- ns2にて、ループバックおよびns2-veth0をUpし、ns2-veth0にIPアドレスアサイン

```shell
sudo ip netns exec ns1 ip l2tp add tunnel tunnel_id 1001 peer_tunnel_id 1002 \
     encap udp local 172.16.1.1 remote 172.16.1.2 udp_sport 1701 udp_dport 1701
sudo ip netns exec ns1 ip l2tp add session tunnel_id 1001 session_id 2001 peer_session_id 2002
sudo ip netns exec ns1 ip link set l2tpeth0 up
sudo ip netns exec ns1 ip addr add 10.1.1.1/24 dev l2tpeth0

sudo ip netns exec ns2 ip l2tp add tunnel tunnel_id 1002 peer_tunnel_id 1001 \
     encap udp local 172.16.1.2 remote 172.16.1.1 udp_sport 1701 udp_dport 1701
sudo ip netns exec ns2 ip l2tp add session tunnel_id 1002 session_id 2002 peer_session_id 2001
sudo ip netns exec ns2 ip link set l2tpeth0 up
sudo ip netns exec ns2 ip addr add 10.1.1.2/24 dev l2tpeth0
```

- ns1およびns2にて、ns1-veth0およびns2-veth0を端点として、UDPのL2TPトンネルを作成
    - トンネルID（自身および相手）およびトンネルIDにリンクしたセッションID（自身および相手）をアサイン
- L2TPトンネルインターフェースをUpし、IPアドレスアサイン

この設定で動作したが、このネットワーク構成は実際には用いられないので、検証は省略。

## ケース２
こちらのネットワーク構成が一般的かつ分かりやすい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/2da6ca7d-bd81-9a75-a70b-1905f1194014.png)

これをNamespaceにて実現すると、下記となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/13873f33-a4c4-6419-78fc-b5f00d9a3654.png)

### 設定
上記Namespaceの説明。

```shell:
sudo ip netns add ns1
sudo ip netns add ns2
sudo ip netns add ns3
sudo ip netns add ns4
```

- Namespace ns1、ns2、ns3、ns4作成

```shell
sudo ip link add name ns1-veth0 type veth peer name ns2-veth0
sudo ip link set ns1-veth0 netns ns1
sudo ip link set ns2-veth0 netns ns2
sudo ip netns exec ns1 ip link set lo up
sudo ip netns exec ns1 ip link set ns1-veth0 up
sudo ip netns exec ns1 ip addr add 172.16.1.1/24 dev ns1-veth0
sudo ip netns exec ns2 ip link set lo up
sudo ip netns exec ns2 ip link set ns2-veth0 up
sudo ip netns exec ns2 ip addr add 172.16.1.2/24 dev ns2-veth0
```

- 仮想ネットワークインターフェースPairであるns1-veth0およびns2-veth0作成
- ns1-veth0をns1へ、ns2-veth0をns2へ配置
- ns1にて、ループバックおよびns1-veth0をUpし、ns1-veth0にIPアドレスアサイン
- ns2にて、ループバックおよびns2-veth0をUpし、ns2-veth0にIPアドレスアサイン

```shell
sudo ip link add name ns1-veth type veth peer name ns3-veth
sudo ip link set ns1-veth netns ns1
sudo ip link set ns3-veth netns ns3
sudo ip netns exec ns1 ip link set ns1-veth up
sudo ip netns exec ns3 ip link set lo up
sudo ip netns exec ns3 ip link set ns3-veth up
sudo ip netns exec ns3 ip addr add 10.1.1.33/24 dev ns3-veth
```

- 仮想ネットワークインターフェースPairであるns1-vethおよびns3-veth作成
- ns1-vethをns1へ、ns3-vethをns3へ配置
- ns1にて、ns1-vethをUp
- ns3にて、ループバックおよびns3-vethをUpし、ns3-vethにIPアドレスアサイン

```shell
sudo ip link add name ns2-veth type veth peer name ns4-veth
sudo ip link set ns2-veth netns ns2
sudo ip link set ns4-veth netns ns4
sudo ip netns exec ns2 ip link set ns2-veth up
sudo ip netns exec ns4 ip link set lo up
sudo ip netns exec ns4 ip link set ns4-veth up
sudo ip netns exec ns4 ip addr add 10.1.1.44/24 dev ns4-veth
```

- 仮想ネットワークインターフェースPairであるns2-vethおよびns4-veth作成
- ns2-vethをns2へ、ns4-vethをns4へ配置
- ns2にて、ns2-vethをUp
- ns4にて、ループバックおよびns4-vethをUpし、ns4-vethにIPアドレスアサイン

```shell
sudo ip netns exec ns1 ip l2tp add tunnel tunnel_id 1001 peer_tunnel_id 1002 \
     encap udp local 172.16.1.1 remote 172.16.1.2 udp_sport 1701 udp_dport 1701
sudo ip netns exec ns1 ip l2tp add session tunnel_id 1001 session_id 2001 peer_session_id 2002
sudo ip netns exec ns1 ip link set l2tpeth0 up
```

- ns1にて、ns1-veth0およびns2-veth0を端点として、UDPのL2TPトンネルを作成
    - トンネルID（自身および相手）およびトンネルIDにリンクしたセッションID（自身および相手）をアサイン
    - L2TPトンネルインターフェースをUp

```shell
sudo ip netns exec ns2 ip l2tp add tunnel tunnel_id 1002 peer_tunnel_id 1001 \
     encap udp local 172.16.1.2 remote 172.16.1.1 udp_sport 1701 udp_dport 1701
sudo ip netns exec ns2 ip l2tp add session tunnel_id 1002 session_id 2002 peer_session_id 2001
sudo ip netns exec ns2 ip link set l2tpeth0 up
```

- ns2にて、同様にL2TPトンネルを作成

```shell
sudo ip netns exec ns1 ip link add name br1 type bridge
sudo ip netns exec ns1 ip link set br1 up
sudo ip netns exec ns1 ip link set l2tpeth0 master br1
sudo ip netns exec ns1 ip link set ns1-veth master br1
sudo ip netns exec ns1 ip addr add 10.1.1.1/24 dev br1
```

- ns1にて、ブリッジを作成し、Up
- ブリッジにL2TPインターフェースおよびns1-vethを追加
- ブリッジにIPアドレスアサイン

```shell
sudo ip netns exec ns2 ip link add name br2 type bridge
sudo ip netns exec ns2 ip link set br2 up
sudo ip netns exec ns2 ip link set l2tpeth0 master br2
sudo ip netns exec ns2 ip link set ns2-veth master br2
sudo ip netns exec ns2 ip addr add 10.1.1.2/24 dev br2
```

- ns2にて、同様のブリッジ設定

### 設定状況
上記の設定状況を下記（ns1）。まずは、ブリッジの状況。

```shell
$ sudo ip netns exec ns1 brctl show
bridge name	bridge id		STP enabled	interfaces
br1		8000.2e2024e48f88	no		l2tpeth0
									ns1-veth
```

L2TPトンネル。

```shell
$ sudo ip netns exec ns1 ip l2tp show tunnel
Tunnel 1001, encap UDP
  From 172.16.1.1 to 172.16.1.2
  Peer tunnel 1002
  UDP source / dest ports: 1701/1701
  UDP checksum: disabled

$ sudo ip netns exec ns1 ip l2tp show session
Session 2001 in tunnel 1001
  Peer session 2002, tunnel 1002
  interface name: l2tpeth0
  offset 0, peer offset 0
```

### 検証
同一ネットワークセグメントであるns3とns4との疎通（ping）。

```
$ sudo ip netns exec ns3 ping 10.1.1.44 -c 1
PING 10.1.1.44 (10.1.1.44) 56(84) bytes of data.
64 bytes from 10.1.1.44: icmp_seq=1 ttl=64 time=0.132 ms
```

このときのtcpdumpの状況。

```
$ sudo ip netns exec ns2 tcpdump -nel -i ns2-veth0

15:28:51.898009 d6:54:ae:b7:04:48 > 8e:3e:f5:de:56:f9, ethertype IPv4 (0x0800), length 152: 172.16.1.1.1701 > 172.16.1.2.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
15:28:51.898042 8e:3e:f5:de:56:f9 > d6:54:ae:b7:04:48, ethertype IPv4 (0x0800), length 152: 172.16.1.2.1701 > 172.16.1.1.1701:  Unknown Version, neither L2F(1) nor L2TP(2)
```

トンネルの外側（ns2-veth0）では、UDP1701の状況（L2TPパケット）が見える。

```
$ sudo ip netns exec ns2 tcpdump -nel -i l2tpeth0

15:29:19.506855 f2:4a:62:38:1e:ce > 82:31:be:e9:87:f1, ethertype IPv4 (0x0800), length 98: 10.1.1.33 > 10.1.1.44: ICMP echo request, id 2767, seq 1, length 64
15:29:19.506884 82:31:be:e9:87:f1 > f2:4a:62:38:1e:ce, ethertype IPv4 (0x0800), length 98: 10.1.1.44 > 10.1.1.33: ICMP echo reply, id 2767, seq 1, length 64
```

トンネルの内側（トンネルインターフェースl2tpeth0）では、ns3およびns4のIPアドレス（同一ネットワークセグメント）のICMPパケットが見える。

EOF