ネームスペース3つでルーターを作る
このラボはVM上で動きます
3つのネームスペース(ホストh1、ルーターr1、ホストh2)を、vethペア2組でつなぎます。サブネットの異なる2台のホストがルーターを経由して通信する、最も小さなネットワークです。
目標
ルーティングテーブルを読み、デフォルトルートと静的ルートを設定し、1台のLinuxをルーターに変えるスイッチ(ip_forward)が何を変えるのかを確認します。
なぜ重要なのか
「あるアドレス帯だけつながらない」という報告は、ほぼいつもルーティングです。ところがルーティングは両側が合っていて初めて成立します。行きの道があっても帰りの道がなければ同じようにつながらず、症状は区別できません。そしてLinuxは、デフォルトでは他のホスト宛てのパケットを転送しません。ip_forwardの1行がホストをルーターに変えるのですが、Kubernetesのノード・Dockerホスト・VPNサーバーは、すべてこの1行の上に成り立っています。
ステップ
- ネームスペース
h1・r1・h2を作成し、vethペアh1r↔rh1とh2r↔rh2を作って、h1rはh1に、h2rはh2に、rh1・rh2はr1に入れてください。 h1rに10.20.1.10/24、rh1に10.20.1.1/24、rh2に10.20.2.1/24、h2rに10.20.2.10/24を付け、すべてのインターフェースとloをUPにしてください。h1からh2(10.20.2.10)へpingして、失敗メッセージを/root/route/unreach.txtに保存してください。h1とh2に、それぞれのルーターのアドレスをデフォルトルートとして入れてください。r1のnet.ipv4.ip_forwardを1にして、h1→h2のpingが通るようにしてください。h1からh2へtraceroute -nを実行した結果を/root/route/trace.txtに保存してください。h2にダミーインターフェースsvc0を作成して10.99.0.10/24を付け、r1に10.99.0.0/24 via 10.20.2.10の静的ルートを入れて、h1から10.99.0.10に届くようにしてください。/root/route/report.mdに、hops=の1行、h1でのip route get 10.99.0.10の結果1行、そしてip_forwardがないとなぜ通らないのかを書いてください。
参考
- インターフェースが4つあるので、コマンドが多くなります。シェルのfor文を使ってください。
ip -n h1 route add default via 10.20.1.1。ゲートウェイは必ずh1と同じサブネットでなければなりません。ip netns exec r1 sysctl -w net.ipv4.ip_forward=1。値はネームスペースごとに別です。ip route get <주소>は、テーブルを目で読む代わりに、カーネルに「この宛先はどこへ出ていくか」を直接尋ねます(プレースホルダーはアドレスです)。- よくある間違い: ステップ4でh2のデフォルトルートを入れ忘れることです。行きの道はあるのに、答えが戻ってこられません。
3つをつなぐ
ネームスペースh1・r1・h2を作成し、vethペアh1r↔rh1とh2r↔rh2を作って、h1rはh1に、h2rはh2に、rh1・rh2はr1に入れてください。
ip link add h1r type veth peer name rh1のようにペアを2つ作成し、ip link set <이름> netns <ns>で移します(プレースホルダーは名前とネームスペース名です)。ルーターはインターフェースを2つ持つというのが核心です。片方の脚が1つのサブネットにかかります。
アドレスを付ける
h1rに10.20.1.10/24、rh1に10.20.1.1/24、rh2に10.20.2.1/24、h2rに10.20.2.10/24を付け、すべてのインターフェースとloをUPにしてください。
ip -n h1 addr add 10.20.1.10/24 dev h1rの要領で4つ付けます。そのあと6つのインターフェース(vethが4つ+loが3つ)をlink set … upで上げます。確認はip netns exec h1 ping -c1 10.20.1.1です。同じサブネットのルーターまでは、すでに届くはずです。
道がなければ
h1からh2(10.20.2.10)へpingして、失敗メッセージを /root/route/unreach.txt に保存してください。
ip netns exec h1 ping -c 1 -W 1 10.20.2.10 > /root/route/unreach.txt 2>&1。エラーは標準エラー出力に出るので、2>&1を忘れないでください。まだデフォルトルートがないので、Network is unreachableになるはずです。
デフォルトルート
h1とh2に、それぞれのルーターのアドレスをデフォルトルートとして入れてください。
ip -n h1 route add default via 10.20.1.1、ip -n h2 route add default via 10.20.2.1。両方入れる必要があります。片方だけだと、リクエストは届くのに、レスポンスが戻る道がありません。
ルーターにする
r1のnet.ipv4.ip_forwardを1にして、h1→h2のpingが通るようにしてください。
ip netns exec r1 sysctl -w net.ipv4.ip_forward=1。この値が0だと、カーネルは自分宛てでないパケットを静かに捨てます。ネームスペースごとに別の値です。
経路をたどってみる
h1からh2へtraceroute -nを実行した結果を /root/route/trace.txt に保存してください。
ip netns exec h1 traceroute -n -w 1 10.20.2.10 > /root/route/trace.txt。1ホップ目がルーター(10.20.1.1)、2ホップ目がh2になっている必要があります。-nは名前解決をオフにするオプションです。
静的ルート
h2にダミーインターフェースsvc0を作成して10.99.0.10/24を付け、r1に10.99.0.0/24 via 10.20.2.10の静的ルートを入れて、h1から10.99.0.10に届くようにしてください。
h2側: ip -n h2 link add svc0 type dummy、addr add 10.99.0.10/24 dev svc0、link set svc0 up。r1側: ip -n r1 route add 10.99.0.0/24 via 10.20.2.10。h1はデフォルトルートでr1に任せるので、手を加えるところはありません。
学んだこと
/root/route/report.md に、hops=の1行、h1でのip route get 10.99.0.10の結果1行、そしてip_forwardがないとなぜ通らないのかを書いてください。
hopsはステップ6のtracerouteのホップ数です。ip netns exec h1 ip route get 10.99.0.10の最初の行をそのまま貼り付けてください(via 10.20.1.1が見えます)。説明には、ip_forwardという語を含める必要があります。