Carpe Diem

備忘録

Network NamespaceにBridge経由でアクセスする

概要

前回

christina04.hatenablog.com

でネットワーク名前空間の機能に触れてみました。
今回はブリッジを挟んでアクセスするネットワーク環境を構築してみます。

環境

ブリッジを挟んだネットワーク環境構築

ネットワーク名前空間を作成

ip netns addでネットワーク名前空間host1host2を作ります。

$ sudo ip netns add host1
$ sudo ip netns add host2
$ ip netns l
host2
host1

ループバックアドレスをUPしておきます。

$ sudo ip netns exec host1 ip link set lo up
$ sudo ip netns exec host2 ip link set lo up

図で表すと以下の状態です。

f:id:quoll00:20200126215142p:plain

vethの作成

次のように3つvethを作ります。

  • veth1 -- br-veth
  • host1 -- br-host1
  • host2 -- br-host2

分かりやすいようブリッジに繋げるピアにはbr-のprefixを付けています。

$ sudo ip link add name veth1 type veth peer name br-veth1
$ sudo ip link add name host1 type veth peer name br-host1
$ sudo ip link add name host2 type veth peer name br-host2

確認します。

$ ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:b7:1f:33:e9:24 brd ff:ff:ff:ff:ff:ff
3: br-veth1@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 82:be:07:ab:dc:2d brd ff:ff:ff:ff:ff:ff
4: veth1@br-veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether fa:00:4d:fc:fd:11 brd ff:ff:ff:ff:ff:ff
5: br-host1@host1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 4e:54:69:94:e2:81 brd ff:ff:ff:ff:ff:ff
6: host1@br-host1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 56:ec:40:cb:55:85 brd ff:ff:ff:ff:ff:ff
7: br-host2@host2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3e:ed:c3:1c:1d:ee brd ff:ff:ff:ff:ff:ff
8: host2@br-host2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 5e:1e:01:b5:02:58 brd ff:ff:ff:ff:ff:ff

図で表すと以下の状態です。

f:id:quoll00:20200126215600p:plain

vethのピアをネットワーク名前空間

$ sudo ip link set host1 netns host1
$ sudo ip link set host2 netns host2

vethhost1host2がネットワーク名前空間へセットされたのでホストLinuxから無くなりました。

$ ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:b7:1f:33:e9:24 brd ff:ff:ff:ff:ff:ff
3: br-veth1@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 82:be:07:ab:dc:2d brd ff:ff:ff:ff:ff:ff
4: veth1@br-veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether fa:00:4d:fc:fd:11 brd ff:ff:ff:ff:ff:ff
5: br-host1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 4e:54:69:94:e2:81 brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: br-host2@if8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3e:ed:c3:1c:1d:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1

図で表すと以下の状態です。

f:id:quoll00:20200126215804p:plain

Bridgeを作成する

ip link addでブリッジを作成します。

$ sudo ip link add br0 type bridge

br0が増えていることが確認できます。

$ ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:b7:1f:33:e9:24 brd ff:ff:ff:ff:ff:ff
3: br-veth1@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 82:be:07:ab:dc:2d brd ff:ff:ff:ff:ff:ff
4: veth1@br-veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether fa:00:4d:fc:fd:11 brd ff:ff:ff:ff:ff:ff
5: br-host1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 4e:54:69:94:e2:81 brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: br-host2@if8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3e:ed:c3:1c:1d:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1
9: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 32:8c:2e:f2:bb:77 brd ff:ff:ff:ff:ff:ff

図で表すと以下の状態です。

f:id:quoll00:20200126220044p:plain

Bridgeに各NICをセットする

$ sudo ip link set dev br-veth1 master br0
$ sudo ip link set dev br-host1 master br0
$ sudo ip link set dev br-host2 master br0

ブリッジにどのNICが結びついているか確認します。

$ ip link show master br0
3: br-veth1@veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master br0 state DOWN mode DEFAULT group default qlen 1000
    link/ether 82:be:07:ab:dc:2d brd ff:ff:ff:ff:ff:ff
5: br-host1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master br0 state DOWN mode DEFAULT group default qlen 1000
    link/ether 4e:54:69:94:e2:81 brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: br-host2@if8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master br0 state DOWN mode DEFAULT group default qlen 1000
    link/ether 3e:ed:c3:1c:1d:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1

bridgeコマンドでも確認できます。

$ bridge link show
3: br-veth1 state DOWN @veth1: <BROADCAST,MULTICAST> mtu 1500 master br0 state disabled priority 32 cost 2
5: br-host1 state DOWN @if6: <BROADCAST,MULTICAST> mtu 1500 master br0 state disabled priority 32 cost 2
7: br-host2 state DOWN @if8: <BROADCAST,MULTICAST> mtu 1500 master br0 state disabled priority 32 cost 2

図で表すと以下の状態です。

f:id:quoll00:20200126220315p:plain

IPアドレスを付与

サブネットを10.0.0.0/24として以下のように付与していきます。

veth IP
veth1 10.0.0.100
host1 10.0.0.1
host2 10.0.0.2
$ sudo ip addr add 10.0.0.100/24 dev veth1
$ sudo ip netns exec host1 ip addr add 10.0.0.1/24 dev host1
$ sudo ip netns exec host2 ip addr add 10.0.0.2/24 dev host2

図で表すと以下の状態です。

f:id:quoll00:20200126220716p:plain

NIC、BridgeをUP

NICをUP状態にします。

$ sudo ip netns exec host1 ip link set host1 up
$ sudo ip netns exec host2 ip link set host2 up
$ sudo ip link set veth1 up
$ sudo ip link set br-veth1 up
$ sudo ip link set br-host1 up
$ sudo ip link set br-host2 up

BridgeもUPします。

$ sudo ip link set br0 up

図で表すと以下の状態です。

f:id:quoll00:20200126220817p:plain

これで準備が全て整いました。

動作確認

ホストLinuxからhost1

ルーティングテーブルを確認すると10.0.0.0/24のサブネットはveth1を使うことが分かります。

vagrant@ubuntu-bionic:~$ netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.0.2.2        0.0.0.0         UG        0 0          0 enp0s3
10.0.0.0        0.0.0.0         255.255.255.0   U         0 0          0 veth1
10.0.2.0        0.0.0.0         255.255.255.0   U         0 0          0 enp0s3
10.0.2.2        0.0.0.0         255.255.255.255 UH        0 0          0 enp0s3
vagrant@ubuntu-bionic:~$ ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.071 ms

ホストLinuxからhost2

vagrant@ubuntu-bionic:~$ ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.044 ms

host1からホストLinux

host1に入っておきます。

vagrant@ubuntu-bionic:~$ sudo ip netns exec host1 bash
root@ubuntu-bionic:~# ping 10.0.0.100
PING 10.0.0.100 (10.0.0.100) 56(84) bytes of data.
64 bytes from 10.0.0.100: icmp_seq=1 ttl=64 time=0.019 ms

host1からhost2

root@ubuntu-bionic:~# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.038 ms

host2からホストLinux

host2に入っておきます。

vagrant@ubuntu-bionic:~$ sudo ip netns exec host2 bash
root@ubuntu-bionic:~# ping 10.0.0.100
PING 10.0.0.100 (10.0.0.100) 56(84) bytes of data.
64 bytes from 10.0.0.100: icmp_seq=1 ttl=64 time=0.036 ms

host2からhost1

root@ubuntu-bionic:~# ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.039 ms

まとめ

ネットワーク名前空間へブリッジ経由でアクセスすることができました。
今回のブリッジはdockerでいうとdocker0と同じ役割をしています。

次回はiptablesによるNATを構築してネットワーク名前空間から外部ネットワークにアクセスできるようにします。

ソース