NAT ゲートウェイのラボ:nftables でマスカレードとポート転送をブラウザーで学ぶ
アドレス変換(NAT)を学ぶネットワークラボです。生徒の Ubuntu VM 1台の中に3台のマシンを作ります。10.0.0.0/24 のプライベートなホスト、ゲートウェイ、203.0.113.0/24 の外側のサーバーです。外側にはプライベートアドレスへ戻る経路がないので、ホストはサーバーに届きません。生徒はその理由を調べ、ゲートウェイで nftables を使って直さなければなりません。
インストールするものも、買うルーターもありません。マシンはどれもネットワーク名前空間で、本物のコマンドがそのまま使えます。外側のサーバーはどのリクエストにも、それが来たアドレスを返すので、生徒はアドレス変換が何をするかを自分の目で確かめられます。
生徒が学ぶこと
プライベートアドレスがインターネットでは使えない理由と、ゲートウェイが背後のマシンの代わりにどう振る舞うか。出ていくものの送信元アドレスを書き換えるマスカレードと、入ってくるものの宛先を書き換えて、外側からプライベートなホストの1つのサービスに届くようにするポート転送です。conntrack でゲートウェイの接続テーブルを読み、tcpdump でリンクを観察し、ほかをすべて破棄するファイアウォールを広げすぎずに転送された通信だけ通し、再起動しても残るようにルールを保存します。
トポロジーと課題
ポート80で Web ページ、ポート8081で非公開のページを出す LAN のホスト、両側に1本ずつケーブルがあるゲートウェイ、ポート8000の外側のサーバーです。いまのゲートウェイは、LAN から始まる接続を通し、ほかは破棄します。生徒は、LAN のホストがゲートウェイの外側のアドレスとして外側のサーバーに届くようにし、次に LAN の Web ページを外側からポート8080で届くようにします。それ以外は開けません。アドレスは、ラボがホームフォルダーに置く README にあります。README にはやることが書かれていて、答えは書かれていません。
ブラウザーで動かす
VM ラボはモジュールにラボ課題として追加し、サンプルはラボのページにあります。
- ラボを追加する. 自分が教えるモジュールで課題を追加し、「Ubuntu VM ラボ」のカードを選びます。ページにはcompose ファイルの代わりにマシンの短い記述が表示されます。
- サンプルから始める. ページには、そこから始められるサンプルが用意されています。NAT gateway: masquerade and port forwarding を選びます。サンプルを使うとテキストが置き換わりますが、「元に戻す」で自分のテキストに戻せます。
- 公開して自分のコピーを起動する. 「公開」してから「起動」を押します。VM の初回起動時に、ラボ自身の setup スクリプトが Ubuntu のアーカイブから nftables といくつかのネットワークツールをインストールし、3台のマシンを作ります。所要時間は約10秒です。
- ターミナルを開く. ターミナルを開き、ホームフォルダーの README.md を読みます。やることが書かれていて、答えは書かれていません。netlab status でマシンの一覧、netlab shell gw でゲートウェイのシェルを開けます。
このラボの基本レッスン
NAT Basics は、このラボで進める小さなレッスンです。このラボは Ubuntu VM で、各手順に説明と、マシンのターミナルにコマンドを入力して出力を表示する「実行」ボタンが付いています。生徒はマシンを確認し、外側のサーバーにページを要求してタイムアウトするのを見て、外側のサーバーの経路にプライベートアドレス宛てのものがないことを確かめ、ゲートウェイのルールにアドレスを変換するものがないことを読み取ります。
生徒は見て回るだけで、動かすというラボ本来の課題は生徒に任せるので、レッスンは答えを教えません。無料の個人アカウントには、ホームにある Basics モジュールで配布されます。どの学校もライブラリの Basics フォルダから自分のモジュールにコピーでき、新しい学校ではサンプルモジュールの Networking Basics (Sample) に入っています。意図的に小さくしてあり、ラボで進めるレッスンとは何かを教員に見せるためのもので、残りはラボが担います。変更したい場合は、自分のモジュールにコピーしてください。
採点の仕組み
ラボにはチェックがあります。新しく起動し直した、保存されたマシンのコピーで実行されるため、生徒が /etc/nftables.conf に保存した内容だけが見えます。採点するのはルールの書き方ではなく、ネットワークの実際の動きです。LAN のホストからのリクエストが外側のサーバーに届き、サーバーがゲートウェイの外側のアドレスを見ていること。外側からポート8080へのリクエストがLAN のページに届き、ページがクライアント自身のアドレスを見ていること(ゲートウェイ上のプロキシでは合格しません)。非公開のページとほかのポートは閉じたままで、ゲートウェイは許可されていないものを引き続き破棄していること。動いているゲートウェイに入力しただけで保存していないルールは合格にならず、チェックの出力の1行目にその理由が出ます。
- 配布する. ほかの課題と同じようにラボを配布します。期限を付けることもできます。各生徒には専用の VM が渡され、セッションをまたいで保持されます。
- チェックを実行する. クラス一覧の生徒の行で「チェックを実行」を押します。保存されたマシンのコピーが(元には保存されない形で)起動し、ラボのチェックスクリプトが root で実行されて、合格したか、何を出力したか、いつかが表示されます。結果は生徒には知らされません。
- 採点する. チェックの出力を読みます。生徒が VM を停止すると、クラス一覧にインストールしたパッケージや書いたファイルなどの変更内容も表示されるので、VM を起動せずに採点できます。足りない場合は理由を書いて差し戻します。
GitHub の定義ファイル
このファイルがラボの定義のすべてで、プラットフォームが実行するのと同じテキストです。サイズ、setup スクリプト、トポロジー、README、チェックが入っています。必要なのは CPU 1つと 1 GB です。コピーして書き換えれば自分のラボになります。
よくある質問
- 外側は本物のインターネットですか?
- いいえ。外側は生徒の VM の中のネットワーク名前空間で、ドキュメント用に確保された範囲の 203.0.113.0/24 を使います。VM 自体が届くのは Ubuntu のパッケージアーカイブ、PyPI、npm、GitHub だけなので、ラボをインターネット上のホストに向けることはできません。
- 生徒は本物の Linux コマンドを使えますか?
- はい。それが狙いです。sudo ip netns exec gw nft list ruleset や sudo ip netns exec gw conntrack -L はそのまま使え、netlab shell gw は近道です。
- マスカレードとポートフォワードの違いは何ですか?
- マスカレードはプライベートネットワークから出ていくものの送信元アドレスを書き換えるので、LAN のホストが外のサーバーに届きます。ポートフォワードは入ってくるものの宛先を書き換えるので、外からプライベートホストの1つのサービスに届きます。このラボは両方を求め、フォワードはポート 8080 です。