Segmentation Faultぐ

Segmentation Fault

コアダンプの数だけ強くなれるよ。

Linuxのnamespaceでネットワークを区切って遊ぶ

Linuxのnamaspace(名前空間)で遊んでみます。

Dockerとかコンテナを実現する技術で使われるアレですね。

お遊び内容



まず、下図のネットワーク構成を作ります。

f:id:segmentation-fault:20180121153248p:plain


・eth1,eth2は内部ネットワーク
・vlan100,vlan200はVLANタグ付きのインタフェース
・veth1, veth2はnamespace間をつなぐインタフェース
・br1,br2はブリッジ



VLAN単位でネットワークを区切って通信ができるのか確認してみます。
ルーター、L3スイッチのVRFみたいなものですね。

vlan100,vlan200はネットワークが違うのでIPアドレスが同じでも各々で通信が可能なはずです。


各種設定


まず、VM1,VM2を作成します。(ここではともにCentOS 7です)

内部ネットワークのインタフェースはプロミスキャスモードをすべて許可にしてから起動します。
(許可しないとnamespace側のMACアドレスが宛先MACになっているフレームを破棄してしまうため)

f:id:segmentation-fault:20180121154012p:plain


以下、各VMの設定です。

◆VM1

内部ネットワークのインタフェース名を構成図のeth1に合わせます。

[user@localhost ~]$ ip link show dev enp0s9
4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 08:00:27:1d:b8:43 brd ff:ff:ff:ff:ff:ff

[user@localhost ~]$ sudo ip link set dev enp0s9 down
[user@localhost ~]$ sudo ip link set dev enp0s9 name eth1
[user@localhost ~]$ sudo ip link set dev eth1 up

[user@localhost ~]$ ip link show dev eth1
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 08:00:27:1d:b8:43 brd ff:ff:ff:ff:ff:


続いてnamespace, 各インタフェースを作成します。

namespaceはip netns add 作ります。
namespace上でコマンドを実行する場合はip netns exec "namespace" "実行したいcommand" となります。

[user@vm1 ~]$ # namespaceの作成
[user@vm1 ~]$ sudo ip netns add ns1                                                      # namespaceの作成
[user@vm1 ~]$ sudo ip link add veth1 type veth peer name eth1 netns ns1                  # namespace間インタフェースの作成

[user@vm1 ~]$ # ブリッジの作成
[user@vm1 ~]$ sudo brctl addbr br1                                                       # ブリッジの作成
[user@vm1 ~]$ sudo brctl addif br1 veth1                                                 # ブリッジにveth1を接続
[user@vm1 ~]$ sudo brctl addif br1 eth1                                                  # ブリッジにeth1を接続

[user@vm1 ~]$ # VLANの作成
[user@vm1 ~]$ sudo ip netns exec ns1 ip link add link eth1 name vlan100 type vlan id 100 # vlan100の作成
[user@vm1 ~]$ sudo ip netns exec ns1 ip addr add 192.168.0.1/24 dev vlan100              # vlan100にIPアドレス設定
[user@vm1 ~]$ sudo ip link add link eth1 name vlan200 type vlan id 200                   # vlan200の作成
[user@vm1 ~]$ sudo ip addr add 192.168.0.1/24 dev vlan200                                # vlan200にIPアドレス設定

[user@vm1 ~]$ # インタフェースのUP
[user@vm1 ~]$ sudo ip link set dev veth1 up                                              # veth1のUP
[user@vm1 ~]$ sudo ip link set dev eth1 up                                               # eth1のUP
[user@vm1 ~]$ sudo ip link set dev br1 up                                                # br1のUP
[user@vm1 ~]$ sudo ip netns exec ns1 ip link set dev eth1 up                             # ns1のeth1をUP
[user@vm1 ~]$ sudo ip netns exec ns1 ip link set dev vlan100 up                          # vlan100のUP
[user@vm1 ~]$ sudo ip link set dev vlan200 up                                            # vlan200のUP


namespaceと各インタフェースが作成されていることを確認します。

[user@vm1 ~]$ ip netns list
ns1
[user@vm1 ~]$
[user@vm1 ~]$ ip addr show
...
       valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br1 state UP qlen 1000
    link/ether 08:00:27:1d:b8:43 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::bac:439:3aa7:6261/64 scope link
       valid_lft forever preferred_lft forever
6: veth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br1 state UP qlen 1000
    link/ether 3a:f0:e6:57:6b:16 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::38f0:e6ff:fe57:6b16/64 scope link
       valid_lft forever preferred_lft forever
7: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 08:00:27:1d:b8:43 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a00:27ff:fe1d:b843/64 scope link
       valid_lft forever preferred_lft forever
8: vlan200@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 08:00:27:1d:b8:43 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.1/32 scope global vlan200
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe1d:b843/64 scope link
       valid_lft forever preferred_lft forever

[user@vm1 ~]$ sudo ip netns exec ns1 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth1@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT qlen 1000
    link/ether 26:5a:84:c9:33:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
3: vlan100@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT qlen 1000
    link/ether 26:5a:84:c9:33:03 brd ff:ff:ff:ff:ff:ff


◆VM2

VM2もVM1と同じように設定します。

[user@vm2 ~]$ # namespaceの作成
[user@vm2 ~]$ sudo ip netns add ns2                                                      # namespaceの作成
[user@vm2 ~]$ sudo ip link add veth2 type veth peer name eth2 netns ns2                  # namespace間インタフェースの作成

[user@vm2 ~]$ # ブリッジの作成
[user@vm2 ~]$ sudo brctl addbr br2                                                       # ブリッジの作成
[user@vm2 ~]$ sudo brctl addif br2 veth2                                                 # ブリッジにveth2を接続
[user@vm2 ~]$ sudo brctl addif br2 eth2                                                  # ブリッジにeth2を接続

[user@vm2 ~]$ # VLANの作成
[user@vm2 ~]$ sudo ip netns exec ns2 ip link add link eth2 name vlan100 type vlan id 100 # vlan100の作成
[user@vm2 ~]$ sudo ip netns exec ns2 ip addr add 192.168.0.2/24 dev vlan100              # vlan100にIPアドレス設定
[user@vm2 ~]$ sudo ip link add link eth2 name vlan200 type vlan id 200                   # vlan200の作成
[user@vm2 ~]$ sudo ip addr add 192.168.0.2/24 dev vlan200                                # vlan200にIPアドレス設定

[user@vm2 ~]$ # インタフェースのUP
[user@vm2 ~]$ sudo ip link set dev veth2 up                                              # veth2のUP
[user@vm2 ~]$ sudo ip link set dev eth2 up                                               # eth2のUP
[user@vm2 ~]$ sudo ip link set dev br2 up                                                # br2のUP
[user@vm2 ~]$ sudo ip netns exec ns2 ip link set dev eth2 up                             # ns2のeth2をUP
[user@vm2 ~]$ sudo ip netns exec ns2 ip link set dev vlan100 up                          # vlan100のUP
[user@vm2 ~]$ sudo ip link set dev vlan200 up                                            # vlan200のUP


疎通確認


vlan200の通信確認

[user@vm1 ~]$ ping 192.168.0.2
[user@vm2 ~]$ sudo tcpdump -i vlan200


f:id:segmentation-fault:20180121154730p:plain



vlan100の通信確認

[user@vm1 ~]$ sudo ip netns exec ns1 ping 192.168.0.2
[user@vm2 ~]$ sudo ip netns exec ns2 tcpdump -i vlan100


f:id:segmentation-fault:20180121154753p:plain



期待通り通信ができることを確認できました。


参考


Technology: VRF & Linux Network Name Space

Linux Network Namespace で遊んでみる | CUBE SUGAR STORAGE

namespace を使ってみる - いますぐ実践! Linuxシステム管理 / Vol.260