honai.me / slides

Network namespaceで遊ぼう

埋め込みコード (iframe)

Network namespaceで遊ぼう のスクリプト

  1. Network namespaceで遊ぼう 1
  2. 今日話すこと 3
  3. 物理ネットワークの世界 https://en.wikipedia.org/wiki/Ethernet_physical_layer https://www.buffalo.jp/product/detail/wsr- 1166dhpl2.html 4
  4. 一般のご家庭* のLANの例 インターネッ ト ISP ONU等 ルーター パソコン IP: 192.168.0.254/24 MAC: CC:CC:CC:33:33:33 IP: 192.168.0.1/24 MAC: AA:AA:AA:11:11:11 プリンタ IP: 192.168.0.2/24 MAC: BB:BB:BB:22:22:22 192.168.0.0/24 5
  5. Network namespaceとは 6
  6. トーク内容について 7
  7. Linuxの “ip” コマンド 8
  8. VMのネットワークを確認する # ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN …(略) link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc mq state UP …(略) link/ether 42:01:0a:8a:00:03 brd ff:ff:ff:ff:ff:ff inet 10.138.0.3/32 brd 10.138.0.3 scope global dynamic ens4 valid_lft 3060sec preferred_lft 3060sec Internet 物理マシンや データセンタ ネットワーク IP 10.138.0.3/32 ens4 MAC 42:01:0a:8a:00:03 VM 9
  9. VMのネットワークを確認する # ip route default via 10.138.0.1 dev ens4 10.138.0.1 dev ens4 scope link Internet ゲート ウェイ IP 10.138.0.1 IP 10.138.0.3/32 ens4 MAC 42:01:0a:8a:00:03 VM 10
  10. VMからインターネットへの疎通を確認 # ping -c 3 1.1.1.1 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data. 64 bytes from 1.1.1.1: icmp_seq=1 ttl=61 time=8.29 ms 64 bytes from 1.1.1.1: icmp_seq=2 ttl=61 time=7.42 ms 64 bytes from 1.1.1.1: icmp_seq=3 ttl=61 time=7.66 ms --- 1.1.1.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 7.424/7.792/8.289/0.364 ms Internet 1.1.1.1 ゲート (Cloudflare) ウェイ IP 10.138.0.1 ens4 IP 10.138.0.3/32 MAC 42:01:0a:8a:00:03 VM 11
  11. VMのネットワークについて確認した 12
  12. ここからNetwork namespaceの話 13
  13. Network namespaceを作成 # ip netns show ← namespace確認。デフォルトのnamespace は表示されません # ip netns add test_ns ← 「test_ns」というnamespaceを作成 # ip netns show ← 作成された test_ns 14
  14. Network namespaceを指定してプロセスを起動 “test_ns” namespaceで実行 # ip netns exec test_ns ip address show 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 15
  15. Network namespaceを指定して通信を試す “test_ns” namespaceで実行 # ip netns exec test_ns ip route show Error: ipv4: FIB table does not exist. Dump terminated “test_ns” namespaceで実行 # ip netns exec test_ns ping 1.1.1.1 ping: connect: Network is unreachable 16
  16. Network namespace (略) ゲートウェイ ens4 デフォルトのnamespace test_ns (何もない) 17
  17. 今回構築するネットワークの構成 Internet (略) ② pcから外部へ通信できる ens4 VMのデフォルトのnamespace 10.0.0.1/24 仮想ブリッジ “pc” 10.0.0.254/24 namespace 10.0.0.2/24 ① pcとprinter間で通信ができる “printer” namespace 18
  18. Namespaceを作成 # ip netns delete test_ns (先ほど作成したtest_nsは消しておく) # ip netns add pc # ip netns add printer # ip netns show pc printer “pc” namespace ens4 VMのデフォルトのnamespace “printer” namespace 19
  19. vethを作成 # ip link add name veth1-pc type veth peer name veth1-br (仮想的なLANケーブル) veth1-pc veth1-br “pc”側に接続する用 ブリッジ側に 接続する用 20
  20. vethを作成 “pc” namespace ens4 veth1-pc veth1-br “printer” VMのデフォルトのnamespace namespace 21
  21. vethを作成 # ip link set veth1-pc netns pc “pc” namespace veth1-pc ens4 veth1-br “printer” VMのデフォルトのnamespace namespace 22
  22. “pc”のインターフェース確認 “pc” namespaceで実行 # ip netns exec pc ip link show 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT …(略) link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4: veth1-pc@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN… link/ether b6:a0:3c:0b:3b:60 brd ff:ff:ff:ff:ff:ff link-netnsid 0 “pc” veth1-pc namespace ens4 veth1-br VMのデフォルトのnamespace “printer” namespace 23
  23. さらにvethを2本作成 # ip link add name veth2-printer type veth peer name veth2-br # ip link add name veth3-df type veth peer name veth3-br # ip link set veth2-printer netns printer “pc” veth1-pc namespace ens4 veth1-br VMのデフォルトのnamespace “printer” veth2- namespace veth2-br veth3-df veth3-br printer 24
  24. ブリッジを作成 # brctl addbr bridge0 # brctl show bridge name bridge id STP enabled interfaces bridge0 8000.ea9d7394db4f no “pc” veth1-pc ens4 namespace bridge0 veth1-br VMのデフォルトのnamespace “printer” veth2- namespace printer veth2-br veth3-df veth3-br 25
  25. vethの片方をブリッジに割り当てる # brctl addif bridge0 veth1-br # brctl addif bridge0 veth2-br # brctl show bridge0 bridge name bridge id STP enabled interfaces bridge0 8000.ea9d7394db4f no veth1-br veth2-br (veth3-br は一旦後回しにします) ens4 “pc” veth1-pc veth1-br namespace bridge0 veth2-br veth3-df veth3-br “printer” veth2- namespace VMのデフォルトのnamespace printer 26
  26. まずpcとprinterで通信できるようにする “pc” veth1-pc namespace veth1-br bridge0 veth2-br “printer” namespace veth2- VMのデフォルトのnamespace printer 27
  27. pcとprinter側にIPアドレスを設定 “pc” namespaceで実行 # ip netns exec pc ip address add 10.0.0.1/24 dev veth1-pc # ip netns exec printer ip address add 10.0.0.2/24 dev veth2-printer “printer” namespaceで実行 (# ip netns exec [ns名] ip address show でIPを確認できる) 10.0.0.1/24 “pc” veth1-pc namespace veth1-br bridge0 veth2-br 10.0.0.2/24 “printer” namespace veth2- VMのデフォルトのnamespace printer 28
  28. ステータスをUPにする # ip link set bridge0 up # ip link set veth1-br up # ip link set veth2-br up # ip netns exec pc ip link set veth1-pc up # ip netns exec printer ip link set veth2-printer up 10.0.0.1/24 “pc” veth1-pc namespace veth1-br bridge0 veth2-br 10.0.0.2/24 “printer” namespace veth2- VMのデフォルトのnamespace printer 29
  29. pcからprinterへping “pc” namespaceで実行 # ip netns exec pc ping -c 3 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.036 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.049 ms 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.054 ms --- 10.0.0.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2024ms rtt min/avg/max/mdev = 0.036/0.046/0.054/0.007 ms 10.0.0.1/24 “pc” veth1-pc veth1-br namespace bridge0 veth2-br 10.0.0.2/24 “printer” veth2- namespace printer 30
  30. printer, pcとVMを接続する veth3-brをbridge0に接続 # brctl addif bridge0 veth3-br # brctl show bridge0 bridge name bridge id STP enabled interfaces bridge0 8000.ea9d7394db4f no veth1-br veth2-br veth3-br 10.0.0.1/24 ens4 “pc” veth1-pc veth1-br namespace bridge0 veth2-br 10.0.0.2/24 veth3-br veth3-df “printer” veth2- namespace VMのデフォルトのnamespace printer 31
  31. “printer, ” “pc”とVMを接続する veth3-df(VM側)にIPアドレスを割り当てる # ip address add 10.0.0.254/24 dev veth3-df 各インターフェースをUPにする # ip link set veth3-br up # ip link set veth3-df up 10.0.0.1/24 ens4 “pc” veth1-pc namespace veth1-br bridge0 veth2-br 10.0.0.254/24 10.0.0.2/24 “printer” veth3-br veth3-df namespace veth2- VMのデフォルトのnamespace printer 32
  32. ”pc”とVM間での通信を確認 “pc” namespaceで実行 # ip netns exec pc ping -c 3 10.0.0.254 PING 10.0.0.254 (10.0.0.254) 56(84) bytes of data. 64 bytes from 10.0.0.254: icmp_seq=1 ttl=64 time=0.045 ms 64 bytes from 10.0.0.254: icmp_seq=2 ttl=64 time=0.058 ms 64 bytes from 10.0.0.254: icmp_seq=3 ttl=64 time=0.051 ms --- 10.0.0.254 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2040ms rtt min/avg/max/mdev = 0.045/0.051/0.058/0.005 ms 10.0.0.1/24 ens4 “pc” veth1-pc veth1-br namespace bridge0 veth2-br 10.0.0.254/24 10.0.0.2/24 veth3-br veth3-df “printer” veth2- namespace VMのデフォルトのnamespace printer 33
  33. “pc”から外部接続できるか? “pc” namespaceで実行 # ip netns exec pc ping 1.1.1.1 ping: connect: Network is unreachable # ip netns exec pc ip route show 10.0.0.0/24 dev veth1-pc proto kernel scope link src 10.0.0.1 ↑デフォルトゲートウェイがない 1.1.1.1 ens4 10.0.0.1/24 “pc” veth1-pc namespace veth1-br 1.1.1.1宛 bridge0 veth2-br 10.0.0.254/24 10.0.0.2/24 “printer” veth3-br veth3-df namespace veth2- VMのデフォルトのnamespace printer 34
  34. “pc”から外部接続できるか? テイク2 # ip netns exec pc ip route add default via 10.0.0.254 # ip netns exec pc ip route show default via 10.0.0.254 dev veth1-pc 10.0.0.0/24 dev veth1-pc proto kernel scope link src 10.0.0.1 # ip netns exec pc ping 1.1.1.1 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data. [応答なし] 1.1.1.1 ^C [Ctrl+C] --- 1.1.1.1 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1026ms 10.0.0.1/24 ens4 “pc” veth1-pc veth1-br namespace bridge0 1.1.1.1宛 veth2-br 10.0.0.254/24 10.0.0.2/24 veth3-br veth3-df “printer” veth2- namespace VMのデフォルトのnamespace printer 35
  35. 外部接続に必要なこと Internet 10.138.0.3 ens4 10.0.0.1/24 “pc” veth1-pc iptables namespace veth1-br IPマスカレード (NAPT) bridge0 10.0.0.2/24 veth2-br “printer” veth3-br veth3-df namespace veth2- 10.0.0.254/24 printer VMのデフォルトのnamespace 36
  36. iptablesの設定 # echo 1 > /proc/sys/net/ipv4/ip_forward ←IPフォワーディング有効化 # iptables --table nat --flush ←NATテーブルの初期化 # iptables --table nat --append POSTROUTING \ ←NAPTの設定 --source 10.0.0.0/24 --jump MASQUERADE Internet 10.138.0.3 10.0.0.1/24 ens4 “pc” veth1-pc iptables namespace veth1-br IPマスカレード (NAPT) bridge0 10.0.0.2/24 veth2-br “printer” veth2- veth3-br veth3-df namespace 10.0.0.254/24 printer VMのデフォルトのnamespace 37
  37. “pc”から外部接続できるか? テイク3 # ip netns exec pc ping -c 3 1.1.1.1 🎉🎉 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data. 64 bytes from 1.1.1.1: icmp_seq=1 ttl=60 time=8.02 ms 64 bytes from 1.1.1.1: icmp_seq=2 ttl=60 time=6.80 ms 64 bytes from 1.1.1.1: icmp_seq=3 ttl=60 time=6.95 ms 1.1.1.1 --- 1.1.1.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 6.796/7.255/8.017/0.542 ms Internet 10.138.0.3 ens4 10.0.0.1/24 “pc” veth1-pc iptables namespace veth1-br IPマスカレード (NAPT) 1.1.1.1宛 bridge0 10.0.0.2/24 veth2-br “printer” veth3-br veth3-df namespace veth2- 10.0.0.254/24 printer VMのデフォルトのnamespace 38
  38. まとめ 39
  39. Appendix: tcpdumpでNAPTの動作を確認 # curl -I 1.1.1.1 ←VMのnamespace, “pc”, “printer” (略) # ip netns exec pc curl -I 1.1.1.1 から1.1.1.1にcurlでHTTP通信する (略) # ip netns exec printer curl -I 1.1.1.1 ↓別ターミナルで、tcpdumpで観察 # tcpdump -nn -i ens4 src or dst 1.1.1.1 listening on ens4, (略) 21:29:20.298355 IP 10.138.0.3.40446 > 1.1.1.1.80: Flags [S], (略) 21:29:20.304912 IP 1.1.1.1.80 > 10.138.0.3.40446: Flags [S.], (略) (略) 21:29:47.140985 IP 10.138.0.3.43984 > 1.1.1.1.80: Flags [S], (略) 21:29:47.149100 IP 1.1.1.1.80 > 10.138.0.3.43984: Flags [S.], (略) (略) 21:30:07.152752 IP 10.138.0.3.60080 > 1.1.1.1.80: Flags [S], (略) 21:30:07.162737 IP 1.1.1.1.80 > 10.138.0.3.60080: Flags [S.], (略) (略) 40
  40. 参考文献 https://blog.kamijin-fanta.info/2018/12/netns/ https://sagantaf.hatenablog.com/entry/2019/12/14/000948 https://www.man7.org/linux/man- pages/man8/ip-route.8.html 41