Web サーバー堅牢化のラボ:弱い nginx の設定を直して curl で確かめる

このラボは、各生徒に、わざと弱い設定にした nginx で配信される小さなサイトを渡します。サイトはバージョン番号を表示し、フォルダーの一覧を見せ、セキュリティヘッダーを1つも送らず、.git フォルダーとバックアップファイル、だれでも開ける管理画面を公開しています。生徒は curl で調べ、動いているコンテナーの中で設定を直し、nginx を再読み込みして、各チェックが FAIL から PASS に変わるのを確かめます。

公開されている nginx のイメージだけから私たちが設計したため、攻撃する脆弱なアプリはなく、安全にするためのサーバーがあるだけです。ラボのコピーは、インターネットにも他の生徒にも通じていません。

生徒が学ぶこと

Web サーバーが、頼まれなくても訪問者に伝えてしまうこと:正確なバージョン、フォルダーの中のファイル、だれも公開するつもりのなかったファイルです。生徒は curl -I でレスポンスヘッダーを読み、よく使われる4つのセキュリティヘッダーを追加し、フォルダー一覧とバージョン表示を止め、.git フォルダーとバックアップファイルを拒否し、管理画面を訪問者に閉じます。さらに、nginx -t で設定をテストし、nginx -s reload で読み込み、ツールで結果を確かめる練習もします。安全な設定とシステム管理の単元に向いています。正確な表現は、お使いの認定機関の単元でご確認ください。

ブラウザーで動かす

サイトは web という名前のサービスで、ラボのターミナルからはその名前で届きます。ターミナルの docker コマンドは、ラボのサービスを見る、中に入る、再起動する、ログを読むことができます。作成、取得、削除はできません。設定フォルダーは名前付きボリュームなので、生徒が保存した内容は、ラボを停止してもう一度起動したあとも残ります。

  1. コンテナーのページを開く. バーの「つくる」を開き、「コンテナーを実行」を選びます。ページは誰でも開けて、Git ラボと SQL ラボはアカウントなしで起動できます。ほかのラボには無料アカウントが必要です。アカウントを作成してサインインし、「起動」を押します。
  2. ラボを探す. 「サンプルラボ」のカードにすべてのサンプルが並んでいます。Web サーバーの堅牢化(nginx)を探します。
  3. 「起動」を押す. 「起動」はそのまま1回の操作で実行します。「先にファイルを編集」は compose ファイルを開くので、起動する前に変更できます。
  4. 開く. ラボのページで、ラボの横のターミナルを開きます。curl -I http://web でヘッダーを、docker exec web lab-check で PASS か FAIL の9行を見ます。続いて docker exec -it web sh でサーバーの中のシェルを開き、/etc/nginx/conf.d/default.conf を編集し、nginx -t でテストし、nginx -s reload で読み込みます。ラボのリンク The bakery’s website は、サイトを新しいタブで開きます。

何を提出させるか

curl -I http://web の出力を直す前と直したあとの両方、そして最後の docker exec web lab-check の出力を提出させます。変更が生徒自身のターミナルに見える形になります。修正ごとに、その弱点が攻撃者に何を与えていたか、その設定が何をするかを、自分の言葉で1文で書かせます。チェックはサーバーが正しく動くかを示し、理解したかどうかを示すのは説明だけです。より高い水準を求めるなら、設定ファイル全体も提出させます。

チェックはラボ自身のものです。lab-check は動いているサーバーに問い合わせるので、ファイルに何と書いてあるかではなく nginx が実際に何をするかを示し、9行すべてが PASS のときだけ成功で終了します。リポジトリの README には、どこからでも確かめられる、修正ごとの1行の curl もあります。自動では採点されません。

このラボの基本レッスン

Web Server Hardening Basics は、このラボで進める小さなレッスンで、各手順に説明と、生徒のターミナルにコマンドを入力する「実行」ボタンが付いています。ヘッダーとフォルダー一覧を見て、チェックを実行し、1つのコマンドでバージョン番号を直し、nginx を再読み込みして、もう一度確かめます。ほかの修正は生徒に任せます。

無料の個人アカウントには、ホームにある Basics モジュールで配布されます。どの学校もライブラリの Basics フォルダから自分のモジュールにコピーでき、新しい学校ではサンプルモジュールの Lab Basics (Sample) に入っています。意図的に小さくしてあり、ラボで進めるレッスンとは何かを教員に見せるためのもので、残りはラボが担います。変更したい場合は、自分のモジュールにコピーしてください。

GitHub のコード

compose ファイルは、nginx 自身の公開イメージをバージョンで固定し、唯一のサービスとして実行し、起動時にサイトと弱い設定を書き出します。nginx は BSD-2-Clause ライセンスで、当社が配布するものではありません。リポジトリのテストは、プラットフォームが適用するのと同じ制限のもとで、生徒としてラボを修正ごとにたどります。ラボにはインターネットへの出口がないため、サイトが外部へ張ったリンクは取得できません。

課題として出す

どの修正を行い、何を提出するかを、課題に書いておきます。

  1. ラボを作る. モジュールで課題を追加し、「コンテナーラボ」のカードを選んでから「GitHub リポジトリ」を選びます。https://github.com/mitsurutech/lab-harden-nginx とブランチ main を指定します。compose ファイルは既定の compose.yaml です。変更したい場合は、先にリポジトリをフォークしてください。
  2. 公開して試す. 「公開」すると、確認したコミットに固定されるので、あとでリポジトリを変更しても、すでに出したラボは変わりません。まず自分のコピーを起動してください。
  3. 配布する. ほかの課題と同じように配布します。期限を付けることもでき、課題には何をするか、何を提出するかを書いておきます。
  4. 提出物を採点する. 生徒のコピーを開いて提出された内容を確認し、採点します。足りない場合は理由を書いて差し戻します。

よくある質問

生徒が設定に間違いを保存したらどうなりますか?
ラボは起動します。起動時に nginx -t を通らない設定は、default.conf.broken としてその横に残され、弱い設定が書き直されます。わざと弱い設定からやり直したいときは、/etc/nginx/conf.d の .seeded ファイルを削除して、サービスを再起動します。
生徒は何かをインストールしたり、インターネットに接続したりする必要がありますか?
いいえ。nginx と curl はラボのイメージに入っていて、ターミナルはブラウザーの中にあり、ラボのコピーにはインターネットへの出口がありません。
生徒は nginx の堅牢化がうまくいったことをどう確かめますか?
ラボのターミナルで docker exec web lab-check を実行します。PASS または FAIL が9行表示され、9行すべてが通ったときだけ成功で終了します。動いているサーバーに問い合わせるので、ファイルの内容ではなく nginx の実際の動作が分かり、curl -I http://web で前後のヘッダーも確認できます。