ルーター・DNS・ファイアウォール・NAT を備えた小さなネットワーク
このラボはVM上で動きます
これまでの9つのラボを1つにまとめます。ネームスペースhome(ユーザー側)とdmz(サーバー側)の間にVM自身がルーターとして立ち、そのルーターがDNSサーバー・ファイアウォール・NATまで担当します。家庭用ルーター1台が行う仕事の縮小版です。60分のラボなので、時間を一度延長する必要があるかもしれません。作業内容はVMとともに消えるので、あらかじめ知っておいてください。
目標
2つのサブネットをつなぎ、名前でサーバーを見つけられるようにし、Webだけを通し、プライベートネットワークをインターネットに出し、その全部をパケットで確認したうえで、レポートとして残します。
なぜ重要なのか
ここまでは、一度に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が通るようにしてください。 /root/final/www/index.htmlを作成し、dmz内で10.40.2.10:80を待ち受けるWebサーバーを起動して(ログは/root/final/http.log)、homeからcurl http://10.40.2.10/が通るようにしてください。/etc/dnsmasq.d/lab.confで、dnsmasqが10.40.1.1で待ち受けてweb.lab.internal→10.40.2.10を答え、残りは上流へ転送するようにし、/etc/netns/home/resolv.confでhomeがそのサーバーを使うようにしてください。homeからcurl -si http://web.lab.internal/を実行したレスポンスを/root/final/byname.txtに保存してください。- ルートにテーブル
inet labfwとforwardフックのチェーン(ポリシーdrop)を作成し、established,relatedとhome→dmzのtcp dport 80だけを許可して、Webは通りpingは通らないようにしてください。 - テーブル
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に保存してください。 r-dmzでキャプチャしながらhomeからもう一度Webを取得し、10.40.1.10が10.40.2.10.80へ送ったSYNが見える出力を/root/final/capture.txtに保存してください。- 全ルールを
/root/final/ruleset.nftに保存し、/root/final/report.mdに、home_ip=・dmz_ip=・dns=・ping_blocked=の4行と、「web.lab.internalが開かない」という報告を受けたときにどの順序で調べるかを書いてください。
参考
- これまでのラボのコマンドをそのまま組み合わせます。3つ目と8つ目のラボのヒントが特に役立ちます。
- dnsmasqに上流へ転送させるには、
no-resolvとともにserver=<상류주소>を書きます(プレースホルダーは上流サーバーのアドレスです)。上流はresolvectl dns enp1s0で確認できます。 - ファイアウォールはforwardチェーンです。VM自身のinputには手を付けないでください。採点エージェントがブロックされます。
nft add rule inet labfw forward iifname "r-home" oifname "r-dmz" tcp dport 80 accept。- よくある間違い: ステップ6で、forwardにuplink側の許可を書き忘れることです。NATルールだけでは、forwardのdropを越えられません。
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)を含める必要があります。