1台のLinuxシステム内部に「仮想ルーター」と「仮想ホスト」という完全に独立した2つの仮想的なネットワーク空間を構築し、それらの間を「vethペア」と呼ばれる仮想LANケーブルで直結して通信を行う仕組みを見てみる。
まず、システムの初期化を行った後、ip netns add コマンドによってネットワーク環境が隔離された2つの空間を作成。次に、ip link add コマンドで両端にプラグを持つ1本の仮想LANケーブルを用意し、それぞれの端を先ほど作ったルーターとホストの空間へ別々に所属させることで物理的な有線接続と同じ状態を再現する。
接続を確立した後は、それぞれの部屋にログインするような形で ip addr add コマンドを実行し、ルーター側とホスト側にそれぞれ固有のIPアドレスを割り当ててインターフェースを有効化する。このとき、家庭内などの閉じられたローカルネットワークで自由に使用できるプライベートIPアドレスが採用され、仮想ルーター側には 192.168.10.1、仮想ホスト側には 192.168.10.2 という固有のアドレスがそれぞれの機器に登録される。
同時に、ホスト側には自分以外のネットワークへ通信する際の出口としてルーターの住所である 192.168.10.1 を指定する経路設定を書き込む。
この192.168.〜から始まる数字は、プライベートIPアドレスと呼ばれるもので、家庭内や社内などの閉じられたローカルなネットワークで自由に使ってよい決まりになっている。
最後に、ホストの空間からルーターのIPアドレスである 192.168.10.1 に向けて ping コマンドによるパケットを送信し、仮想LANケーブルを通じて2つの空間でデータが正常に往復できることを確認してネットワークの開通テストを完了させている。
まず、net_test.shというファイルを新規に作成する。今回作成する net_test.sh の中身には、1行目に、このファイルは Bash で動かしてください、という指定(#!/bin/bash)が書き込まれる。
cat << 'EOF' > net_test.sh
#!/bin/bash
# 1. クリーンアップ
echo "=== 1. クリーンアップを実行中 ==="
sudo ip netns del ns_router 2>/dev/null
sudo ip netns del ns_host 2>/dev/null
sudo ip link del veth_r 2>/dev/null
# 2. 仮想ルーターと仮想ホストの作成
echo "=== 2. 仮想ルーターと仮想ホストの作成 ==="
sudo ip netns add ns_router
sudo ip netns add ns_host
# 3. 仮想LANケーブル(vethペア)の接続
echo "=== 3. 仮想LANケーブル(vethペア)の接続 ==="
sudo ip link add veth_r type veth peer name veth_h
sudo ip link set veth_r netns ns_router
sudo ip link set veth_h netns ns_host
# 4. ネットワーク設定(IP割り当てと起動)
echo "=== 4. ネットワーク設定(IP割り当てと起動) ==="
sudo ip netns exec ns_router ip addr add 192.168.10.1/24 dev veth_r
sudo ip netns exec ns_router ip link set veth_r up
sudo ip netns exec ns_router ip link set lo up
sudo ip netns exec ns_host ip addr add 192.168.10.2/24 dev veth_h
sudo ip netns exec ns_host ip link set veth_h up
sudo ip netns exec ns_host ip link set lo up
sudo ip netns exec ns_host ip route add default via 192.168.10.1
# 5. 接続テスト
echo "=== 5. 接続テストを実行 ==="
sudo ip netns exec ns_host ping -c 3 192.168.10.1
EOF
なお、2>/dev/null は、削除が成功したときの通常のログ(1)は画面に出し、もし空間がなくて削除に失敗したときのエラー(2)が発生した場合は、それは画面に出さずに /dev/null(ゴミ箱)へということを意味している。/dev/null は、Linuxシステムに用意されている「投げ込まれたデータをすべて完全に消去して、何も出力しない」という特殊な空のファイル。
次に、作成したnet_test.shというスクリプトを実行する。
bash net_test.sh
実行結果は、
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.039 ms
--- 192.168.10.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2046ms
Mathematics is the language with which God has written the universe.