1 はじめに
ネームスペースを使って、ホストールーターホストの環境を構築してみます。
ip netnsコマンドの基本的な使い方は、以下を参照ください。
ip netnsコマンドの使い方(ネットワークの実験の幅が広がるなぁ~) - hana_shinのLinux技術ブログ
2 検証環境
CentOS版数は以下のとおりです。
[root@server ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)
カーネル版数は以下のとおりです。
[root@server ~]# uname -r 3.10.0-1160.el7.x86_64
3 構築する環境
ルータにホストが2台接続する環境を仮想マシンに構築してみます。
+-- host1 --+ +--- router ---+ +-- host2 --+ | | 192.168.100.0/24 | | 192.168.200.0/24 | | | veth1-h1 ------------------ veth2-rt veth3-rt ------------------ veth1-h2 | | | .10 .20 | | .20 .10 | | +-----------+ +--------------+ +-----------+
4 構築手順
4.1 ホストの作成
ホストを2つ作成します。
[root@server ~]# ip netns add host1 [root@server ~]# ip netns add host2
4.2 ルータの作成
ルータを1つ作成します。
[root@server ~]# ip netns add router
ネームスペースを確認します。ホストとルータが追加されたことがわかります。
[root@server ~]# ip netns list router host2 host1
4.3 ポートの作成
ホストとルータに接続するポートを作成します。
[root@server ~]# ip link add name veth1-h1 type veth peer name veth2-rt [root@server ~]# ip link add name veth1-h2 type veth peer name veth3-rt
4.4 ポートの接続
作成したポートをホスト1に接続します。
[root@server ~]# ip link set veth1-h1 netns host1
作成したポートをホスト2に接続します。
[root@server ~]# ip link set veth1-h2 netns host2
作成したポートをルータに接続します。
[root@server ~]# ip link set veth2-rt netns router [root@server ~]# ip link set veth3-rt netns router
4.5 IPアドレスの設定
ホスト1のポートにIPアドレスを設定します。
[root@server ~]# ip netns exec host1 ip addr add 192.168.100.10/24 dev veth1-h1
ホスト2のポートにIPアドレスを設定します。
[root@server ~]# ip netns exec host2 ip addr add 192.168.200.10/24 dev veth1-h2
ルータのポートにIPアドレスを設定します。
[root@server ~]# ip netns exec router ip addr add 192.168.100.20/24 dev veth2-rt [root@server ~]# ip netns exec router ip addr add 192.168.200.20/24 dev veth3-rt
4.6 ポートのリンクアップ
ホスト1のポートをリンクアップします。
[root@server ~]# ip netns exec host1 ip link set veth1-h1 up [root@server ~]# ip netns exec host1 ip link set lo up
ホスト2のポートをリンクアップします。
[root@server ~]# ip netns exec host2 ip link set veth1-h2 up [root@server ~]# ip netns exec host2 ip link set lo up
ルータのポートをリンクアップします。
[root@server ~]# ip netns exec router ip link set veth2-rt up [root@server ~]# ip netns exec router ip link set veth3-rt up [root@server ~]# ip netns exec router ip link set lo up
4.7 ルーティングテーブルの設定
ルータにルーティングテーブルを設定します。
[root@server ~]# ip netns exec host1 ip route add 192.168.200.0/24 via 192.168.100.20 dev veth1-h1 [root@server ~]# ip netns exec host2 ip route add 192.168.100.0/24 via 192.168.200.20 dev veth1-h2
4.8 ルーティングの有効化
ルーティングを有効化します。
[root@server ~]# ip netns exec router sysctl -w net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1
5 設定内容の確認
5.1 IPアドレスの確認
ホスト1のIPアドレスを確認します。
[root@server ~]# ip netns exec host1 ip a 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 4: veth1-h1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 36:5d:1c:41:41:0e brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet 192.168.100.10/24 scope global veth1-h1 valid_lft forever preferred_lft forever inet6 fe80::345d:1cff:fe41:410e/64 scope link valid_lft forever preferred_lft forever
ホスト2のIPアドレスを確認します。
[root@server ~]# ip netns exec host2 ip a 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 6: veth1-h2@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 02:84:23:df:85:c5 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet 192.168.200.10/24 scope global veth1-h2 valid_lft forever preferred_lft forever inet6 fe80::84:23ff:fedf:85c5/64 scope link valid_lft forever preferred_lft forever
ルータのIPアドレスを確認します。
[root@server ~]# ip netns exec router ip a 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 3: veth2-rt@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 1e:d0:cf:6d:34:4c brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.100.20/24 scope global veth2-rt valid_lft forever preferred_lft forever inet6 fe80::1cd0:cfff:fe6d:344c/64 scope link valid_lft forever preferred_lft forever 5: veth3-rt@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 02:25:3f:6b:a1:7d brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet 192.168.200.20/24 scope global veth3-rt valid_lft forever preferred_lft forever inet6 fe80::25:3fff:fe6b:a17d/64 scope link valid_lft forever preferred_lft forever
5.2 ルーティングテーブルの確認
ルータのルーティングテーブルを確認します。
[root@server ~]# ip netns exec router ip r 192.168.100.0/24 dev veth2-rt proto kernel scope link src 192.168.100.20 192.168.200.0/24 dev veth3-rt proto kernel scope link src 192.168.200.20
6 動作確認
host1に入ります。これをターミナル1と呼びます。
[root@server ~]# ip netns exec host1 bash
もう1つターミナルをオープンします。これをターミナル2と呼びます。そして、ルータに入ります。
[root@server ~]# ip netns exec router bash
ターミナル2で、tcpdumpを実行してパケットの流れを確認してみます。パケットキャプチャに使用できるインタフェースを確認します。本手順で作成したインタフェース(veth2-rt,veth3-rt)が、インタフェースに指定できることがわかります。なお、tcpdumpの使い方は、tcpdumpの使い方(基本編) - hana_shinのLinux技術ブログを参照してください。
[root@server ~]# tcpdump -D 1.nflog (Linux netfilter log (NFLOG) interface) 2.nfqueue (Linux netfilter queue (NFQUEUE) interface) 3.usbmon1 (USB bus number 1) 4.veth2-rt 5.usbmon2 (USB bus number 2) 6.veth3-rt 7.any (Pseudo-device that captures on all interfaces) 8.lo [Loopback]
ターミナル1で、host1からhost2に対してpingを実行してみます。host2から応答があることがわかります。
[root@server ~]# ping -c 1 192.168.200.10 PING 192.168.200.10 (192.168.200.10) 56(84) bytes of data. 64 bytes from 192.168.200.10: icmp_seq=1 ttl=63 time=0.125 ms --- 192.168.200.10 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.125/0.125/0.125/0.000 ms
次に、tcpdumpの実行結果を確認します。ホスト1とホスト2でやりとりするICMPパケットを確認することができます。
[root@server ~]# tcpdump -i veth3-rt icmp -nn tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on veth3-rt, link-type EN10MB (Ethernet), capture size 262144 bytes 20:24:27.284258 IP 192.168.100.10 > 192.168.200.10: ICMP echo request, id 21990, seq 1, length 64 20:24:27.284318 IP 192.168.200.10 > 192.168.100.10: ICMP echo reply, id 21990, seq 1, length 64
7 環境構築用シェルスクリプト
今まで説明した手順をシェルスクリプトに記述して、環境構築/削除の自動化をしてみたいと思います。
7.1 構築
環境を構築するスクリプトです。
[root@server ~]# cat build.sh #!/usr/bin/bash ip netns add host1 ip netns add host2 ip netns add router ip link add name veth1-h1 type veth peer name veth2-rt ip link add name veth1-h2 type veth peer name veth3-rt ip link set veth1-h1 netns host1 ip link set veth1-h2 netns host2 ip link set veth2-rt netns router ip link set veth3-rt netns router ip netns exec host1 ip addr add 192.168.100.10/24 dev veth1-h1 ip netns exec host2 ip addr add 192.168.200.10/24 dev veth1-h2 ip netns exec router ip addr add 192.168.100.20/24 dev veth2-rt ip netns exec router ip addr add 192.168.200.20/24 dev veth3-rt ip netns exec host1 ip link set veth1-h1 up ip netns exec host1 ip link set lo up ip netns exec host2 ip link set veth1-h2 up ip netns exec host2 ip link set lo up ip netns exec router ip link set veth2-rt up ip netns exec router ip link set veth3-rt up ip netns exec router ip link set lo up ip netns exec host1 ip route add 192.168.200.0/24 via 192.168.100.20 dev veth1-h1 ip netns exec host2 ip route add 192.168.100.0/24 via 192.168.200.20 dev veth1-h2 ip netns exec router sysctl -w net.ipv4.ip_forward=1
シェルを実行して環境を構築する。
[root@server ~]# ./build.sh
host1からhost2に対してpingを実行します。host2から応答があることがわかります。
[root@server ~]# ping -c 1 192.168.200.10 PING 192.168.200.10 (192.168.200.10) 56(84) bytes of data. 64 bytes from 192.168.200.10: icmp_seq=1 ttl=63 time=0.087 ms --- 192.168.200.10 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.087/0.087/0.087/0.000 ms
7.2 削除
環境を削除するスクリプトです。
[root@server ~]# cat del.sh #!/usr/bin/bash ip netns exec host1 ip link set veth1-h1 down ip netns exec host1 ip link set lo down ip netns exec host2 ip link set veth1-h2 down ip netns exec host2 ip link set lo down ip netns exec router ip link set veth2-rt down ip netns exec router ip link set veth3-rt down ip netns exec router ip link set lo down ip netns delete host1 ip netns delete host2 ip netns delete router
シェルを実行して環境を削除する。
[root@server ~]# ./del.sh
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ