TT Lab
はじめる
学ぶ 学習パス コース

ネットワーク基礎 — Linux VM で手を動かす

ルーター・DNS・ファイアウォール・NAT を備えた小さなネットワーク

TT Labで続きを見る

このラボはVM上で動きます

これまでの9つのラボを1つにまとめます。ネームスペースhome(ユーザー側)とdmz(サーバー側)の間にVM自身がルーターとして立ち、そのルーターがDNSサーバー・ファイアウォール・NATまで担当します。家庭用ルーター1台が行う仕事の縮小版です。60分のラボなので、時間を一度延長する必要があるかもしれません。作業内容はVMとともに消えるので、あらかじめ知っておいてください。

目標

2つのサブネットをつなぎ、名前でサーバーを見つけられるようにし、Webだけを通し、プライベートネットワークをインターネットに出し、その全部をパケットで確認したうえで、レポートとして残します。

なぜ重要なのか

ここまでは、一度に1つの層だけを見てきました。実際の障害は、複数の層が重なっています。名前は解決できるのにファイアウォールが遮断し、ファイアウォールは開いているのに戻る経路がない、というように。1つのネットワークを最初から最後まで構築したことのある人は、「つながらない」と聞いたとき、どの層から見るかの順序を持っています: リンク → アドレス → ネイバー → 経路 → 名前 → ポート → ファイアウォール → レスポンス。

ステップ

  1. ネームスペースhome・dmzと、vethhome0(home、10.40.1.10/24)↔r-home(ルート、10.40.1.1/24)、dmz0(dmz、10.40.2.10/24)↔r-dmz(ルート、10.40.2.1/24)を作成し、2つのネームスペースのデフォルトルートとルートのip_forwardを設定して、home→dmzのpingが通るようにしてください。
  2. /root/final/www/index.html を作成し、dmz内で10.40.2.10:80を待ち受けるWebサーバーを起動して(ログは /root/final/http.log)、homeからcurl http://10.40.2.10/が通るようにしてください。
  3. /etc/dnsmasq.d/lab.conf で、dnsmasqが10.40.1.1で待ち受けてweb.lab.internal→10.40.2.10を答え、残りは上流へ転送するようにし、/etc/netns/home/resolv.conf でhomeがそのサーバーを使うようにしてください。
  4. homeからcurl -si http://web.lab.internal/を実行したレスポンスを /root/final/byname.txt に保存してください。
  5. ルートにテーブルinet labfwとforwardフックのチェーン(ポリシーdrop)を作成し、established,relatedとhome→dmzのtcp dport 80だけを許可して、Webは通りpingは通らないようにしてください。
  6. テーブルip labnatに10.40.1.0/24のマスカレードを入れ、forwardにhome→uplinkのtcp dport { 80, 443 }を許可して、homeからcurl -sI http://archive.ubuntu.com/を実行した1行目を /root/final/internet.txt に保存してください。
  7. r-dmzでキャプチャしながらhomeからもう一度Webを取得し、10.40.1.10が10.40.2.10.80へ送ったSYNが見える出力を /root/final/capture.txt に保存してください。
  8. 全ルールを /root/final/ruleset.nft に保存し、/root/final/report.md に、home_ip=・dmz_ip=・dns=・ping_blocked=の4行と、「web.lab.internalが開かない」という報告を受けたときにどの順序で調べるかを書いてください。

参考

2つのサブネットとルーター

ネームスペースhome・dmzと、vethhome0(home、10.40.1.10/24)↔r-home(ルート、10.40.1.1/24)、dmz0(dmz、10.40.2.10/24)↔r-dmz(ルート、10.40.2.1/24)を作成し、2つのネームスペースのデフォルトルートとルートのip_forwardを設定して、home→dmzのpingが通るようにしてください。

8つ目のラボのステップ1を2回行います。vethのr-側は、ルートに残します。ip -n home route add default via 10.40.1.1、ip -n dmz route add default via 10.40.2.1、sysctl -w net.ipv4.ip_forward=1。

DMZのWebサーバー

/root/final/www/index.html を作成し、dmz内で10.40.2.10:80を待ち受けるWebサーバーを起動して(ログは /root/final/http.log)、homeからcurl http://10.40.2.10/が通るようにしてください。

ip netns exec dmz setsid python3 -m http.server 80 --bind 10.40.2.10 --directory /root/final/www > /root/final/http.log 2>&1 < /dev/null &。index.htmlにdmzという語を入れておくと、あとでレスポンスを区別しやすくなります。

ルーターがDNSも担当する

/etc/dnsmasq.d/lab.conf で、dnsmasqが10.40.1.1で待ち受けてweb.lab.internal→10.40.2.10を答え、残りは上流へ転送するようにし、/etc/netns/home/resolv.conf でhomeがそのサーバーを使うようにしてください。

4つ目のラボの設定にserver=<상류>(プレースホルダーは上流のアドレスです)を加え、no-resolvはそのままにします(上流をresolv.confから読まず、この行から読むという意味です)。systemctl restart dnsmasqを実行します。/etc/netns/home/resolv.confにnameserver 10.40.1.1を書きます。確認: ip netns exec home getent hosts web.lab.internal。

名前で開く

homeからcurl -si http://web.lab.internal/を実行したレスポンスを /root/final/byname.txt に保存してください。

ip netns exec home curl -si -m 3 http://web.lab.internal/ > /root/final/byname.txt。-iはヘッダーまで出力します。200 OKとindex.htmlの内容が表示されている必要があります。

Webだけ通す

ルートにテーブルinet labfwとforwardフックのチェーン(ポリシーdrop)を作成し、established,relatedとhome→dmzのtcp dport 80だけを許可して、Webは通りpingは通らないようにしてください。

nft add table inet labfw; nft 'add chain inet labfw forward { type filter hook forward priority 0; policy drop; }'を実行します。ルールは2つ: ct state established,related accept、iifname "r-home" oifname "r-dmz" tcp dport 80 accept。これでhomeのpingはタイムアウト、curlは200になる必要があります。

家の中をインターネットへ

テーブルip labnatに10.40.1.0/24のマスカレードを入れ、forwardにhome→uplinkのtcp dport { 80, 443 }を許可して、homeからcurl -sI http://archive.ubuntu.com/を実行した1行目を /root/final/internet.txt に保存してください。

8つ目のラボのステップ3のとおりです(ip saddr 10.40.1.0/24 oifname "enp1s0" counter masquerade)。そしてforwardにiifname "r-home" oifname "enp1s0" tcp dport { 80, 443 } acceptを追加します。DNSはルーター自身(dnsmasq)が答えるので、forwardを通りません。

パケットで確認

r-dmzでキャプチャしながらhomeからもう一度Webを取得し、10.40.1.10が10.40.2.10.80へ送ったSYNが見える出力を /root/final/capture.txt に保存してください。

timeout 5 tcpdump -i r-dmz -nn -l 'tcp port 80' > /root/final/capture.txt 2>&1 &のあと、ip netns exec home curl -s http://web.lab.internal/を実行します。10.40.1.10.<포트> > 10.40.2.10.80: Flags [S]の行がある必要があります(プレースホルダーはポート番号です)。送信元がそのままであることを確認してください。内側どうしの間にはNATがありません。

ルールとレポート

全ルールを /root/final/ruleset.nft に保存し、/root/final/report.md に、home_ip=・dmz_ip=・dns=・ping_blocked=の4行と、「web.lab.internalが開かない」という報告を受けたときにどの順序で調べるかを書いてください。

nft list ruleset > /root/final/ruleset.nft。レポートの4つの値は、10.40.1.10、10.40.2.10、10.40.1.1、yesです。順序には、名前(getent)・経路(ip route get)・ファイアウォール(nft counter)・ポート(ss)を含める必要があります。