Open8

ネットワーク勉強の続き - 1: VLAN/VXLANを試すなど

bells17bells17

VXLANの勉強

参考(参考というよりほぼそのまま試すだけ):

https://blog.amedama.jp/entry/2020/02/08/012513

作るもの

marmaid.jsがいい感じに描画してくれなくてみずらい
IPアドレスだけ参考記事から入れ替えを行ってるので注意

VXLAN以外の構成を先に作る

# NSを作成
$ ip netns add ns1
$ ip netns add router
$ ip netns add ns2

# 仮想ネットワークインターフェイスを追加
$ ip link add ns1-veth0 type veth peer name gw-veth0
$ ip link add ns2-veth0 type veth peer name gw-veth1

# 仮想ネットワークインターフェイスをNetwork Namespaceで使えるようにする
$ ip link set ns1-veth0 netns ns1
$ ip link set gw-veth0 netns router
$ ip link set gw-veth1 netns router
$ ip link set ns2-veth0 netns router

# ネットワークインターフェイスをUP状態にして、利用可能にする
$ ip netns exec ns1 ip link set ns1-veth0 up
$ ip netns exec router ip link set gw-veth0 up
$ ip netns exec router ip link set gw-veth1 up
$ ip netns exec ns2 ip link set ns2-veth0 up

# Routerのアドレスなどを設定
$ ip netns exec router ip addr add 192.0.2.254/24 dev gw-veth0
$ ip netns exec router ip addr add 203.0.113.254/24 dev gw-veth1
$ ip netns exec router sysctl net.ipv4.ip_forward=1

# ns1のアドレスなどを設定
$ ip netns exec ns1 ip addr add 192.0.2.1/24 dev ns1-veth0
$ ip netns exec ns1 ip route add default via 192.0.2.254

# ns2のアドレスなどを設定
$ ip netns exec ns2 ip addr add 203.0.113.1/24 dev ns2-veth0
$ ip netns exec ns2 ip route add default via 203.0.113.254

VXLAN構成

# VXLANインターフェイスを作成
$ ip netns exec ns1 \
  ip link add ns1-vxlan0 \
  type vxlan \
  id 100 \
  remote 203.0.113.1 \
  dstport 4789 \
  dev ns1-veth0

$ ip netns exec ns2 \
  ip link add ns2-vxlan0 \
  type vxlan \
  id 100 \
  remote 192.0.2.1 \
  dstport 4789 \
  dev ns2-veth0

# ネットワークインターフェイスをUP状態にしてIPアドレスを付与
$ sudo ip netns exec ns1 ip link set ns1-vxlan0 up
$ sudo ip netns exec ns1 ip address add 198.51.100.1/24 dev ns1-vxlan0
$ sudo ip netns exec ns2 ip link set ns2-vxlan0 up
$ sudo ip netns exec ns2 ip address add 198.51.100.2/24 dev ns2-vxlan0

動作確認

まずはvxlanのインターフェイス同士でpingが通るか確認

$ ip netns exec ns1 ping -c 3 198.51.100.2 -I 198.51.100.1
PING 198.51.100.2 (198.51.100.2) from 198.51.100.1 : 56(84) bytes of data.
64 bytes from 198.51.100.2: icmp_seq=1 ttl=64 time=0.075 ms
64 bytes from 198.51.100.2: icmp_seq=2 ttl=64 time=0.037 ms
64 bytes from 198.51.100.2: icmp_seq=3 ttl=64 time=0.048 ms

--- 198.51.100.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2041ms
rtt min/avg/max/mdev = 0.037/0.053/0.075/0.017 ms

次にtcpdumpで確認

別ターミナルでns2-veth0に対してtcpdumpを実行

$ ip netns exec ns2 tcpdump -tnl -i ns2-veth0

別ターミナルでns2-vxlan0に対してtcpdumpを実行

$ ip netns exec ns2 tcpdump -tnl -i ns2-vxlan0

pingを実行

$ ip netns exec ns1 ping -c 3 198.51.100.2 -I 198.51.100.1
PING 198.51.100.2 (198.51.100.2) from 198.51.100.1 : 56(84) bytes of data.
64 bytes from 198.51.100.2: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 198.51.100.2: icmp_seq=2 ttl=64 time=0.063 ms
64 bytes from 198.51.100.2: icmp_seq=3 ttl=64 time=0.063 ms

--- 198.51.100.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2049ms
rtt min/avg/max/mdev = 0.063/0.063/0.065/0.009 ms

tcpdumpの出力結果

ns2-veth0

$ ip netns exec ns2 tcpdump -tnl -i ns2-veth0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ns2-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
IP 192.0.2.1.42296 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP6 fe80::c469:7dff:fe30:7130 > ff02::2: ICMP6, router solicitation, length 16
ARP, Request who-has 203.0.113.1 tell 203.0.113.254, length 28
ARP, Reply 203.0.113.1 is-at ae:8c:fb:3b:df:7b, length 28
IP 192.0.2.1.45577 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1 > 198.51.100.2: ICMP echo request, id 13907, seq 1, length 64
IP 203.0.113.1.45577 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.2 > 198.51.100.1: ICMP echo reply, id 13907, seq 1, length 64
IP 192.0.2.1.45577 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1 > 198.51.100.2: ICMP echo request, id 13907, seq 2, length 64
IP 203.0.113.1.45577 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.2 > 198.51.100.1: ICMP echo reply, id 13907, seq 2, length 64
IP 192.0.2.1.45577 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1 > 198.51.100.2: ICMP echo request, id 13907, seq 3, length 64
IP 203.0.113.1.45577 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.2 > 198.51.100.1: ICMP echo reply, id 13907, seq 3, length 64
ARP, Request who-has 203.0.113.254 tell 203.0.113.1, length 28
IP 203.0.113.1.49442 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Request who-has 198.51.100.1 tell 198.51.100.2, length 28
ARP, Reply 203.0.113.254 is-at be:17:4e:31:a5:d6, length 28
IP 192.0.2.1.49442 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Request who-has 198.51.100.2 tell 198.51.100.1, length 28
IP 203.0.113.1.49442 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Reply 198.51.100.2 is-at 9a:dc:d9:35:e3:fa, length 28
IP 192.0.2.1.49442 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Reply 198.51.100.1 is-at c6:69:7d:30:71:30, length 28
IP 203.0.113.1.49096 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP6 fe80::98dc:d9ff:fe35:e3fa > ff02::2: ICMP6, router solicitation, length 16

ns2-vxlan0

$ ip netns exec ns2 tcpdump -tnl -i ns2-vxlan0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ns2-vxlan0, link-type EN10MB (Ethernet), capture size 262144 bytes
IP 198.51.100.1 > 198.51.100.2: ICMP echo request, id 13907, seq 1, length 64
IP 198.51.100.2 > 198.51.100.1: ICMP echo reply, id 13907, seq 1, length 64
IP 198.51.100.1 > 198.51.100.2: ICMP echo request, id 13907, seq 2, length 64
IP 198.51.100.2 > 198.51.100.1: ICMP echo reply, id 13907, seq 2, length 64
IP 198.51.100.1 > 198.51.100.2: ICMP echo request, id 13907, seq 3, length 64
IP 198.51.100.2 > 198.51.100.1: ICMP echo reply, id 13907, seq 3, length 64
ARP, Request who-has 198.51.100.1 tell 198.51.100.2, length 28
ARP, Request who-has 198.51.100.2 tell 198.51.100.1, length 28
ARP, Reply 198.51.100.2 is-at 9a:dc:d9:35:e3:fa, length 28
ARP, Reply 198.51.100.1 is-at c6:69:7d:30:71:30, length 28
IP6 fe80::98dc:d9ff:fe35:e3fa > ff02::2: ICMP6, router solicitation, length 16

メモ

  • ns2-vxlan0 のtcpdumpをみると 198.51.100.1198.51.100.2 の通信だけが行われているのが確認できる
  • ns2-veth0 の tcpdumoでも198.51.100.1198.51.100.2 の通信が見れるのが確認できる
  • IP 192.0.2.1.45577 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100 のように 192.0.2.1.45577 となっていて、45577はポートとかそういうもの?
  • これの後に IP 198.51.100.1 > 198.51.100.2: ICMP echo request, id 13907, seq 1, length 64 とnx<x>-vxlan0への通信が行われているので、上記のはカプセル化を行っているという理解で良い?

ncで確認

ターミナル1でncでサーバーを立てる

$ ip netns exec ns2 nc -lnv 54321
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::54321
Ncat: Listening on 0.0.0.0:54321
Ncat: Connection from 198.51.100.1.
Ncat: Connection from 198.51.100.1:52372.
Hello World!

ターミナル2でncで通信する

$ ip netns exec ns1 nc 198.51.100.2 54321
Hello World!
^C

ターミナル3でns1-veth0をtcpdump

$ ip netns exec ns2 tcpdump -tnl -i ns2-veth0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ns2-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
ARP, Request who-has 203.0.113.1 tell 203.0.113.254, length 28
ARP, Reply 203.0.113.1 is-at ae:8c:fb:3b:df:7b, length 28
IP 192.0.2.1.49442 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Request who-has 198.51.100.2 tell 198.51.100.1, length 28
IP 203.0.113.1.49442 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Reply 198.51.100.2 is-at 9a:dc:d9:35:e3:fa, length 28
IP 192.0.2.1.36127 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [S], seq 1274390200, win 28200, options [mss 1410,sackOK,TS val 3503355312 ecr 0,nop,wscale 7], length 0
IP 203.0.113.1.60086 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.2.54321 > 198.51.100.1.52372: Flags [S.], seq 3947230463, ack 1274390201, win 27960, options [mss 1410,sackOK,TS val 3795849301 ecr 3503355312,nop,wscale 7], length 0
IP 192.0.2.1.36127 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [.], ack 1, win 221, options [nop,nop,TS val 3503355312 ecr 3795849301], length 0
ARP, Request who-has 203.0.113.254 tell 203.0.113.1, length 28
IP 203.0.113.1.49442 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Request who-has 198.51.100.1 tell 198.51.100.2, length 28
ARP, Reply 203.0.113.254 is-at be:17:4e:31:a5:d6, length 28
IP 192.0.2.1.49442 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
ARP, Reply 198.51.100.1 is-at c6:69:7d:30:71:30, length 28
IP 192.0.2.1.36127 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [P.], seq 1:14, ack 1, win 221, options [nop,nop,TS val 3503361054 ecr 3795849301], length 13
IP 203.0.113.1.60086 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.2.54321 > 198.51.100.1.52372: Flags [.], ack 14, win 219, options [nop,nop,TS val 3795855044 ecr 3503361054], length 0
IP 192.0.2.1.36127 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [F.], seq 14, ack 1, win 221, options [nop,nop,TS val 3503363519 ecr 3795855044], length 0
IP 203.0.113.1.60086 > 192.0.2.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.2.54321 > 198.51.100.1.52372: Flags [F.], seq 1, ack 15, win 219, options [nop,nop,TS val 3795857508 ecr 3503363519], length 0
IP 192.0.2.1.36127 > 203.0.113.1.vxlan: VXLAN, flags [I] (0x08), vni 100
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [.], ack 2, win 221, options [nop,nop,TS val 3503363519 ecr 3795857508], length 0
^C
16 packets captured
16 packets received by filter
0 packets dropped by kernel

ターミナル4でns1-vxlan0をtcpdump

$ ip netns exec ns2 tcpdump -tnl -i ns2-vxlan0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ns2-vxlan0, link-type EN10MB (Ethernet), capture size 262144 bytes
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [S], seq 1274390200, win 28200, options [mss 1410,sackOK,TS val 3503355312 ecr 0,nop,wscale 7], length 0
IP 198.51.100.2.54321 > 198.51.100.1.52372: Flags [S.], seq 3947230463, ack 1274390201, win 27960, options [mss 1410,sackOK,TS val 3795849301 ecr 3503355312,nop,wscale 7], length 0
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [.], ack 1, win 221, options [nop,nop,TS val 3503355312 ecr 3795849301], length 0
ARP, Request who-has 198.51.100.1 tell 198.51.100.2, length 28
ARP, Reply 198.51.100.1 is-at c6:69:7d:30:71:30, length 28
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [P.], seq 1:14, ack 1, win 221, options [nop,nop,TS val 3503361054 ecr 3795849301], length 13
IP 198.51.100.2.54321 > 198.51.100.1.52372: Flags [.], ack 14, win 219, options [nop,nop,TS val 3795855044 ecr 3503361054], length 0
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [F.], seq 14, ack 1, win 221, options [nop,nop,TS val 3503363519 ecr 3795855044], length 0
IP 198.51.100.2.54321 > 198.51.100.1.52372: Flags [F.], seq 1, ack 15, win 219, options [nop,nop,TS val 3795857508 ecr 3503363519], length 0
IP 198.51.100.1.52372 > 198.51.100.2.54321: Flags [.], ack 2, win 221, options [nop,nop,TS val 3503363519 ecr 3795857508], length 0
^C
10 packets captured
10 packets received by filter
0 packets dropped by kernel

その他

以下のコマンドでvxlanの設定を確認する

$ ip netns exec ns1 ip -d addr show ns1-vxlan0
2: ns1-vxlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether c6:69:7d:30:71:30 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535
    vxlan id 100 remote 203.0.113.1 dev ns1-veth0 srcport 0 0 dstport 4789 ttl auto ageing 300 udpcsum noudp6zerocsumtx noudp6zerocsumrx numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet 198.51.100.1/24 scope global ns1-vxlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::c469:7dff:fe30:7130/64 scope link
       valid_lft forever preferred_lft forever

クリーンアップ

$ ip netns delete ns1
$ ip netns delete ns2
$ ip netns delete router

VXLANについて

https://blogs.vmware.com/vmware-japan/2015/04/nwv02.html

VMWare固有の話が多くてあんまりよくわからなかった

  • VTEP(VXLAN Tunnel Endpoint): 端末の送信したフレームをカプセル化(VXLAN ヘッダを付加すること)するポイント
  • ネットワーク仮想化環境では論理スイッチのVNI(VXLAN Network Identifier物理環境のVLAN IDに相当) とあるのでVNI(VXLAN Network Identifier)はvlanのIDと同様という理解で良い?
  • VTEP テーブル:VNI(VXLAN Network Identifier)とVTEP を対応させたテーブル
    MAC テーブル :VNI、VTEP、仮想マシンのMAC アドレスを対応させたテーブル
    ARP テーブル :仮想マシンのIP アドレスとMAC アドレスを対応させたテーブル

https://www.janog.gr.jp/meeting/janog37/program/vxlan

https://www.janog.gr.jp/meeting/janog37/download_file/vxlan.pdf

難してよくわからんかった

RFC7348

https://tex2e.github.io/rfc-translater/html/rfc7348.html

bells17bells17

VLANの勉強

↓をbridgeもnamespaceにしてやってみてる
https://blog.amedama.jp/entry/linux-bridge-8021q-vlan

作る環境

環境構築

# NSを作成
$ ip netns add ns1
$ ip netns add ns2
$ ip netns add bridge

# 仮想ネットワークインターフェイスを追加
$ ip link add ns1-veth0 type veth peer name br0-veth0
$ ip link add ns2-veth0 type veth peer name br0-veth1

# 仮想ネットワークインターフェイスをNetwork Namespaceで使えるようにする
$ ip link set ns1-veth0 netns ns1
$ ip link set ns2-veth0 netns ns2
$ ip link set br0-veth0 netns bridge
$ ip link set br0-veth1 netns bridge

# ネットワークインターフェイスをUP状態にして、利用可能にする
$ ip netns exec ns1 ip link set ns1-veth0 up
$ ip netns exec ns2 ip link set ns2-veth0 up
$ ip netns exec bridge ip link set br0-veth0 up
$ ip netns exec bridge ip link set br0-veth1 up

# IP使って通信可能にするためにIPアドレスを付与
$ ip netns exec ns1 ip addr add 192.0.2.1/24 dev ns1-veth0
$ ip netns exec ns2 ip addr add 192.0.2.2/24 dev ns2-veth0

# ネットワークブリッジを作成してUP状態にする
$ ip netns exec bridge ip link add dev br0 type bridge vlan_filtering 1
$ ip netns exec bridge ip link set br0 up

# vethをネットワークブリッジに追加
$ ip netns exec bridge ip link set br0-veth0 master br0
$ ip netns exec bridge ip link set br0-veth1 master br0

# 追加したらUP状態にする
$ ip netns exec bridge ip link set br0-veth0 up
$ ip netns exec bridge ip link set br0-veth1 up

# br0-veth0/1をVLAN ID 100に追加して
$ ip netns exec bridge bridge vlan add vid 100 dev br0-veth0 pvid untagged
$ ip netns exec bridge bridge vlan add vid 100 dev br0-veth1 pvid untagged

# br0-veth0/1をVLAN ID 1(デフォルト)から削除する
$ ip netns exec bridge bridge vlan del dev br0-veth0 vid 1
$ ip netns exec bridge bridge vlan del dev br0-veth1 vid 1

動作確認

ping

$ ip netns exec ns1 ping -c 3 192.0.2.2
PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.
64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.062 ms
64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.048 ms

--- 192.0.2.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2083ms
rtt min/avg/max/mdev = 0.046/0.052/0.062/0.007 ms

tcpdump

$ ip netns exec bridge tcpdump -nel -i br0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
16:38:52.556858 9a:1e:01:62:dc:2b > 33:33:00:00:00:02, ethertype 802.1Q (0x8100), length 74: vlan 100, p 0, ethertype IPv6, fe80::981e:1ff:fe62:dc2b > ff02::2: ICMP6, router solicitation, length 16
16:38:54.569445 26:7f:61:52:da:5b > Broadcast, ethertype 802.1Q (0x8100), length 46: vlan 100, p 0, ethertype ARP, Request who-has 192.0.2.2 tell 192.0.2.1, length 28
16:38:54.569462 9a:1e:01:62:dc:2b > 26:7f:61:52:da:5b, ethertype 802.1Q (0x8100), length 46: vlan 100, p 0, ethertype ARP, Reply 192.0.2.2 is-at 9a:1e:01:62:dc:2b, length 28
16:38:54.569466 26:7f:61:52:da:5b > 9a:1e:01:62:dc:2b, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.1 > 192.0.2.2: ICMP echo request, id 14179, seq 1, length 64
16:38:54.569473 9a:1e:01:62:dc:2b > 26:7f:61:52:da:5b, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 14179, seq 1, length 64
16:38:55.628806 26:7f:61:52:da:5b > 9a:1e:01:62:dc:2b, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.1 > 192.0.2.2: ICMP echo request, id 14179, seq 2, length 64
16:38:55.628832 9a:1e:01:62:dc:2b > 26:7f:61:52:da:5b, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 14179, seq 2, length 64
16:38:56.652813 26:7f:61:52:da:5b > 9a:1e:01:62:dc:2b, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.1 > 192.0.2.2: ICMP echo request, id 14179, seq 3, length 64
16:38:56.652841 9a:1e:01:62:dc:2b > 26:7f:61:52:da:5b, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 14179, seq 3, length 64
16:38:59.724792 9a:1e:01:62:dc:2b > 26:7f:61:52:da:5b, ethertype 802.1Q (0x8100), length 46: vlan 100, p 0, ethertype ARP, Request who-has 192.0.2.1 tell 192.0.2.2, length 28
16:38:59.724807 26:7f:61:52:da:5b > 9a:1e:01:62:dc:2b, ethertype 802.1Q (0x8100), length 46: vlan 100, p 0, ethertype ARP, Reply 192.0.2.1 is-at 26:7f:61:52:da:5b, length 28

参考記事の通り vlan 100 となっているのがわかる

クリーンアップ

$ ip netns delete ns1
$ ip netns delete ns2
$ ip netns delete bridge

参考

802.1Qの仕様そのもののドキュメントがどこにあるのかよくわからなかった

https://ja.wikipedia.org/wiki/IEEE_802.1Q

ポートVLANというのは物理ポートにVLAN IDがついてるものみたいなやつっぽいので、Linuxだと検証難しい?

https://xtech.nikkei.com/atcl/nxt/column/18/00131/020600002/

bells17bells17

VLANの勉強

上記の例に加えてVLAN IDを複数作ってみる
タグVLANによるセグメンテーション?が行われてるかの検証をする

作る環境

環境構築

# NSを作成
$ ip netns add ns1
$ ip netns add ns2
$ ip netns add ns3
$ ip netns add ns4
$ ip netns add bridge

# 仮想ネットワークインターフェイスを追加
$ ip link add ns1-veth0 type veth peer name br0-veth0
$ ip link add ns2-veth0 type veth peer name br0-veth1
$ ip link add ns3-veth0 type veth peer name br0-veth2
$ ip link add ns4-veth0 type veth peer name br0-veth3

# 仮想ネットワークインターフェイスをNetwork Namespaceで使えるようにする
$ ip link set ns1-veth0 netns ns1
$ ip link set ns2-veth0 netns ns2
$ ip link set ns3-veth0 netns ns3
$ ip link set ns4-veth0 netns ns4
$ ip link set br0-veth0 netns bridge
$ ip link set br0-veth1 netns bridge
$ ip link set br0-veth2 netns bridge
$ ip link set br0-veth3 netns bridge

# ネットワークインターフェイスをUP状態にして、利用可能にする
$ ip netns exec ns1 ip link set ns1-veth0 up
$ ip netns exec ns2 ip link set ns2-veth0 up
$ ip netns exec ns3 ip link set ns3-veth0 up
$ ip netns exec ns4 ip link set ns4-veth0 up
$ ip netns exec bridge ip link set br0-veth0 up
$ ip netns exec bridge ip link set br0-veth1 up
$ ip netns exec bridge ip link set br0-veth2 up
$ ip netns exec bridge ip link set br0-veth3 up

# IP使って通信可能にするためにIPアドレスを付与
$ ip netns exec ns1 ip addr add 192.0.2.1/24 dev ns1-veth0
$ ip netns exec ns2 ip addr add 192.0.2.2/24 dev ns2-veth0
$ ip netns exec ns3 ip addr add 192.0.2.3/24 dev ns3-veth0
$ ip netns exec ns4 ip addr add 192.0.2.4/24 dev ns4-veth0

# ネットワークブリッジを作成してUP状態にする
$ ip netns exec bridge ip link add dev br0 type bridge vlan_filtering 1
$ ip netns exec bridge ip link set br0 up

# vethをネットワークブリッジに追加
$ ip netns exec bridge ip link set br0-veth0 master br0
$ ip netns exec bridge ip link set br0-veth1 master br0
$ ip netns exec bridge ip link set br0-veth2 master br0
$ ip netns exec bridge ip link set br0-veth3 master br0

# 追加したらUP状態にする
$ ip netns exec bridge ip link set br0-veth0 up
$ ip netns exec bridge ip link set br0-veth1 up
$ ip netns exec bridge ip link set br0-veth2 up
$ ip netns exec bridge ip link set br0-veth3 up

# br0-veth0/1をVLAN ID 100に追加して
$ ip netns exec bridge bridge vlan add vid 100 dev br0-veth0 pvid untagged
$ ip netns exec bridge bridge vlan add vid 100 dev br0-veth1 pvid untagged

# br0-veth0/1をVLAN ID 1(デフォルト)から削除する
$ ip netns exec bridge bridge vlan del dev br0-veth0 vid 1
$ ip netns exec bridge bridge vlan del dev br0-veth1 vid 1

# br0-veth2/3をVLAN ID 200に追加して
$ ip netns exec bridge bridge vlan add vid 100 dev br0-veth0 pvid untagged
$ ip netns exec bridge bridge vlan add vid 100 dev br0-veth1 pvid untagged

# br0-veth2/3をVLAN ID 1(デフォルト)から削除する
$ ip netns exec bridge bridge vlan del dev br0-veth0 vid 1
$ ip netns exec bridge bridge vlan del dev br0-veth1 vid 1

動作確認

想定どおり

  • VLAND ID100に所属するns1(192.0.2.1)からは同じVLAN ID 100に属するns2(192.0.2.2)には通信ができた
  • VLAND ID100に所属するns1(192.0.2.1)からは別のVLAN ID 200に属するns3(192.0.2.3)には通信ができなかった
  • VLAND ID200に所属するns4(192.0.2.4)からは同じVLAN ID 200に属するns3(192.0.2.3)には通信ができた
$ ip netns exec ns1 ping -c 3 192.0.2.2
PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.
64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.034 ms

--- 192.0.2.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2050ms
rtt min/avg/max/mdev = 0.034/0.046/0.069/0.017 ms

$ ip netns exec ns1 ping -c 3 192.0.2.3
PING 192.0.2.3 (192.0.2.3) 56(84) bytes of data.

--- 192.0.2.3 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2046ms

$ ip netns exec ns4 ping -c 3 192.0.2.3
PING 192.0.2.3 (192.0.2.3) 56(84) bytes of data.
64 bytes from 192.0.2.3: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 192.0.2.3: icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from 192.0.2.3: icmp_seq=3 ttl=64 time=0.033 ms

--- 192.0.2.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2071ms
rtt min/avg/max/mdev = 0.033/0.039/0.048/0.006 ms

クリーンアップ

$ ip netns delete ns1
$ ip netns delete ns2
$ ip netns delete ns3
$ ip netns delete ns4
$ ip netns delete bridge
bells17bells17

Network Namespaceからインターネットに接続する

参考:

https://blog.kamijin-fanta.info/2018/12/netns/

構成

前提

8.8.8.8にpingできることを持ってインターネットに接続できてるかを確認するので、事前にホスト側からpingが通ることを確認しておく

$ ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=119 time=3.86 ms

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

環境構築

# NSを作成
$ ip netns add ns1

# 仮想ネットワークインターフェイスを追加
$ ip link add ns1-veth0 type veth peer name veth0

# 仮想ネットワークインターフェイスをNetwork Namespaceで使えるようにする
$ ip link set ns1-veth0 netns ns1

# ネットワークインターフェイスをUP状態にして、利用可能にする
$ ip netns exec ns1 ip link set ns1-veth0 up
$ ip link set veth0 up

# IPアドレスを設定
$ ip netns exec ns1 ip addr add 192.0.2.1/24 dev ns1-veth0
$ ip addr add 192.0.2.254/24 dev veth0

# デフォルトゲートウェイを設定
$ ip netns exec ns1 ip route add default via 192.0.2.254

# NATを設定
$ iptables -t nat \
  -A POSTROUTING \
  -s 192.0.2.0/24 \
  -j MASQUERADE

# hostをIPv4ルーター化
$ sysctl net.ipv4.ip_forward=1

動作確認

$ ip netns exec ns1 ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=3.95 ms

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

クリーンアップ

$ ip netns delete ns1
$ iptables --table nat --flush
$ sysctl net.ipv4.ip_forward=0
bells17bells17

ルーターを挟んでNetwork Namespaceからインターネットに接続する

そういえば書籍の内容では作成したNamespaceから外部インターネットへのアクセスなどは行ってなかった気がするのでやってみる

構成

環境構築

# NSを作成
$ ip netns add ns1
$ ip netns add router

# 仮想ネットワークインターフェイスを追加
$ ip link add ns1-veth0 type veth peer name gw-veth0
$ ip link add gw-veth1 type veth peer name veth0

# 仮想ネットワークインターフェイスをNetwork Namespaceで使えるようにする
$ ip link set ns1-veth0 netns ns1
$ ip link set gw-veth0 netns router
$ ip link set gw-veth1 netns router

# ネットワークインターフェイスをUP状態にして、利用可能にする
$ ip netns exec ns1 ip link set ns1-veth0 up
$ ip netns exec router ip link set gw-veth0 up
$ ip netns exec router ip link set gw-veth1 up
$ ip link set veth0 up

# IPアドレスを設定
$ ip netns exec ns1 ip addr add 192.0.2.1/24 dev ns1-veth0
$ ip netns exec router ip addr add 192.0.2.254/24 dev gw-veth0
$ ip netns exec router ip addr add 198.51.100.1/24 dev gw-veth1
$ ip addr add 198.51.100.254/24 dev veth0

# デフォルトゲートウェイを設定
$ ip netns exec ns1 ip route add default via 192.0.2.254
$ ip netns exec router ip route add default via 198.51.100.254

# host/routerをIPv4ルーター化
$ sysctl net.ipv4.ip_forward=1
$ ip netns exec router sysctl net.ipv4.ip_forward=1

# NATを設定
$ ip netns exec router iptables -t nat \
  -A POSTROUTING \
  -s 192.0.2.0/24 \
  -o gw-veth1 \
  -j MASQUERADE

$ iptables -t nat \
  -A POSTROUTING \
  -s 198.51.100.0/24 \
  -j MASQUERADE

動作確認

$ ip netns exec ns1 ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=3.95 ms

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

$ ip netns exec router ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=3.93 ms

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

クリーンアップ

$ ip netns delete ns1
$ ip netns delete router
$ iptables --table nat --flush
$ sysctl net.ipv4.ip_forward=0

不明点

  • router側でデフォルトゲートウェイを設定しただけだとns1から8.8.8.8に通信ができなくて、NATを設定したらできるようになったんだけどなんで?
bells17bells17

macvlanを試す

参考:
https://networkstatic.net/configuring-macvlan-ipvlan-linux-networking/

構成

環境構築

# NSを作成
$ ip netns add net1
$ ip netns add net2

# macvlanを追加
$ ip link add macvlan1 link eth0 type macvlan mode bridge
$ ip link add macvlan2 link eth0 type macvlan mode bridge

# macvlanをNetwork Namespaceで使えるようにする
$ ip link set macvlan1 netns net1
$ ip link set macvlan2 netns net2

# ネットワークインターフェイスをUP状態にして、利用可能にする
$ ip netns exec net1 ip link set lo up
$ ip netns exec net2 ip link set lo up

# IP使って通信可能にするためにIPアドレスを付与
$ ip netns exec net1 ifconfig macvlan1 192.168.1.50/24 up
$ ip netns exec net2 ifconfig macvlan2 192.168.1.60/24 up

動作確認

$ ip netns exec net1 ping -c 3 192.168.1.60
PING 192.168.1.60 (192.168.1.60) 56(84) bytes of data.
64 bytes from 192.168.1.60: icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from 192.168.1.60: icmp_seq=2 ttl=64 time=0.029 ms
64 bytes from 192.168.1.60: icmp_seq=3 ttl=64 time=0.035 ms

--- 192.168.1.60 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2084ms
rtt min/avg/max/mdev = 0.023/0.029/0.035/0.005 ms

クリーンアップ

$ ip -all netns delete

感想

macvlan経由で通信はできたけど、macvlan自体が何かはよくわからなかった

https://gihyo.jp/admin/serial/01/linux_containers/0006

一方、macvlanはMACアドレスを持ちますので、DHCPでアドレスを割り当てることが可能です。

仮想インターフェースとは言っても、実際の受信処理は物理的なインターフェースのドライバ経由で行われますので、vethに比べるとオーバーヘッドが少なく、パフォーマンスが良い傾向にあります。

こういう違い?

https://zenn.dev/link/comments/00f88ee401cddf

でDHCPを試した時にvethにDHCPでIPアドレスを割り当てられたので

一方、macvlanはMACアドレスを持ちますので、DHCPでアドレスを割り当てることが可能です。

がよくわからない

これがあんまわかってないけど勉強になった

https://markunet.github.io/blog/Intro_Linux_interfaces_JP/

bells17bells17

Network Namespaceからインターネットに接続する(bridge版)

↓のbridge版

https://zenn.dev/link/comments/ade91086233a07

参考:
https://christina04.hatenablog.com/entry/access-internet-from-network-namespace

https://christina04.hatenablog.com/entry/network-namespace-with-bridge

構成

環境構築

# NSを作成
$ ip netns add ns1
$ ip netns add ns2
$ ip netns add bridge

# 仮想ネットワークインターフェイスを追加
$ ip link add ns1-veth0 type veth peer name ns1-br0
$ ip link add ns2-veth0 type veth peer name ns2-br0
$ ip link add br0-veth0 type veth peer name veth0

# 仮想ネットワークインターフェイスをNetwork Namespaceで使えるようにする
$ ip link set ns1-veth0 netns ns1
$ ip link set ns2-veth0 netns ns2
$ ip link set ns1-br0 netns bridge
$ ip link set ns2-br0 netns bridge
$ ip link set br0-veth0 netns bridge

# IP使って通信可能にするためにIPアドレスを付与
$ ip netns exec ns1 ip addr add 192.0.2.1/24 dev ns1-veth0
$ ip netns exec ns2 ip addr add 192.0.2.2/24 dev ns2-veth0
$ ip addr add 192.0.2.254/24 dev veth0

# ネットワークブリッジを作成してUP状態にする
$ ip netns exec bridge ip link add dev br0 type bridge
$ ip netns exec bridge ip link set br0 up

# vethをネットワークブリッジに追加
$ ip netns exec bridge ip link set ns1-br0 master br0
$ ip netns exec bridge ip link set ns2-br0 master br0
$ ip netns exec bridge ip link set br0-veth0 master br0

# ネットワークインターフェイスをUP状態にして、利用可能にする
$ ip netns exec ns1 ip link set ns1-veth0 up
$ ip netns exec ns2 ip link set ns2-veth0 up
$ ip netns exec bridge ip link set ns1-br0 up
$ ip netns exec bridge ip link set ns2-br0 up
$ ip netns exec bridge ip link set br0-veth0 up
$ ip link set veth0 up

# デフォルトゲートウェイを設定
$ ip netns exec ns1 ip route add default via 192.0.2.254
$ ip netns exec ns2 ip route add default via 192.0.2.254

# hostをIPv4ルーター化
$ sysctl net.ipv4.ip_forward=1

# NATを設定
$ iptables -t nat \
  -A POSTROUTING \
  -s 192.0.2.0/24 \
  -j MASQUERADE

動作確認

$ ip netns exec ns1 ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=3.100 ms

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

クリーンアップ

$ ip -all netns delete
$ iptables --table nat --flush
$ sysctl net.ipv4.ip_forward=0