「TCP/IP」の版間の差分
ナビゲーションに移動
検索に移動
(ページの作成:「==TCP/IP==」) |
(→ブリッジ) |
||
(同じ利用者による、間の122版が非表示) | |||
1行目: | 1行目: | ||
+ | | [[Multipass]] | [[Ubuntu]] | | ||
==TCP/IP== | ==TCP/IP== | ||
+ | {{amazon|B085BG8CH5}} | ||
+ | |||
+ | ===ipコマンド=== | ||
+ | ---- | ||
+ | ====[https://atmarkit.itmedia.co.jp/ait/articles/1709/22/news019.html 基礎1]==== | ||
+ | *https://atmarkit.itmedia.co.jp/ait/articles/1709/22/news019.html から引用 | ||
+ | |||
+ | <table class="wikitable" ><tr><td>オブジェクト</td><td>別名(省略形)</td><td>意味</td></tr><tr><td>link</td><td>l</td><td>ネットワークデバイス</td></tr><tr><td>addr</td><td>a、address</td><td>ネットワークデバイスのIPアドレス</td></tr><tr><td>addrlabel</td><td>addrl</td><td>アドレスラベル</td></tr><tr><td>route</td><td>r</td><td>ルーティングテーブルのエントリー</td></tr><tr><td>rule</td><td>rul</td><td>ルーティングポリシーデータベースに登録されているルール</td></tr><tr><td>neigh</td><td>n、neighbour</td><td>近傍キャッシュエントリ(ARPまたはNDISCキャッシュエントリ)</td></tr><tr><td>ntable</td><td>nt、ntb</td><td>近傍キャッシュの管理テーブル</td></tr><tr><td>tunnel</td><td>t</td><td>IPトンネル</td></tr><tr><td>tuntap</td><td>tu</td><td>トンネルデバイス</td></tr><tr><td>maddr</td><td>m、ma、mad</td><td>マルチキャストアドレス</td></tr><tr><td>mroute</td><td>mr</td><td>マルチキャストルーティングのキャッシュエントリ</td></tr><tr><td>mrule</td><td>mru</td><td>マルチキャストルーティングポリシーデータベースに登録されているルール</td></tr><tr><td>monitor</td><td>mon</td><td>ネットリンクメッセージの監視</td></tr><tr><td>xfrm</td><td>x、xf</td><td>IPsecポリシー</td></tr><tr><td>netns</td><td>net</td><td>ネットワーク名前空間</td></tr><tr><td>l2tp</td><td>l2</td><td>L2TPv3(レイヤー2トンネリングプロトコル)</td></tr><tr><td>tcp_metrics</td><td>tcp_m、tcp_metrics、tcpm</td><td>TCPメトリック</td></tr><tr><td>token</td><td>tok</td><td>トークン</td></table> | ||
+ | |||
+ | ====[https://atmarkit.itmedia.co.jp/ait/articles/1709/28/news029.html 基礎2]==== | ||
+ | ====[https://atmarkit.itmedia.co.jp/ait/articles/1709/29/news019.html 基礎3]==== | ||
+ | ====[https://atmarkit.itmedia.co.jp/ait/articles/1710/05/news012.html 応用]==== | ||
+ | |||
+ | ===ip address show=== | ||
+ | ---- | ||
+ | *inet の後がIPアドレス | ||
+ | *lo,ens3 はネットワークインターフェース(NICや無線LANアダプタなどを抽象化) | ||
+ | *IPアドレスはネットワークインターフェースに付与される | ||
+ | *127.0.0.1はループバックアドレスで、自分自身を表す | ||
+ | *ループバックアドレスが付与されているインターフェースはループバックインターフェース | ||
+ | |||
+ | <pre> | ||
+ | $ ip address show | ||
+ | 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 | ||
+ | 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 | ||
+ | inet6 ::1/128 scope host | ||
+ | valid_lft forever preferred_lft forever | ||
+ | 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 | ||
+ | link/ether 52:54:00:97:68:97 brd ff:ff:ff:ff:ff:ff | ||
+ | inet 192.168.122.243/24 brd 192.168.122.255 scope global dynamic ens3 | ||
+ | valid_lft 3189sec preferred_lft 3189sec | ||
+ | inet6 fe80::5054:ff:fe97:6897/64 scope link | ||
+ | valid_lft forever preferred_lft forever | ||
+ | </pre> | ||
+ | |||
+ | ===tcpdump パケットキャプチャ=== | ||
+ | ---- | ||
+ | * -t : 時刻情報出力抑制 | ||
+ | * -n : IP逆引きしない | ||
+ | * -i : 対象インターフェースを指定 anyで全て | ||
+ | * icmp : icmp プロトコルに限定 | ||
+ | <pre> | ||
+ | $ sudo tcpdump -tn -i any icmp | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes | ||
+ | IP 192.168.122.243 > 8.8.8.8: ICMP echo request, id 2, seq 1, length 64 | ||
+ | IP 8.8.8.8 > 192.168.122.243: ICMP echo reply, id 2, seq 1, length 64 | ||
+ | IP 192.168.122.243 > 8.8.8.8: ICMP echo request, id 2, seq 2, length 64 | ||
+ | IP 8.8.8.8 > 192.168.122.243: ICMP echo reply, id 2, seq 2, length 64 | ||
+ | </pre> | ||
+ | ===traceroute=== | ||
+ | ---- | ||
+ | * パケット通過ルーター | ||
+ | * TTL : 0-255と解釈される値が入りパケット送出時にノードが初期値を設定、ルーター追加ごとに1つづつ値が減る。経路で値が0になるとルーターにより破棄されるが、この時ルーターは、ICMPで時間切れメッセージを送信元に送る | ||
+ | * TTLにあえて小さな値を設定し、TTLを1つづつ増やしたパケットを送信、時間切れをおこした通知を組み立てる | ||
+ | * 時間切れを通知しないルーター設定は、* となる | ||
+ | <pre> | ||
+ | $ traceroute typea.info | ||
+ | traceroute to typea.info (160.16.110.88), 64 hops max | ||
+ | 1 192.168.122.1 0.343ms 0.288ms 0.301ms | ||
+ | 2 192.168.0.1 0.694ms 0.492ms 0.487ms | ||
+ | 3 210.173.146.32 4.710ms 4.013ms 3.784ms | ||
+ | 4 210.173.145.69 3.968ms 4.044ms 4.072ms | ||
+ | 5 210.173.150.97 3.557ms 4.091ms 3.896ms | ||
+ | 6 210.171.224.113 9.550ms 7.866ms 8.150ms | ||
+ | 7 * * * | ||
+ | 8 * * * | ||
+ | 9 * * * | ||
+ | 10 * * * | ||
+ | 11 160.16.110.88 11.148ms 12.124ms 12.150ms | ||
+ | </pre> | ||
+ | ===ip route show ルーティングテーブル=== | ||
+ | ---- | ||
+ | * 複数のルーティングエントリから構成(それぞれの行) | ||
+ | * 先頭に宛先のIPアドレス | ||
+ | * 宛先に続くのがネクストホップ(パケットを次に渡す相手) | ||
+ | <pre> | ||
+ | $ ip route show | ||
+ | default via 192.168.122.1 dev ens3 proto dhcp src 192.168.122.243 metric 100 | ||
+ | 192.168.122.0/24 dev ens3 proto kernel scope link src 192.168.122.243 | ||
+ | 192.168.122.1 dev ens3 proto dhcp scope link src 192.168.122.243 metric 100 | ||
+ | </pre> | ||
+ | |||
+ | ==IPアドレス== | ||
+ | *32bitの前半をネットワーク部(ネットワークアドレス)、後半をホスト部(ホストアドレス) | ||
+ | *192.0.2.1/24 24bitで分割 -> ネットワーク部 192.0.2.0、ホスト部 .1 | ||
+ | *ネットワーク部は、ネットワークセグメントを表す、同じなら同じセグメントに属する | ||
+ | *192.0.2.1/24 この書き方はCIDR表記と呼ばれる | ||
+ | *サブネット表記では、255.255.255.0 | ||
+ | |||
+ | ==Network Namespace== | ||
+ | * ip netns add {{名前}}で新しいNetwork Namespaceを作成できる | ||
+ | * ip netns delete {{名前}}で削除 | ||
+ | <pre> | ||
+ | $ sudo ip netns add helloworld | ||
+ | $ ip netns list | ||
+ | helloworld | ||
+ | </pre> | ||
+ | |||
+ | * ip nets exec | ||
+ | ** 指定したNetwork Namespace環境でコマンドを実行 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec helloworld 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 | ||
+ | </pre> | ||
+ | |||
+ | * Network Namespaceでシェルも起動できる | ||
+ | <pre> | ||
+ | $ sudo ip netns exec helloworld bash | ||
+ | </pre> | ||
+ | ===ネットワークを作成して接続=== | ||
+ | ---- | ||
+ | ====2つのNetwork Namespaceを作成==== | ||
+ | [[File:network01.png|400px]] | ||
+ | <pre> | ||
+ | $ sudo ip netns add ns1 | ||
+ | $ sudo ip netns add ns2 | ||
+ | </pre> | ||
+ | *接続するには、veth(Virtual Ethernet Device)を作成 | ||
+ | *Nework Namespaceに所属させる | ||
+ | <pre> | ||
+ | $ sudo ip link add ns1-veth0 type veth peer name ns2-veth0 | ||
+ | $ sudo ip link set ns1-veth0 netns ns1 | ||
+ | $ sudo ip link set ns2-veth0 netns ns2 | ||
+ | </pre> | ||
+ | * 確認 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip link show | ||
+ | 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 | ||
+ | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 | ||
+ | 4: ns1-veth0@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 | ||
+ | link/ether ca:f0:3b:a9:2a:eb brd ff:ff:ff:ff:ff:ff link-netns ns2 | ||
+ | </pre> | ||
+ | |||
+ | ====IPアドレスを付与==== | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 | ||
+ | $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0 | ||
+ | </pre> | ||
+ | *確認 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 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 | ||
+ | 4: ns1-veth0@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 | ||
+ | link/ether ca:f0:3b:a9:2a:eb brd ff:ff:ff:ff:ff:ff link-netns ns2 | ||
+ | inet 192.0.2.1/24 scope global ns1-veth0 | ||
+ | valid_lft forever preferred_lft forever | ||
+ | </pre> | ||
+ | ====vethを有効化==== | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip link set ns1-veth0 up | ||
+ | $ sudo ip netns exec ns2 ip link set ns2-veth0 up | ||
+ | </pre> | ||
+ | *疎通 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ping 192.0.2.2 -c 3 | ||
+ | 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.334 ms | ||
+ | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.101 ms | ||
+ | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.091 ms | ||
+ | |||
+ | --- 192.0.2.2 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2051ms | ||
+ | rtt min/avg/max/mdev = 0.091/0.175/0.334/0.112 ms | ||
+ | </pre> | ||
+ | ===ルーターを介したネットワーク=== | ||
+ | ---- | ||
+ | [[File:network_router.png|400px]] | ||
+ | ====Network Namespaceの構成==== | ||
+ | <pre> | ||
+ | $ sudo ip netns add ns1 | ||
+ | $ sudo ip netns add router | ||
+ | $ sudo ip netns add route2 | ||
+ | $ sudo ip netns add ns2 | ||
+ | </pre> | ||
+ | *それぞれのNetwork Namespaceを繋ぐvethインターフェースを作成 | ||
+ | <pre> | ||
+ | $ sudo ip link add ns1-veth0 type veth peer name gw-veth0 | ||
+ | $ sudo ip link add ns2-veth0 type veth peer name gw-veth1 | ||
+ | </pre> | ||
+ | *vethをNetwork Namespaceに属させる | ||
+ | <pre> | ||
+ | $ sudo ip link set ns1-veth0 netns ns1 | ||
+ | $ sudo ip link set gw-veth0 netns router | ||
+ | $ sudo ip link set gw-veth1 netns router | ||
+ | $ sudo ip link set ns2-veth0 netns ns2 | ||
+ | </pre> | ||
+ | *vethをup | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip link set ns1-veth0 up | ||
+ | $ sudo ip netns exec router ip link set gw-veth0 up | ||
+ | $ sudo ip netns exec router ip link set gw-veth1 up | ||
+ | $ sudo ip netns exec ns2 ip link set ns2-veth0 up | ||
+ | </pre> | ||
+ | * IPアドレスを付与 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 | ||
+ | $ sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0 | ||
+ | $ sudo ip netns exec router ip address add 198.51.100.254/24 dev gw-veth1 | ||
+ | $ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0 | ||
+ | </pre> | ||
+ | |||
+ | ====セグメント内の通信==== | ||
+ | *ns1 と ns2それぞれから、rouer にping | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ping -c 3 192.0.2.254 | ||
+ | PING 192.0.2.254 (192.0.2.254) 56(84) bytes of data. | ||
+ | 64 bytes from 192.0.2.254: icmp_seq=1 ttl=64 time=0.362 ms | ||
+ | 64 bytes from 192.0.2.254: icmp_seq=2 ttl=64 time=0.102 ms | ||
+ | 64 bytes from 192.0.2.254: icmp_seq=3 ttl=64 time=0.108 ms | ||
+ | |||
+ | --- 192.0.2.254 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2049ms | ||
+ | rtt min/avg/max/mdev = 0.102/0.190/0.362/0.121 ms | ||
+ | $ sudo ip netns exec ns2 ping -c 3 198.51.100.254 | ||
+ | PING 198.51.100.254 (198.51.100.254) 56(84) bytes of data. | ||
+ | 64 bytes from 198.51.100.254: icmp_seq=1 ttl=64 time=0.314 ms | ||
+ | 64 bytes from 198.51.100.254: icmp_seq=2 ttl=64 time=0.106 ms | ||
+ | 64 bytes from 198.51.100.254: icmp_seq=3 ttl=64 time=0.110 ms | ||
+ | |||
+ | --- 198.51.100.254 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2051ms | ||
+ | rtt min/avg/max/mdev = 0.106/0.176/0.314/0.097 ms | ||
+ | </pre> | ||
+ | |||
+ | *セグメントはこえられない | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 | ||
+ | ping: connect: Network is unreachable | ||
+ | </pre> | ||
+ | |||
+ | ====ルーティングテーブルの確認と設定==== | ||
+ | *確認 | ||
+ | *自身のセグメントしか表示されない | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip route show | ||
+ | 192.0.2.0/24 dev ns1-veth0 proto kernel scope link src 192.0.2.1 | ||
+ | </pre> | ||
+ | *デフォルトルート(他の宛先に一致しない場合)を追加、routerに向ける | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip route add default via 192.0.2.254 | ||
+ | </pre> | ||
+ | *追加された | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip route show | ||
+ | default via 192.0.2.254 dev ns1-veth0 | ||
+ | 192.0.2.0/24 dev ns1-veth0 proto kernel scope link src 192.0.2.1 | ||
+ | </pre> | ||
+ | *ns2にも同様に | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns2 ip route add default via 198.51.100.254 | ||
+ | </pre> | ||
+ | *ns1 から ns2 へ再度 ping | ||
+ | *エラーとはならないが、パケットロス100% | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 | ||
+ | PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. | ||
+ | |||
+ | --- 198.51.100.1 ping statistics --- | ||
+ | 3 packets transmitted, 0 received, 100% packet loss, time 2039ms | ||
+ | </pre> | ||
+ | *以下の設定を実施 | ||
+ | *sysctlでカーネルパラメータを設定(net.ipv4.ip_forward = 1 ルーターとして動作するかを設定) | ||
+ | <pre> | ||
+ | $ sudo ip netns exec router sysctl net.ipv4.ip_forward=1 | ||
+ | net.ipv4.ip_forward = 1 | ||
+ | </pre> | ||
+ | *ルーターを介した接続成功 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 | ||
+ | PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. | ||
+ | 64 bytes from 198.51.100.1: icmp_seq=1 ttl=63 time=0.208 ms | ||
+ | 64 bytes from 198.51.100.1: icmp_seq=2 ttl=63 time=0.114 ms | ||
+ | 64 bytes from 198.51.100.1: icmp_seq=3 ttl=63 time=0.134 ms | ||
+ | |||
+ | --- 198.51.100.1 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2032ms | ||
+ | rtt min/avg/max/mdev = 0.114/0.152/0.208/0.040 ms | ||
+ | </pre> | ||
+ | |||
+ | ===ルーターを増やす=== | ||
+ | [[File:network3.png|400px]] | ||
+ | * これまでの設定を削除 | ||
+ | <pre> | ||
+ | $ sudo ip --all netns delete | ||
+ | $ sudo ip netns ls | ||
+ | </pre> | ||
+ | ====Network Namespace作成==== | ||
+ | <pre> | ||
+ | $ sudo ip netns add ns1 | ||
+ | $ sudo ip netns add router1 | ||
+ | $ sudo ip netns add router2 | ||
+ | $ sudo ip netns add ns2 | ||
+ | </pre> | ||
+ | *veth作成 | ||
+ | <pre> | ||
+ | $ sudo ip link add ns1-veth0 type veth peer name gw1-veth0 | ||
+ | $ sudo ip link add gw1-veth1 type veth peer name gw2-veth0 | ||
+ | $ sudo ip link add gw2-veth1 type veth peer name ns2-veth0 | ||
+ | </pre> | ||
+ | *vethを所属させる | ||
+ | <pre> | ||
+ | $ sudo ip link set ns1-veth0 netns ns1 | ||
+ | $ sudo ip link set gw1-veth0 netns router1 | ||
+ | $ sudo ip link set gw1-veth1 netns router1 | ||
+ | $ sudo ip link set gw2-veth0 netns router2 | ||
+ | $ sudo ip link set gw2-veth1 netns router2 | ||
+ | $ sudo ip link set ns2-veth0 netns ns2 | ||
+ | </pre> | ||
+ | *up | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip link set ns1-veth0 up | ||
+ | $ sudo ip netns exec router1 ip link set gw1-veth0 up | ||
+ | $ sudo ip netns exec router1 ip link set gw1-veth1 up | ||
+ | $ sudo ip netns exec router2 ip link set gw2-veth0 up | ||
+ | $ sudo ip netns exec router2 ip link set gw2-veth1 up | ||
+ | $ sudo ip netns exec ns2 ip link set ns2-veth0 up | ||
+ | </pre> | ||
+ | ====IP設定==== | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 | ||
+ | $ sudo ip netns exec router1 ip address add 192.0.2.254/24 dev gw1-veth0 | ||
+ | $ sudo ip netns exec router1 ip address add 203.0.113.1/24 dev gw1-veth1 | ||
+ | $ sudo ip netns exec router2 ip address add 203.0.113.2/24 dev gw2-veth0 | ||
+ | $ sudo ip netns exec router2 ip address add 198.51.100.254/24 dev gw2-veth1 | ||
+ | $ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0 | ||
+ | </pre> | ||
+ | *ns1,ns2 のデフォルトルートをルーターに向ける | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip route add default via 192.0.2.254 | ||
+ | $ sudo ip netns exec ns2 ip route add default via 198.51.100.254 | ||
+ | </pre> | ||
+ | *router1,route2のカーネルオプションを設定しルーターにする | ||
+ | <pre> | ||
+ | $ sudo ip netns exec router1 sysctl net.ipv4.ip_forward=1 | ||
+ | net.ipv4.ip_forward = 1 | ||
+ | $ sudo ip netns exec router2 sysctl net.ipv4.ip_forward=1 | ||
+ | net.ipv4.ip_forward = 1 | ||
+ | </pre> | ||
+ | *ns1から、ns2へpingを流すと、router1からパケットを届けることができなかったメッセージが帰る | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 | ||
+ | PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. | ||
+ | From 192.0.2.254 icmp_seq=1 Destination Net Unreachable | ||
+ | From 192.0.2.254 icmp_seq=2 Destination Net Unreachable | ||
+ | From 192.0.2.254 icmp_seq=3 Destination Net Unreachable | ||
+ | |||
+ | --- 198.51.100.1 ping statistics --- | ||
+ | 3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2025ms | ||
+ | </pre> | ||
+ | ====ルーターにもルーティングエントリを追加==== | ||
+ | <pre> | ||
+ | $ sudo ip netns exec router1 ip route add 198.51.100.0/24 via 203.0.113.2 | ||
+ | $ sudo ip netns exec router2 ip route add 192.0.2.0/24 via 203.0.113.1 | ||
+ | </pre> | ||
+ | *ns1から、ns2へpingが通るようになった | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ping -c 3 198.51.100.1 | ||
+ | PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. | ||
+ | 64 bytes from 198.51.100.1: icmp_seq=1 ttl=62 time=0.093 ms | ||
+ | 64 bytes from 198.51.100.1: icmp_seq=2 ttl=62 time=0.158 ms | ||
+ | 64 bytes from 198.51.100.1: icmp_seq=3 ttl=62 time=0.155 ms | ||
+ | |||
+ | --- 198.51.100.1 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2030ms | ||
+ | rtt min/avg/max/mdev = 0.093/0.135/0.158/0.029 ms | ||
+ | </pre> | ||
+ | ====ルーティング==== | ||
+ | *手動でルーティングエントリを追加する方式:静的経路制御(スタティックルーティング) | ||
+ | *ルーター同士が自律的に自身が知っているルーティング情報を教え合う方式:動的経路制御(ダイナミックルーティング) | ||
+ | *ルーティング情報交換プロトコル:BGP(Border Gateway Protocol)やOSPF(Open Shortest Path First) | ||
+ | ==イーサネット== | ||
+ | *OSI参照モデルでは、データリンク層と物理層に対応、IPの下の階層 | ||
+ | *OSI参照モデルや、TCP/IPの階層構造を下から番号を振って呼ぶことがある例えば、IPなら下から3番目のためレイヤー3、イーサネットは一般的にレイヤー2と見做される | ||
+ | *イーサネットはIPを含む上位プロトコルのデータを運ぶ | ||
+ | *イーサネットではデータを運ぶ1単位をフレーム(Frame)という | ||
+ | *フレームの送信元、送信先の管理に使われるのが、MACアドレスとなり、イーサネットのフレームを受信する機器ごとに付与される | ||
+ | *MACアドレスは、48ビット空間(上位24ビットは製造ベンダー、下位24ビットはベンダーが一意になるよう割り振る)を持った整数値で、原則的には全世界で一意 | ||
+ | *MACアドレスの一意性は厳しくなく、仮想マシンのハイパーバイザーが動的に割り振ると、重複の可能性があるが、ブロードキャストドメインの中で重複しなければ問題ない | ||
+ | ===Network Namespaceの作成=== | ||
+ | <pre> | ||
+ | $ sudo ip netns add ns1 | ||
+ | $ sudo ip netns add ns2 | ||
+ | </pre> | ||
+ | *vethインターフェースの作成 | ||
+ | <pre> | ||
+ | $ sudo ip link add ns1-veth0 type veth peer name ns2-veth0 | ||
+ | </pre> | ||
+ | *インターフェースを所属させ、up | ||
+ | <pre> | ||
+ | $ sudo ip link set ns1-veth0 netns ns1 | ||
+ | $ sudo ip link set ns2-veth0 netns ns2 | ||
+ | $ sudo ip netns exec ns1 ip link set ns1-veth0 up | ||
+ | $ sudo ip netns exec ns2 ip link set ns2-veth0 up | ||
+ | </pre> | ||
+ | *IPアドレスの設定 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 | ||
+ | $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0 | ||
+ | </pre> | ||
+ | *MACアドレスの設定 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:01 | ||
+ | $ sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:02 | ||
+ | </pre> | ||
+ | *確認 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip link show | grep "link/ether" | ||
+ | link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff link-netns ns2 | ||
+ | $ sudo ip netns exec ns2 ip link show | grep "link/ether" | ||
+ | link/ether 00:00:5e:00:53:02 brd ff:ff:ff:ff:ff:ff link-netns ns1 | ||
+ | </pre> | ||
+ | *別ターミナルから、パケットキャプチャ準備 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes | ||
+ | </pre> | ||
+ | *ns1 から ns2 へping | ||
+ | <pre> | ||
+ | $ sudo 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.461 ms | ||
+ | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.196 ms | ||
+ | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.187 ms | ||
+ | |||
+ | --- 192.0.2.2 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2004ms | ||
+ | rtt min/avg/max/mdev = 0.187/0.281/0.461/0.127 ms | ||
+ | </pre> | ||
+ | *ダンプの内容を確認 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes | ||
+ | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37038, seq 1, length 64 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37038, seq 1, length 64 | ||
+ | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37038, seq 2, length 64 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37038, seq 2, length 64 | ||
+ | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37038, seq 3, length 64 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37038, seq 3, length 64 | ||
+ | </pre> | ||
+ | |||
+ | *どうやって、MACアドレスを知るのか?一旦、MACアドレスのキャッシュをクリア | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip neigh flush all | ||
+ | </pre> | ||
+ | *icmp だけでなく、arpもダンプ対象に加える | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp or arp | ||
+ | </pre> | ||
+ | *再度ping | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp or arp | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes | ||
+ | 00:00:5e:00:53:01 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.2 tell 192.0.2.1, length 28 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Reply 192.0.2.2 is-at 00:00:5e:00:53:02, length 28 | ||
+ | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37051, seq 1, length 64 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37051, seq 1, length 64 | ||
+ | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37051, seq 2, length 64 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37051, seq 2, length 64 | ||
+ | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37051, seq 3, length 64 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37051, seq 3, length 64 | ||
+ | 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.1 tell 192.0.2.2, length 28 | ||
+ | 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype ARP (0x0806), length 42: Reply 192.0.2.1 is-at 00:00:5e:00:53:01, length 28 | ||
+ | </pre> | ||
+ | ==ブリッジ== | ||
+ | *スイッチングハブを利用すると複数のネットワーク機器を同じブロードキャストドメインに接続できる | ||
+ | *スイッチングハブを一般化した用語がブリッジ | ||
+ | *ブリッジはデータリンク層でフレームを転送する | ||
+ | *ブリッジは自身のどのポートにどのMACアドレスの機器が接続されているかMACアドレステーブルを用いて管理する | ||
+ | *[[Linux]]にはブリッジの実装として、ネットワークブリッジという機能がある | ||
+ | |||
+ | *Network Namespaceを作成 | ||
+ | <pre> | ||
+ | $ sudo ip netns add ns1 | ||
+ | $ sudo ip netns add ns2 | ||
+ | $ sudo ip netns add ns3 | ||
+ | $ sudo ip netns add bridge | ||
+ | </pre> | ||
+ | *veth作成 | ||
+ | <pre> | ||
+ | $ sudo ip link add ns1-veth0 type veth peer name ns1-br0 | ||
+ | $ sudo ip link add ns2-veth0 type veth peer name ns2-br0 | ||
+ | $ sudo ip link add ns3-veth0 type veth peer name ns3-br0 | ||
+ | </pre> | ||
+ | *所属させる | ||
+ | <pre> | ||
+ | $ sudo ip link set ns1-veth0 netns ns1 | ||
+ | $ sudo ip link set ns2-veth0 netns ns2 | ||
+ | $ sudo ip link set ns3-veth0 netns ns3 | ||
+ | $ sudo ip link set ns1-br0 netns bridge | ||
+ | $ sudo ip link set ns2-br0 netns bridge | ||
+ | $ sudo ip link set ns3-br0 netns bridge | ||
+ | </pre> | ||
+ | *up | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip link set ns1-veth0 up | ||
+ | $ sudo ip netns exec ns2 ip link set ns2-veth0 up | ||
+ | $ sudo ip netns exec ns3 ip link set ns3-veth0 up | ||
+ | $ sudo ip netns exec bridge ip link set ns1-br0 up | ||
+ | $ sudo ip netns exec bridge ip link set ns3-br0 up | ||
+ | $ sudo ip netns exec bridge ip link set ns3-br0 up | ||
+ | </pre> | ||
+ | *Ip | ||
+ | <pre> | ||
+ | $ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 | ||
+ | $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0 | ||
+ | $ sudo ip netns exec ns3 ip address add 192.0.2.3/24 dev ns3-veth0 | ||
+ | </pre> | ||
+ | *bridge | ||
+ | <pre> | ||
+ | $ sudo ip netns exec bridge ip link add dev br0 type bridge | ||
+ | $ sudo ip netns exec bridge ip link set br0 up | ||
+ | </pre> | ||
+ | *ブリッジに接続 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec bridge ip link set ns1-br0 master br0 | ||
+ | $ sudo ip netns exec bridge ip link set ns2-br0 master br0 | ||
+ | $ sudo ip netns exec bridge ip link set ns3-br0 master br0 | ||
+ | </pre> | ||
+ | *ping : ns1 -> ns2 | ||
+ | <pre> | ||
+ | $ sudo 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.496 ms | ||
+ | 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.139 ms | ||
+ | 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.141 ms | ||
+ | |||
+ | --- 192.0.2.2 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2034ms | ||
+ | rtt min/avg/max/mdev = 0.139/0.258/0.496/0.167 ms | ||
+ | </pre> | ||
+ | *ping : ns1 -> ns3 | ||
+ | *ネットワークブリッジを介して3つのNetwork Namespaceが同じセグメントにつながった | ||
+ | <pre> | ||
+ | $ sudo 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. | ||
+ | 64 bytes from 192.0.2.3: icmp_seq=1 ttl=64 time=0.262 ms | ||
+ | 64 bytes from 192.0.2.3: icmp_seq=2 ttl=64 time=0.138 ms | ||
+ | 64 bytes from 192.0.2.3: icmp_seq=3 ttl=64 time=0.138 ms | ||
+ | |||
+ | --- 192.0.2.3 ping statistics --- | ||
+ | 3 packets transmitted, 3 received, 0% packet loss, time 2035ms | ||
+ | rtt min/avg/max/mdev = 0.138/0.179/0.262/0.058 ms | ||
+ | </pre> | ||
+ | ===ブリッジの削除=== | ||
+ | <pre> | ||
+ | # ip link set br100 down | ||
+ | # brctl delbr br100 | ||
+ | </pre> | ||
+ | |||
+ | ==トランスポート層プロトコル== | ||
+ | ===ポート=== | ||
+ | *OSが自動で割り当てるポートをエフェメラルポートという | ||
+ | *0~1023(システムポート、またはウェルノウンポート) | ||
+ | *1024~49151(ユーザポート、またはレジスタードポート) | ||
+ | *49152~65535(ダイナミックポート、またはプライベートポート) | ||
+ | ===UDP=== | ||
+ | ====nc(netcat)コマンド==== | ||
+ | ---- | ||
+ | *ループバックアドレスを使って、UDPの54321番ポートで、ncコマンドが通信を待ち受け | ||
+ | <pre> | ||
+ | $ nc -ulnv 127.0.0.1 54321 | ||
+ | Bound on 127.0.0.1 54321 | ||
+ | </pre> | ||
+ | *クライアントから接続してメッセージ | ||
+ | <pre> | ||
+ | $ nc -u 127.0.0.1 54321 | ||
+ | Hello World! | ||
+ | </pre> | ||
+ | |||
+ | *サーバーで確認 | ||
+ | *54928 は、エフェメラルポート | ||
+ | <pre> | ||
+ | $ nc -ulnv 127.0.0.1 54321 | ||
+ | Bound on 127.0.0.1 54321 | ||
+ | Connection received on 127.0.0.1 54928 | ||
+ | Hello World! | ||
+ | </pre> | ||
+ | |||
+ | *別ターミナルから、tcpdumpでやり取りを確認 | ||
+ | *パケットのペイロードはUDPダイアグラム | ||
+ | <pre> | ||
+ | $ sudo tcpdump -i lo -tnlA "udp and port 54321" | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes | ||
+ | IP 127.0.0.1.54928 > 127.0.0.1.54321: UDP, length 13 | ||
+ | E..)~.@.@..............1...(Hello World! | ||
+ | </pre> | ||
+ | ===TCP=== | ||
+ | *UDP同様アプリケーションをポートで区別 | ||
+ | *データ到達確認 | ||
+ | *破棄された場合、再送 | ||
+ | *データ到着順が入れ替わっても正しく並べ替え | ||
+ | *HTTPやSMTPなど数多くのプロトコルの下位プロトコル | ||
+ | *TCPでデータをやり取りする単位をセグメントという | ||
+ | *[https://milestone-of-se.nesuke.com/nw-basic/tcp-udp/tcp-format/ TCPパケットフォーマット] | ||
+ | ====TCPコネクションの確立==== | ||
+ | ---- | ||
+ | *サーバー | ||
+ | <pre> | ||
+ | $ nc -lnv 127.0.0.1 54321 | ||
+ | Listening on 127.0.0.1 54321 | ||
+ | Connection received on 127.0.0.1 53332 | ||
+ | </pre> | ||
+ | *キャプチャ | ||
+ | <pre> | ||
+ | sudo tcpdump -i lo -tnla "tcp and port 54321" | ||
+ | </pre> | ||
+ | *クライアント | ||
+ | <pre> | ||
+ | $ nc 127.0.0.1 54321 | ||
+ | </pre> | ||
+ | *クライアント接続で以下のダンプ | ||
+ | *TCPでやり取りを始める場合、以下のように3つのセグメントをやり取りする、このやり取りをスリーウェイハンドシェイクという | ||
+ | *スリーウェイハンドシェイクが完了するとTCPコネクションが確立されたとみなされる | ||
+ | *TCPセグメントを受信した側はACKの立ったセグメントを送り返すことで示す | ||
+ | *送信側はACKセグメントが返ってこない場合、同じセグメントを何度か送り直す | ||
+ | [[File:tcp_connection.png|200px]] | ||
+ | *Flagsの後の[]に囲まれた内容、S:SYN (synchronize sequence numbers), .:ACK(Acknowledgement field sgnificant) を表す | ||
+ | *シーケンス番号はTCPがデータの順序を管理するのに利用するフィールド | ||
+ | <pre> | ||
+ | $ sudo tcpdump -i lo -tnla "tcp and port 54321" | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes | ||
+ | IP 127.0.0.1.53332 > 127.0.0.1.54321: Flags [S], seq 478701324, win 65495, options [mss 65495,sackOK,TS val 3420633304 ecr 0,nop,wscale 7], length 0 | ||
+ | IP 127.0.0.1.54321 > 127.0.0.1.53332: Flags [S.], seq 795900871, ack 478701325, win 65483, options [mss 65495,sackOK,TS val 3420633304 ecr 3420633304,nop,wscale 7], length 0 | ||
+ | IP 127.0.0.1.53332 > 127.0.0.1.54321: Flags [.], ack 1, win 512, options [nop,nop,TS val 3420633304 ecr 3420633304], length 0 | ||
+ | </pre> | ||
+ | |||
+ | ====通信==== | ||
+ | ---- | ||
+ | *クライアントからメッセージ送信 | ||
+ | <pre> | ||
+ | $ nc 127.0.0.1 54321 | ||
+ | Hello World | ||
+ | </pre> | ||
+ | *サーバー側 | ||
+ | <pre> | ||
+ | $ nc -lnv 127.0.0.1 54321 | ||
+ | Listening on 127.0.0.1 54321 | ||
+ | Connection received on 127.0.0.1 53408 | ||
+ | Hello World | ||
+ | </pre> | ||
+ | *Dump | ||
+ | *セグメントの末尾に送信文字列が含まれている | ||
+ | *文字列を送っているセグメントには、Pというコントロールビットのフラグが立っている。これは、PSHで、Push Functionの略 | ||
+ | *サーバーからクライアントに送られているセグメントはデータを受け取ったことを伝えているackの後ろの数字は不足なく受け取れた最後のシーケンス番号(実際の値ではなく相対値) | ||
+ | <pre> | ||
+ | $ sudo tcpdump -i lo -tnlA "tcp and port 54321" | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes | ||
+ | IP 127.0.0.1.53408 > 127.0.0.1.54321: Flags [P.], seq 3792056963:3792056975, ack 4147605678, win 512, options [nop,nop,TS val 3677326932 ecr 3677294810], length 12 | ||
+ | E..@..@.@.!%...........1..2..7p......4..... | ||
+ | ./.T./..Hello World | ||
+ | |||
+ | IP 127.0.0.1.54321 > 127.0.0.1.53408: Flags [.], ack 12, win 512, options [nop,nop,TS val 3677326932 ecr 3677326932], length 0 | ||
+ | E..4..@.@.^..........1...7p...2......(..... | ||
+ | ./.T./.T | ||
+ | </pre> | ||
+ | ==アプリケーション層プロトコル== | ||
+ | *無数に存在 | ||
+ | *HTTP | ||
+ | *DNS | ||
+ | *DHCP | ||
+ | *など | ||
+ | ===HTTP=== | ||
+ | ---- | ||
+ | <pre> | ||
+ | $ mkdir http-home | ||
+ | $ cd http-home | ||
+ | $ cat << 'EOF' > index.html | ||
+ | > <!doctype html> | ||
+ | > <html> | ||
+ | > <head> | ||
+ | > <title>Hello, World</title> | ||
+ | > </head> | ||
+ | > <body> | ||
+ | > <h1>Hello, World</h1> | ||
+ | > </body> | ||
+ | > </html> | ||
+ | > EOF | ||
+ | </pre> | ||
+ | ====HTTPサーバー==== | ||
+ | [[Python]]のHTTPサーバーを起動 | ||
+ | <pre> | ||
+ | $ sudo python3 -m http.server -b 127.0.0.1 80 | ||
+ | Serving HTTP on 127.0.0.1 port 80 (http://127.0.0.1:80/) ... | ||
+ | </pre> | ||
+ | |||
+ | ====ncコマンドをブラウザとしてアクセス==== | ||
+ | <pre> | ||
+ | $ echo -en "GET / HTTP/1.0\r\n\r\n" | nc 127.0.0.1 80 | ||
+ | HTTP/1.0 200 OK | ||
+ | Server: SimpleHTTP/0.6 Python/3.8.10 | ||
+ | Date: Wed, 13 Apr 2022 11:56:03 GMT | ||
+ | Content-type: text/html | ||
+ | Content-Length: 127 | ||
+ | Last-Modified: Tue, 22 Mar 2022 15:07:11 GMT | ||
+ | |||
+ | <!doctype html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <title>Hello, World</title> | ||
+ | </head> | ||
+ | <body> | ||
+ | <h1>Hello, World</h1> | ||
+ | </body> | ||
+ | </html> | ||
+ | </pre> | ||
+ | ===DNS=== | ||
+ | ---- | ||
+ | *ドメイン名の解決はOSの中でリゾルバというプログラムが担当する | ||
+ | *リゾルバが問い合わせるDNSのサーバーをネームサーバーという | ||
+ | |||
+ | *確認 | ||
+ | **tcpdumpを起動 | ||
+ | <pre> | ||
+ | $ sudo tcpdump -tnl -i any "udp and port 53" | ||
+ | </pre> | ||
+ | *他のターミナルから | ||
+ | <pre> | ||
+ | $ dig +short @8.8.8.8 typea.info A | ||
+ | 160.16.110.88 | ||
+ | </pre> | ||
+ | *tcpdumpの結果を確認 | ||
+ | <pre> | ||
+ | tcpdump: verbose output suppressed, use -v or -vv for full protocol decode | ||
+ | listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes | ||
+ | IP 127.0.0.1.46121 > 127.0.0.53.53: 57838+ [1au] NS? . (40) | ||
+ | IP 192.168.122.243.55378 > 192.168.122.1.53: 22272+ [1au] NS? . (28) | ||
+ | IP 192.168.122.1.53 > 192.168.122.243.55378: 22272 13/0/1 NS c.root-servers.net., NS m.root-servers.net., NS a.root-servers.net., NS d.root-servers.net., NS l.root-servers.net., NS i.root-servers.net., NS k.root-servers.net., NS f.root-servers.net., NS b.root-servers.net., NS e.root-servers.net., NS j.root-servers.net., NS h.root-servers.net., NS g.root-servers.net. (239) | ||
+ | IP 127.0.0.53.53 > 127.0.0.1.46121: 57838 13/0/1 NS c.root-servers.net., NS m.root-servers.net., NS a.root-servers.net., NS d.root-servers.net., NS l.root-servers.net., NS i.root-servers.net., NS k.root-servers.net., NS f.root-servers.net., NS b.root-servers.net., NS e.root-servers.net., NS j.root-servers.net., NS h.root-servers.net., NS g.root-servers.net. (239) | ||
+ | IP 192.168.122.243.55943 > 8.8.8.8.53: 4489+ [1au] A? typea.info. (51) | ||
+ | IP 8.8.8.8.53 > 192.168.122.243.55943: 4489 1/0/1 A 160.16.110.88 (55) | ||
+ | </pre> | ||
+ | ===DHCP=== | ||
+ | ---- | ||
+ | <pre> | ||
+ | $ sudo ip netns add server | ||
+ | $ sudo ip netns add client | ||
+ | $ sudo ip link add s-veth0 type veth peer name c-veth | ||
+ | $ sudo ip link set s-veth0 netns server | ||
+ | $ sudo ip link set c-veth netns client | ||
+ | $ sudo ip netns exec server ip link set s-veth0 up | ||
+ | $ sudo ip netns exec client ip link set c-veth up | ||
+ | $ sudo ip netns exec server ip address add 192.0.2.254/24 dev s-veth0</pre> | ||
+ | |||
+ | *dhcp サーバーをserverで起動 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec server dnsmasq --dhcp-range=192.0.2.100,192.0.2.200,255.255.255.0 --interface=s-veth0 --port 0 --no-resolv --no-daemon | ||
+ | </pre> | ||
+ | |||
+ | *別ターミナルからDHCPサーバーを利用する | ||
+ | <pre> | ||
+ | $ sudo ip netns exec client dhclient -d c-veth | ||
+ | Internet Systems Consortium DHCP Client 4.4.1 | ||
+ | Copyright 2004-2018 Internet Systems Consortium. | ||
+ | All rights reserved. | ||
+ | For info, please visit https://www.isc.org/software/dhcp/ | ||
+ | |||
+ | Listening on LPF/c-veth/fa:e0:8a:cb:c5:19 | ||
+ | Sending on LPF/c-veth/fa:e0:8a:cb:c5:19 | ||
+ | Sending on Socket/fallback | ||
+ | DHCPDISCOVER on c-veth to 255.255.255.255 port 67 interval 3 (xid=0x47349475) | ||
+ | DHCPDISCOVER on c-veth to 255.255.255.255 port 67 interval 6 (xid=0x47349475) | ||
+ | DHCPOFFER of 192.0.2.131 from 192.0.2.254 | ||
+ | DHCPREQUEST for 192.0.2.131 on c-veth to 255.255.255.255 port 67 (xid=0x75943447) | ||
+ | DHCPACK of 192.0.2.131 from 192.0.2.254 (xid=0x47349475) | ||
+ | bound to 192.0.2.131 -- renewal in 1695 seconds. | ||
+ | </pre> | ||
+ | *一旦、DHCPクライアントを終了しIPアドレスを確認 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec client ip addr show | grep "inet" | ||
+ | inet 192.0.2.131/24 brd 192.0.2.255 scope global dynamic c-veth | ||
+ | inet6 fe80::f8e0:8aff:fecb:c519/64 scope link | ||
+ | </pre> | ||
+ | *ルーティングテーブルを確認 | ||
+ | <pre> | ||
+ | $ sudo ip netns exec client ip route show | ||
+ | default via 192.0.2.254 dev c-veth | ||
+ | 192.0.2.0/24 dev c-veth proto kernel scope link src 192.0.2.131 | ||
+ | </pre> |
2022年10月22日 (土) 15:58時点における最新版
TCP/IP
ipコマンド
基礎1
オブジェクト | 別名(省略形) | 意味 |
link | l | ネットワークデバイス |
addr | a、address | ネットワークデバイスのIPアドレス |
addrlabel | addrl | アドレスラベル |
route | r | ルーティングテーブルのエントリー |
rule | rul | ルーティングポリシーデータベースに登録されているルール |
neigh | n、neighbour | 近傍キャッシュエントリ(ARPまたはNDISCキャッシュエントリ) |
ntable | nt、ntb | 近傍キャッシュの管理テーブル |
tunnel | t | IPトンネル |
tuntap | tu | トンネルデバイス |
maddr | m、ma、mad | マルチキャストアドレス |
mroute | mr | マルチキャストルーティングのキャッシュエントリ |
mrule | mru | マルチキャストルーティングポリシーデータベースに登録されているルール |
monitor | mon | ネットリンクメッセージの監視 |
xfrm | x、xf | IPsecポリシー |
netns | net | ネットワーク名前空間 |
l2tp | l2 | L2TPv3(レイヤー2トンネリングプロトコル) |
tcp_metrics | tcp_m、tcp_metrics、tcpm | TCPメトリック |
token | tok | トークン |
基礎2
基礎3
応用
ip address show
- inet の後がIPアドレス
- lo,ens3 はネットワークインターフェース(NICや無線LANアダプタなどを抽象化)
- IPアドレスはネットワークインターフェースに付与される
- 127.0.0.1はループバックアドレスで、自分自身を表す
- ループバックアドレスが付与されているインターフェースはループバックインターフェース
$ ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:97:68:97 brd ff:ff:ff:ff:ff:ff inet 192.168.122.243/24 brd 192.168.122.255 scope global dynamic ens3 valid_lft 3189sec preferred_lft 3189sec inet6 fe80::5054:ff:fe97:6897/64 scope link valid_lft forever preferred_lft forever
tcpdump パケットキャプチャ
- -t : 時刻情報出力抑制
- -n : IP逆引きしない
- -i : 対象インターフェースを指定 anyで全て
- icmp : icmp プロトコルに限定
$ sudo tcpdump -tn -i any icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes IP 192.168.122.243 > 8.8.8.8: ICMP echo request, id 2, seq 1, length 64 IP 8.8.8.8 > 192.168.122.243: ICMP echo reply, id 2, seq 1, length 64 IP 192.168.122.243 > 8.8.8.8: ICMP echo request, id 2, seq 2, length 64 IP 8.8.8.8 > 192.168.122.243: ICMP echo reply, id 2, seq 2, length 64
traceroute
- パケット通過ルーター
- TTL : 0-255と解釈される値が入りパケット送出時にノードが初期値を設定、ルーター追加ごとに1つづつ値が減る。経路で値が0になるとルーターにより破棄されるが、この時ルーターは、ICMPで時間切れメッセージを送信元に送る
- TTLにあえて小さな値を設定し、TTLを1つづつ増やしたパケットを送信、時間切れをおこした通知を組み立てる
- 時間切れを通知しないルーター設定は、* となる
$ traceroute typea.info traceroute to typea.info (160.16.110.88), 64 hops max 1 192.168.122.1 0.343ms 0.288ms 0.301ms 2 192.168.0.1 0.694ms 0.492ms 0.487ms 3 210.173.146.32 4.710ms 4.013ms 3.784ms 4 210.173.145.69 3.968ms 4.044ms 4.072ms 5 210.173.150.97 3.557ms 4.091ms 3.896ms 6 210.171.224.113 9.550ms 7.866ms 8.150ms 7 * * * 8 * * * 9 * * * 10 * * * 11 160.16.110.88 11.148ms 12.124ms 12.150ms
ip route show ルーティングテーブル
- 複数のルーティングエントリから構成(それぞれの行)
- 先頭に宛先のIPアドレス
- 宛先に続くのがネクストホップ(パケットを次に渡す相手)
$ ip route show default via 192.168.122.1 dev ens3 proto dhcp src 192.168.122.243 metric 100 192.168.122.0/24 dev ens3 proto kernel scope link src 192.168.122.243 192.168.122.1 dev ens3 proto dhcp scope link src 192.168.122.243 metric 100
IPアドレス
- 32bitの前半をネットワーク部(ネットワークアドレス)、後半をホスト部(ホストアドレス)
- 192.0.2.1/24 24bitで分割 -> ネットワーク部 192.0.2.0、ホスト部 .1
- ネットワーク部は、ネットワークセグメントを表す、同じなら同じセグメントに属する
- 192.0.2.1/24 この書き方はCIDR表記と呼ばれる
- サブネット表記では、255.255.255.0
Network Namespace
$ sudo ip netns add helloworld $ ip netns list helloworld
- ip nets exec
- 指定したNetwork Namespace環境でコマンドを実行
$ sudo ip netns exec helloworld 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
- Network Namespaceでシェルも起動できる
$ sudo ip netns exec helloworld bash
ネットワークを作成して接続
2つのNetwork Namespaceを作成
$ sudo ip netns add ns1 $ sudo ip netns add ns2
- 接続するには、veth(Virtual Ethernet Device)を作成
- Nework Namespaceに所属させる
$ sudo ip link add 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 show 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4: ns1-veth0@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether ca:f0:3b:a9:2a:eb brd ff:ff:ff:ff:ff:ff link-netns ns2
IPアドレスを付与
$ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
- 確認
$ sudo ip netns exec ns1 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 4: ns1-veth0@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether ca:f0:3b:a9:2a:eb brd ff:ff:ff:ff:ff:ff link-netns ns2 inet 192.0.2.1/24 scope global ns1-veth0 valid_lft forever preferred_lft forever
vethを有効化
$ sudo ip netns exec ns1 ip link set ns1-veth0 up $ sudo ip netns exec ns2 ip link set ns2-veth0 up
- 疎通
$ sudo ip netns exec ns1 ping 192.0.2.2 -c 3 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.334 ms 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.101 ms 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.091 ms --- 192.0.2.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2051ms rtt min/avg/max/mdev = 0.091/0.175/0.334/0.112 ms
ルーターを介したネットワーク
Network Namespaceの構成
$ sudo ip netns add ns1 $ sudo ip netns add router $ sudo ip netns add route2 $ sudo ip netns add ns2
- それぞれのNetwork Namespaceを繋ぐvethインターフェースを作成
$ sudo ip link add ns1-veth0 type veth peer name gw-veth0 $ sudo ip link add ns2-veth0 type veth peer name gw-veth1
- vethをNetwork Namespaceに属させる
$ sudo ip link set ns1-veth0 netns ns1 $ sudo ip link set gw-veth0 netns router $ sudo ip link set gw-veth1 netns router $ sudo ip link set ns2-veth0 netns ns2
- vethをup
$ sudo ip netns exec ns1 ip link set ns1-veth0 up $ sudo ip netns exec router ip link set gw-veth0 up $ sudo ip netns exec router ip link set gw-veth1 up $ sudo ip netns exec ns2 ip link set ns2-veth0 up
- IPアドレスを付与
$ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 $ sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0 $ sudo ip netns exec router ip address add 198.51.100.254/24 dev gw-veth1 $ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
セグメント内の通信
- ns1 と ns2それぞれから、rouer にping
$ sudo ip netns exec ns1 ping -c 3 192.0.2.254 PING 192.0.2.254 (192.0.2.254) 56(84) bytes of data. 64 bytes from 192.0.2.254: icmp_seq=1 ttl=64 time=0.362 ms 64 bytes from 192.0.2.254: icmp_seq=2 ttl=64 time=0.102 ms 64 bytes from 192.0.2.254: icmp_seq=3 ttl=64 time=0.108 ms --- 192.0.2.254 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2049ms rtt min/avg/max/mdev = 0.102/0.190/0.362/0.121 ms $ sudo ip netns exec ns2 ping -c 3 198.51.100.254 PING 198.51.100.254 (198.51.100.254) 56(84) bytes of data. 64 bytes from 198.51.100.254: icmp_seq=1 ttl=64 time=0.314 ms 64 bytes from 198.51.100.254: icmp_seq=2 ttl=64 time=0.106 ms 64 bytes from 198.51.100.254: icmp_seq=3 ttl=64 time=0.110 ms --- 198.51.100.254 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2051ms rtt min/avg/max/mdev = 0.106/0.176/0.314/0.097 ms
- セグメントはこえられない
$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 ping: connect: Network is unreachable
ルーティングテーブルの確認と設定
- 確認
- 自身のセグメントしか表示されない
$ sudo ip netns exec ns1 ip route show 192.0.2.0/24 dev ns1-veth0 proto kernel scope link src 192.0.2.1
- デフォルトルート(他の宛先に一致しない場合)を追加、routerに向ける
$ sudo ip netns exec ns1 ip route add default via 192.0.2.254
- 追加された
$ sudo ip netns exec ns1 ip route show default via 192.0.2.254 dev ns1-veth0 192.0.2.0/24 dev ns1-veth0 proto kernel scope link src 192.0.2.1
- ns2にも同様に
$ sudo ip netns exec ns2 ip route add default via 198.51.100.254
- ns1 から ns2 へ再度 ping
- エラーとはならないが、パケットロス100%
$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. --- 198.51.100.1 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2039ms
- 以下の設定を実施
- sysctlでカーネルパラメータを設定(net.ipv4.ip_forward = 1 ルーターとして動作するかを設定)
$ sudo ip netns exec router sysctl net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1
- ルーターを介した接続成功
$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. 64 bytes from 198.51.100.1: icmp_seq=1 ttl=63 time=0.208 ms 64 bytes from 198.51.100.1: icmp_seq=2 ttl=63 time=0.114 ms 64 bytes from 198.51.100.1: icmp_seq=3 ttl=63 time=0.134 ms --- 198.51.100.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2032ms rtt min/avg/max/mdev = 0.114/0.152/0.208/0.040 ms
ルーターを増やす
- これまでの設定を削除
$ sudo ip --all netns delete $ sudo ip netns ls
Network Namespace作成
$ sudo ip netns add ns1 $ sudo ip netns add router1 $ sudo ip netns add router2 $ sudo ip netns add ns2
- veth作成
$ sudo ip link add ns1-veth0 type veth peer name gw1-veth0 $ sudo ip link add gw1-veth1 type veth peer name gw2-veth0 $ sudo ip link add gw2-veth1 type veth peer name ns2-veth0
- vethを所属させる
$ sudo ip link set ns1-veth0 netns ns1 $ sudo ip link set gw1-veth0 netns router1 $ sudo ip link set gw1-veth1 netns router1 $ sudo ip link set gw2-veth0 netns router2 $ sudo ip link set gw2-veth1 netns router2 $ sudo ip link set ns2-veth0 netns ns2
- up
$ sudo ip netns exec ns1 ip link set ns1-veth0 up $ sudo ip netns exec router1 ip link set gw1-veth0 up $ sudo ip netns exec router1 ip link set gw1-veth1 up $ sudo ip netns exec router2 ip link set gw2-veth0 up $ sudo ip netns exec router2 ip link set gw2-veth1 up $ sudo ip netns exec ns2 ip link set ns2-veth0 up
IP設定
$ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 $ sudo ip netns exec router1 ip address add 192.0.2.254/24 dev gw1-veth0 $ sudo ip netns exec router1 ip address add 203.0.113.1/24 dev gw1-veth1 $ sudo ip netns exec router2 ip address add 203.0.113.2/24 dev gw2-veth0 $ sudo ip netns exec router2 ip address add 198.51.100.254/24 dev gw2-veth1 $ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
- ns1,ns2 のデフォルトルートをルーターに向ける
$ sudo ip netns exec ns1 ip route add default via 192.0.2.254 $ sudo ip netns exec ns2 ip route add default via 198.51.100.254
- router1,route2のカーネルオプションを設定しルーターにする
$ sudo ip netns exec router1 sysctl net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1 $ sudo ip netns exec router2 sysctl net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1
- ns1から、ns2へpingを流すと、router1からパケットを届けることができなかったメッセージが帰る
$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. From 192.0.2.254 icmp_seq=1 Destination Net Unreachable From 192.0.2.254 icmp_seq=2 Destination Net Unreachable From 192.0.2.254 icmp_seq=3 Destination Net Unreachable --- 198.51.100.1 ping statistics --- 3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2025ms
ルーターにもルーティングエントリを追加
$ sudo ip netns exec router1 ip route add 198.51.100.0/24 via 203.0.113.2 $ sudo ip netns exec router2 ip route add 192.0.2.0/24 via 203.0.113.1
- ns1から、ns2へpingが通るようになった
$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 PING 198.51.100.1 (198.51.100.1) 56(84) bytes of data. 64 bytes from 198.51.100.1: icmp_seq=1 ttl=62 time=0.093 ms 64 bytes from 198.51.100.1: icmp_seq=2 ttl=62 time=0.158 ms 64 bytes from 198.51.100.1: icmp_seq=3 ttl=62 time=0.155 ms --- 198.51.100.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2030ms rtt min/avg/max/mdev = 0.093/0.135/0.158/0.029 ms
ルーティング
- 手動でルーティングエントリを追加する方式:静的経路制御(スタティックルーティング)
- ルーター同士が自律的に自身が知っているルーティング情報を教え合う方式:動的経路制御(ダイナミックルーティング)
- ルーティング情報交換プロトコル:BGP(Border Gateway Protocol)やOSPF(Open Shortest Path First)
イーサネット
- OSI参照モデルでは、データリンク層と物理層に対応、IPの下の階層
- OSI参照モデルや、TCP/IPの階層構造を下から番号を振って呼ぶことがある例えば、IPなら下から3番目のためレイヤー3、イーサネットは一般的にレイヤー2と見做される
- イーサネットはIPを含む上位プロトコルのデータを運ぶ
- イーサネットではデータを運ぶ1単位をフレーム(Frame)という
- フレームの送信元、送信先の管理に使われるのが、MACアドレスとなり、イーサネットのフレームを受信する機器ごとに付与される
- MACアドレスは、48ビット空間(上位24ビットは製造ベンダー、下位24ビットはベンダーが一意になるよう割り振る)を持った整数値で、原則的には全世界で一意
- MACアドレスの一意性は厳しくなく、仮想マシンのハイパーバイザーが動的に割り振ると、重複の可能性があるが、ブロードキャストドメインの中で重複しなければ問題ない
Network Namespaceの作成
$ sudo ip netns add ns1 $ sudo ip netns add ns2
- vethインターフェースの作成
$ sudo ip link add ns1-veth0 type veth peer name ns2-veth0
- インターフェースを所属させ、up
$ sudo ip link set ns1-veth0 netns ns1 $ sudo ip link set ns2-veth0 netns ns2 $ sudo ip netns exec ns1 ip link set ns1-veth0 up $ sudo ip netns exec ns2 ip link set ns2-veth0 up
- IPアドレスの設定
$ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
- MACアドレスの設定
$ sudo ip netns exec ns1 ip link set dev ns1-veth0 address 00:00:5E:00:53:01 $ sudo ip netns exec ns2 ip link set dev ns2-veth0 address 00:00:5E:00:53:02
- 確認
$ sudo ip netns exec ns1 ip link show | grep "link/ether" link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff link-netns ns2 $ sudo ip netns exec ns2 ip link show | grep "link/ether" link/ether 00:00:5e:00:53:02 brd ff:ff:ff:ff:ff:ff link-netns ns1
- 別ターミナルから、パケットキャプチャ準備
$ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
- ns1 から ns2 へping
$ sudo 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.461 ms 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.196 ms 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.187 ms --- 192.0.2.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2004ms rtt min/avg/max/mdev = 0.187/0.281/0.461/0.127 ms
- ダンプの内容を確認
$ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37038, seq 1, length 64 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37038, seq 1, length 64 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37038, seq 2, length 64 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37038, seq 2, length 64 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37038, seq 3, length 64 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37038, seq 3, length 64
- どうやって、MACアドレスを知るのか?一旦、MACアドレスのキャッシュをクリア
$ sudo ip netns exec ns1 ip neigh flush all
- icmp だけでなく、arpもダンプ対象に加える
$ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp or arp
- 再度ping
$ sudo ip netns exec ns1 tcpdump -tnel -i ns1-veth0 icmp or arp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ns1-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes 00:00:5e:00:53:01 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.2 tell 192.0.2.1, length 28 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Reply 192.0.2.2 is-at 00:00:5e:00:53:02, length 28 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37051, seq 1, length 64 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37051, seq 1, length 64 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37051, seq 2, length 64 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37051, seq 2, length 64 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype IPv4 (0x0800), length 98: 192.0.2.1 > 192.0.2.2: ICMP echo request, id 37051, seq 3, length 64 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype IPv4 (0x0800), length 98: 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 37051, seq 3, length 64 00:00:5e:00:53:02 > 00:00:5e:00:53:01, ethertype ARP (0x0806), length 42: Request who-has 192.0.2.1 tell 192.0.2.2, length 28 00:00:5e:00:53:01 > 00:00:5e:00:53:02, ethertype ARP (0x0806), length 42: Reply 192.0.2.1 is-at 00:00:5e:00:53:01, length 28
ブリッジ
- スイッチングハブを利用すると複数のネットワーク機器を同じブロードキャストドメインに接続できる
- スイッチングハブを一般化した用語がブリッジ
- ブリッジはデータリンク層でフレームを転送する
- ブリッジは自身のどのポートにどのMACアドレスの機器が接続されているかMACアドレステーブルを用いて管理する
- Linuxにはブリッジの実装として、ネットワークブリッジという機能がある
- Network Namespaceを作成
$ sudo ip netns add ns1 $ sudo ip netns add ns2 $ sudo ip netns add ns3 $ sudo ip netns add bridge
- veth作成
$ sudo ip link add ns1-veth0 type veth peer name ns1-br0 $ sudo ip link add ns2-veth0 type veth peer name ns2-br0 $ sudo ip link add ns3-veth0 type veth peer name ns3-br0
- 所属させる
$ sudo ip link set ns1-veth0 netns ns1 $ sudo ip link set ns2-veth0 netns ns2 $ sudo ip link set ns3-veth0 netns ns3 $ sudo ip link set ns1-br0 netns bridge $ sudo ip link set ns2-br0 netns bridge $ sudo ip link set ns3-br0 netns bridge
- up
$ sudo ip netns exec ns1 ip link set ns1-veth0 up $ sudo ip netns exec ns2 ip link set ns2-veth0 up $ sudo ip netns exec ns3 ip link set ns3-veth0 up $ sudo ip netns exec bridge ip link set ns1-br0 up $ sudo ip netns exec bridge ip link set ns3-br0 up $ sudo ip netns exec bridge ip link set ns3-br0 up
- Ip
$ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0 $ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0 $ sudo ip netns exec ns3 ip address add 192.0.2.3/24 dev ns3-veth0
- bridge
$ sudo ip netns exec bridge ip link add dev br0 type bridge $ sudo ip netns exec bridge ip link set br0 up
- ブリッジに接続
$ sudo ip netns exec bridge ip link set ns1-br0 master br0 $ sudo ip netns exec bridge ip link set ns2-br0 master br0 $ sudo ip netns exec bridge ip link set ns3-br0 master br0
- ping : ns1 -> ns2
$ sudo 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.496 ms 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.139 ms 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.141 ms --- 192.0.2.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2034ms rtt min/avg/max/mdev = 0.139/0.258/0.496/0.167 ms
- ping : ns1 -> ns3
- ネットワークブリッジを介して3つのNetwork Namespaceが同じセグメントにつながった
$ sudo 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. 64 bytes from 192.0.2.3: icmp_seq=1 ttl=64 time=0.262 ms 64 bytes from 192.0.2.3: icmp_seq=2 ttl=64 time=0.138 ms 64 bytes from 192.0.2.3: icmp_seq=3 ttl=64 time=0.138 ms --- 192.0.2.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2035ms rtt min/avg/max/mdev = 0.138/0.179/0.262/0.058 ms
ブリッジの削除
# ip link set br100 down # brctl delbr br100
トランスポート層プロトコル
ポート
- OSが自動で割り当てるポートをエフェメラルポートという
- 0~1023(システムポート、またはウェルノウンポート)
- 1024~49151(ユーザポート、またはレジスタードポート)
- 49152~65535(ダイナミックポート、またはプライベートポート)
UDP
nc(netcat)コマンド
- ループバックアドレスを使って、UDPの54321番ポートで、ncコマンドが通信を待ち受け
$ nc -ulnv 127.0.0.1 54321 Bound on 127.0.0.1 54321
- クライアントから接続してメッセージ
$ nc -u 127.0.0.1 54321 Hello World!
- サーバーで確認
- 54928 は、エフェメラルポート
$ nc -ulnv 127.0.0.1 54321 Bound on 127.0.0.1 54321 Connection received on 127.0.0.1 54928 Hello World!
- 別ターミナルから、tcpdumpでやり取りを確認
- パケットのペイロードはUDPダイアグラム
$ sudo tcpdump -i lo -tnlA "udp and port 54321" tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes IP 127.0.0.1.54928 > 127.0.0.1.54321: UDP, length 13 E..)~.@.@..............1...(Hello World!
TCP
- UDP同様アプリケーションをポートで区別
- データ到達確認
- 破棄された場合、再送
- データ到着順が入れ替わっても正しく並べ替え
- HTTPやSMTPなど数多くのプロトコルの下位プロトコル
- TCPでデータをやり取りする単位をセグメントという
- TCPパケットフォーマット
TCPコネクションの確立
- サーバー
$ nc -lnv 127.0.0.1 54321 Listening on 127.0.0.1 54321 Connection received on 127.0.0.1 53332
- キャプチャ
sudo tcpdump -i lo -tnla "tcp and port 54321"
- クライアント
$ nc 127.0.0.1 54321
- クライアント接続で以下のダンプ
- TCPでやり取りを始める場合、以下のように3つのセグメントをやり取りする、このやり取りをスリーウェイハンドシェイクという
- スリーウェイハンドシェイクが完了するとTCPコネクションが確立されたとみなされる
- TCPセグメントを受信した側はACKの立ったセグメントを送り返すことで示す
- 送信側はACKセグメントが返ってこない場合、同じセグメントを何度か送り直す
- Flagsの後の[]に囲まれた内容、S:SYN (synchronize sequence numbers), .:ACK(Acknowledgement field sgnificant) を表す
- シーケンス番号はTCPがデータの順序を管理するのに利用するフィールド
$ sudo tcpdump -i lo -tnla "tcp and port 54321" tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes IP 127.0.0.1.53332 > 127.0.0.1.54321: Flags [S], seq 478701324, win 65495, options [mss 65495,sackOK,TS val 3420633304 ecr 0,nop,wscale 7], length 0 IP 127.0.0.1.54321 > 127.0.0.1.53332: Flags [S.], seq 795900871, ack 478701325, win 65483, options [mss 65495,sackOK,TS val 3420633304 ecr 3420633304,nop,wscale 7], length 0 IP 127.0.0.1.53332 > 127.0.0.1.54321: Flags [.], ack 1, win 512, options [nop,nop,TS val 3420633304 ecr 3420633304], length 0
通信
- クライアントからメッセージ送信
$ nc 127.0.0.1 54321 Hello World
- サーバー側
$ nc -lnv 127.0.0.1 54321 Listening on 127.0.0.1 54321 Connection received on 127.0.0.1 53408 Hello World
- Dump
- セグメントの末尾に送信文字列が含まれている
- 文字列を送っているセグメントには、Pというコントロールビットのフラグが立っている。これは、PSHで、Push Functionの略
- サーバーからクライアントに送られているセグメントはデータを受け取ったことを伝えているackの後ろの数字は不足なく受け取れた最後のシーケンス番号(実際の値ではなく相対値)
$ sudo tcpdump -i lo -tnlA "tcp and port 54321" tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes IP 127.0.0.1.53408 > 127.0.0.1.54321: Flags [P.], seq 3792056963:3792056975, ack 4147605678, win 512, options [nop,nop,TS val 3677326932 ecr 3677294810], length 12 E..@..@.@.!%...........1..2..7p......4..... ./.T./..Hello World IP 127.0.0.1.54321 > 127.0.0.1.53408: Flags [.], ack 12, win 512, options [nop,nop,TS val 3677326932 ecr 3677326932], length 0 E..4..@.@.^..........1...7p...2......(..... ./.T./.T
アプリケーション層プロトコル
- 無数に存在
- HTTP
- DNS
- DHCP
- など
HTTP
$ mkdir http-home $ cd http-home $ cat << 'EOF' > index.html > <!doctype html> > <html> > <head> > <title>Hello, World</title> > </head> > <body> > <h1>Hello, World</h1> > </body> > </html> > EOF
HTTPサーバー
PythonのHTTPサーバーを起動
$ sudo python3 -m http.server -b 127.0.0.1 80 Serving HTTP on 127.0.0.1 port 80 (http://127.0.0.1:80/) ...
ncコマンドをブラウザとしてアクセス
$ echo -en "GET / HTTP/1.0\r\n\r\n" | nc 127.0.0.1 80 HTTP/1.0 200 OK Server: SimpleHTTP/0.6 Python/3.8.10 Date: Wed, 13 Apr 2022 11:56:03 GMT Content-type: text/html Content-Length: 127 Last-Modified: Tue, 22 Mar 2022 15:07:11 GMT <!doctype html> <html> <head> <title>Hello, World</title> </head> <body> <h1>Hello, World</h1> </body> </html>
DNS
- ドメイン名の解決はOSの中でリゾルバというプログラムが担当する
- リゾルバが問い合わせるDNSのサーバーをネームサーバーという
- 確認
- tcpdumpを起動
$ sudo tcpdump -tnl -i any "udp and port 53"
- 他のターミナルから
$ dig +short @8.8.8.8 typea.info A 160.16.110.88
- tcpdumpの結果を確認
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes IP 127.0.0.1.46121 > 127.0.0.53.53: 57838+ [1au] NS? . (40) IP 192.168.122.243.55378 > 192.168.122.1.53: 22272+ [1au] NS? . (28) IP 192.168.122.1.53 > 192.168.122.243.55378: 22272 13/0/1 NS c.root-servers.net., NS m.root-servers.net., NS a.root-servers.net., NS d.root-servers.net., NS l.root-servers.net., NS i.root-servers.net., NS k.root-servers.net., NS f.root-servers.net., NS b.root-servers.net., NS e.root-servers.net., NS j.root-servers.net., NS h.root-servers.net., NS g.root-servers.net. (239) IP 127.0.0.53.53 > 127.0.0.1.46121: 57838 13/0/1 NS c.root-servers.net., NS m.root-servers.net., NS a.root-servers.net., NS d.root-servers.net., NS l.root-servers.net., NS i.root-servers.net., NS k.root-servers.net., NS f.root-servers.net., NS b.root-servers.net., NS e.root-servers.net., NS j.root-servers.net., NS h.root-servers.net., NS g.root-servers.net. (239) IP 192.168.122.243.55943 > 8.8.8.8.53: 4489+ [1au] A? typea.info. (51) IP 8.8.8.8.53 > 192.168.122.243.55943: 4489 1/0/1 A 160.16.110.88 (55)
DHCP
$ sudo ip netns add server $ sudo ip netns add client $ sudo ip link add s-veth0 type veth peer name c-veth $ sudo ip link set s-veth0 netns server $ sudo ip link set c-veth netns client $ sudo ip netns exec server ip link set s-veth0 up $ sudo ip netns exec client ip link set c-veth up $ sudo ip netns exec server ip address add 192.0.2.254/24 dev s-veth0
- dhcp サーバーをserverで起動
$ sudo ip netns exec server dnsmasq --dhcp-range=192.0.2.100,192.0.2.200,255.255.255.0 --interface=s-veth0 --port 0 --no-resolv --no-daemon
- 別ターミナルからDHCPサーバーを利用する
$ sudo ip netns exec client dhclient -d c-veth Internet Systems Consortium DHCP Client 4.4.1 Copyright 2004-2018 Internet Systems Consortium. All rights reserved. For info, please visit https://www.isc.org/software/dhcp/ Listening on LPF/c-veth/fa:e0:8a:cb:c5:19 Sending on LPF/c-veth/fa:e0:8a:cb:c5:19 Sending on Socket/fallback DHCPDISCOVER on c-veth to 255.255.255.255 port 67 interval 3 (xid=0x47349475) DHCPDISCOVER on c-veth to 255.255.255.255 port 67 interval 6 (xid=0x47349475) DHCPOFFER of 192.0.2.131 from 192.0.2.254 DHCPREQUEST for 192.0.2.131 on c-veth to 255.255.255.255 port 67 (xid=0x75943447) DHCPACK of 192.0.2.131 from 192.0.2.254 (xid=0x47349475) bound to 192.0.2.131 -- renewal in 1695 seconds.
- 一旦、DHCPクライアントを終了しIPアドレスを確認
$ sudo ip netns exec client ip addr show | grep "inet" inet 192.0.2.131/24 brd 192.0.2.255 scope global dynamic c-veth inet6 fe80::f8e0:8aff:fecb:c519/64 scope link
- ルーティングテーブルを確認
$ sudo ip netns exec client ip route show default via 192.0.2.254 dev c-veth 192.0.2.0/24 dev c-veth proto kernel scope link src 192.0.2.131
© 2006 矢木浩人