はじめての DevSecOps 実験

はじめに

アプリケーションは正常に動作していても、利用者に不要な情報を公開していることがあります。この実験では DeskLite がすでに動作していますが、状態応答に内部の開発情報が含まれています。応答を調べ、設定を一つ変更し、必要な機能が維持されていることを確認します。

前提は、ターミナルでの基本的なディレクトリ移動とファイルの読み取りだけです。リクエスト、HTTP 応答、設定スイッチ、用意された再起動コマンドは、使うときに順番に説明します。リスクを観察し、原因を修正し、安全性と通常動作を一緒に確かめる、最初の DevSecOps のサイクルです。

サービスの応答を観察する

このステップでは、DeskLite に情報を要求し、公開されている内部情報を記録します。

DeskLite は小さなヘルプデスクアプリです。担当者にはチケット情報と稼働状態が必要ですが、内部ファイルの場所や開発用診断は不要です。この内部情報が保護対象であり、応答を読める人がその応答の対象者です。

サービスとは、動作を続けて要求に応えるプログラムです。HTTP リクエストは Web サービスに何かを要求し、その応答には状態コードと本文が含まれます。ターミナルの curl を使うため、ブラウザーやプログラミングの知識は必要ありません。

サービスはすでに動作しています。用意された次のディレクトリだけで作業します。

cd /home/labex/project/desklite

URL は curl に要求先を伝えます。http://127.0.0.1:8080/status の http は通信方式、127.0.0.1 はこの実験マシン、8080 はサービス、/status はエンドポイント、つまりサービスが提供する特定の応答を選びます。ここでネットワークを設定する必要はありません。

curl http://127.0.0.1:8080/status

本文は JSON 形式です。波括弧の中に名前付きのフィールドと値があります。読むだけでよく、プログラムを書く必要はありません。

{
  "service": "DeskLite",
  "status": "running",
  "internal_path": "/opt/labex-desklite/private/settings.ini",
  "debug_details": "development diagnostics enabled"
}

service と status は想定する対象者に役立ちます。internal_path は内部のファイル位置を、debug_details は開発情報を示しています。パスを知っても自動的にファイルへアクセスできるわけではありませんが、不要な情報が追加の調査に役立つ可能性があります。これを情報漏えいと呼びます。

-i オプションを加えると、本文の上に HTTP ヘッダーも表示されます。

curl -i http://127.0.0.1:8080/status

最初の行の 200 OK は要求が成功したことを示します。Content-Type: application/json などのヘッダーは本文を説明し、空行がヘッダーと本文を分けます。日時は変わる場合があります。HTTP の成功は安全性を意味しません。この成功した応答も情報を漏らしています。

サービス設定、つまりアプリが利用する設定ファイルを読みます。

cat service.conf

[service] は設定をグループ化します。# から始まる行は説明用コメントです。debug = true は真偽値のスイッチで、true が開発診断を有効にし、false が無効にします。コメントが、この設定と公開された状態フィールドの関係を説明しています。

チームメンバーが発見事項を理解できるよう、短い引き継ぎメモを残します。ターミナル用テキストエディター nano でテンプレートを開きます。

nano investigation.txt

矢印キーで移動し、最初の四つの TODO を次の内容に置き換えます。Checks: TODO は今は残します。リスクは自分の言葉で説明してください。例は考え方を示しています。

Endpoint: http://127.0.0.1:8080/status
Fields: internal_path, debug_details
Config: /home/labex/project/desklite/service.conf
Risk: Unnecessary internal details are visible to status readers.
Checks: TODO

Ctrl+O、Enter で保存し、Ctrl+X で終了します。Ctrl を押しながら文字キーを押してください。保存したメモを読み返します。

cat investigation.txt

エンドポイント、フィールド名、設定パスが観察したサービスと一致することを確認します。このメモは証拠を保存するもので、まだ漏えいを修正したわけではありません。

開発用診断を無効にする

このステップでは、漏えいの原因となる設定を変更し、稼働中のサービスに適用します。

デバッグ情報は開発者の問題調査に役立ちます。しかし、開発時に便利な設定でも、公開状態だけを必要とする対象者には不適切な場合があります。DevSecOps は、開発と運用が共同で安全性に取り組むことです。公開すべき内容を決め、設定を変え、実際の動作をテストします。

同じエディターで設定を開きます。

nano service.conf

debug = true だけを debug = false に変更します。[service] の見出しとコメントは残します。Ctrl+O、Enter で保存し、Ctrl+X で終了します。保存した内容を確認します。

cat service.conf

設定は次のようになります。

[service]
## Include development diagnostics in status responses.
debug = false

ディスク上のファイルと実行中のプログラムは別のものです。このサービスは起動時に設定を読むため、保存するだけでは応答は変わりません。コースが用意した restart.sh を使えば、自分でプロセスを管理せずに設定を適用できます。bash は用意されたスクリプトを実行します。スクリプトの編集は不要です。

bash restart.sh

期待する出力です。

DeskLite restarted.

ヘッダー付きで同じエンドポイントを再度要求します。

curl -i http://127.0.0.1:8080/status

200 OK と次の本文が返るはずです。

{
  "service": "DeskLite",
  "status": "running"
}

二つの内部フィールドが消え、有用な状態情報は残りました。まだ表示される場合は、service.conf を保存して再起動コマンドを実行したか確認します。設定エラーが出た場合は、上の見出しと真偽値の綴りに戻して再試行してください。応答を隠すためにアプリを置き換えたり、サービスを止めたりしてはいけません。

安全性と業務機能を一緒に確認する

このステップでは、再起動後も修正が維持され、DeskLite が利用者の役に立つ状態であることを確認します。

サービスを壊しても応答は消えますが、必要な機能まで失われます。そこで、機密フィールドがなくなったことと、正当なサービスが動くことの二つの証拠が必要です。ヘルスチェックは基本的な稼働準備状態を示し、業務リクエストは利用者が必要とする機能をテストします。

保存した設定が引き続き適用されるよう、もう一度再起動します。

bash restart.sh

状態を再確認します。

curl -i http://127.0.0.1:8080/status

200 OK、service、status があり、internal_path と debug_details はないはずです。次にヘルスエンドポイントを要求します。

curl -i http://127.0.0.1:8080/health

200 OK と次の本文を期待します。

{
  "status": "ok"
}

最後に業務エンドポイントを要求します。

curl -i http://127.0.0.1:8080/tickets

200 OK と元のチケットが返るはずです。

{
  "tickets": [
    {
      "id": 1,
      "title": "Printer offline"
    }
  ]
}

プロセスが正常なだけではチケットへのアクセスまで証明できません。これらの要求を合わせると、漏えいがなくなり、必要な機能が維持されたと分かります。curl に転送状況が表示されることもありますが、判断するのは HTTP 状態と本文です。

エディターで引き継ぎメモを更新します。

nano investigation.txt

元の発見事項は残します。三つの成功結果を観察してから、Checks: TODO だけを次の行に置き換えます。

Checks: /status 200; /health 200; /tickets 200

Ctrl+O、Enter で保存し、Ctrl+X で終了します。メモを確認します。

cat investigation.txt

元の証拠、原因となる設定、リスク、テスト結果が結び付きました。自動検証は事実のフィールドと稼働中のサービスを比較します。リスクの説明は人が確認するもので、数語だけで理解度を証明することはできません。

最後に、ステップ 1 の 200 OK だけではなぜ安全と言えなかったのか、ヘルスチェックだけではなぜ完全な修正を証明できないのかを自分に説明してみてください。この小さな安全性のフィードバックループをコース全体で再利用します。

まとめ

curl と curl -i で HTTP 応答を読み、要求の成功と応答の安全性を区別し、公開されたフィールドを真偽値の設定スイッチに結び付けました。設定を保存して DeskLite を再起動し、内部診断なしで状態、ヘルスチェック、チケットアクセスが動作することを確認しました。

調査メモは発見事項とテスト結果をチームに引き継ぎます。この小さな作業は、開発設定、運用上の動作、安全性検証をつなぎます。次のチャレンジでは、別の用意されたサービスに同じスキルを適用します。