
お客様のInfrastructure as Code(IaC)に共通する脆弱性をスキャンするサービスです。
| 側面 | 情報 |
|---|---|
| ツール名 | IaC Scan Runner |
| Dockerイメージ | xscanner/runner |
| PyPIパッケージ | iac-scan-runner |
| ドキュメント | docs |
| お問い合わせ | [email protected] |
IaC Scan Runnerは、IaC(Infrastructure as Code)パッケージをスキャンし、さまざまなコードチェックを実行して、潜在的な脆弱性や改善点を見つけるためのREST APIサービスです。詳細についてはdocsをご覧ください。
このセクションでは、REST APIの実行方法について説明します。
以下のように、パブリックなxscanner/runner Dockerイメージを使用してREST APIを実行できます。
# run IaC Scan Runner REST API in a Docker container and
# navigate to localhost:8080/swagger or localhost:8080/redoc
$ docker run --name iac-scan-runner -p 8080:80 xscanner/runner
または、イメージをローカルでビルドして次のように実行することもできます。
# build Docker container (it will take some time)
$ docker build -t iac-scan-runner .
# run IaC Scan Runner REST API in a Docker container and
# navigate to localhost:8080/swagger or localhost:8080/redoc
$ docker run --name iac-scan-runner -p 8080:80 iac-scan-runner
IaC Scan Runner CLIを使用して実行するには:
# install the CLI
$ python3 -m venv .venv && . .venv/bin/activate
(.venv) $ pip install iac-scan-runner
# print OpenAPI specification
(.venv) $ iac-scan-runner openapi
# install prerequisites
(.venv) $ iac-scan-runner install
# run IaC Scan Runner REST API
(.venv) $ iac-scan-runner run
ソースからローカルで実行する場合:
# Export env variables
export MONGODB_CONNECTION_STRING=mongodb://localhost:27017
export SCAN_PERSISTENCE=enabled
export USER_MANAGEMENT=enabled
# Setup MongoDB
$ docker run --name mongodb -p 27017:27017 mongo
# install prerequisites
$ python3 -m venv .venv && . .venv/bin/activate
(.venv) $ pip install -r requirements.txt
(.venv) $ ./install-checks.sh
# run IaC Scan Runner REST API (add --reload flag to apply code changes on the way)
(.venv) $ uvicorn src.iac_scan_runner.api:app
この部分では、可能なデプロイメントの一例と、APIコールの使用方法に関する簡単な例を示します。
まず、iac scan runnerリポジトリをクローンしてAPIを実行します。
$ git clone https://github.com/xlab-si/iac-scan-runner.git
$ docker compose up
これが完了すると、localhost:8000を呼び出すことでさまざまなAPIエンドポイントを使用できます。また、localhost:8000/swaggerまたはlocalhost:8000/redocに移動して、すべてのAPIエンドポイントをテストすることもできます。この例では、curlを使用してAPIエンドポイントを呼び出します。
curl -X 'POST' \
'http://0.0.0.0/project?creator_id=test' \
-H 'accept: application/json' \
-d ''
プロジェクトIDが返されます。この例では、プロジェクトIDは1e7b2a91-2896-40fd-8d53-83db56088026です。
curl -X 'PUT' \
'http://0.0.0.0:8000/projects/1e7b2a91-2896-40fd-8d53-83db56088026/checks/ansible-lint/disable' \
-H 'accept: application/json'
curl -X 'POST' \
'http://0.0.0.0:8000/projects/1e7b2a91-2896-40fd-8d53-83db56088026/scan?scan_response_type=json' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F '[email protected];type=application/zip'
以上です。
ある時点で、IaC標準やプロジェクトタイプのより広いカバレッジを提供するために、スキャンワークフローに新しいチェックツールを含める必要が生じることがあります。そのため、このサブセクションでは、その目的のために必要な一連の手順を特定し説明します。ただし、説明される手順は手動で実行する必要がありますが、将来はAPIを介してこの手順を自動化し、スキャンワークフローを構成する利用可能なカタログの一部となる新しいツールをインポートする際にユーザーを支援するユーザーフレンドリーなインターフェースを提供する予定です。図16は、スキャンワークフローを新しいツールで拡張するために必要な手順を示しています。
まず、IaC Scan Runnerのソースコード内のchecksディレクトリに、新しいツール固有のPythonクラスを追加する必要があります: iac-scan-runner/src/iac_scan_runner/checks/new_tool.py
新しいツールのクラスは、スキャンワークフローツールの一般化を提供する既存のCheckクラスを継承します。さらに、以下のメソッドの実装を提供する必要があります:
最初のメソッドは、ツールを設定するために必要なツール固有のパラメータ(パスワード、クライアントID、トークンなど)を提供することを目的としています。もう一方のメソッドは、ツール自体がAPIまたはCLIを介してどのように呼び出され、その生の出力が返されるかを指定します。
Checkから派生した新しいクラスがIaC Scan Runnerのソースコードに追加されたら、そのメインクラスであるScanRunnerのソースコードを変更する必要があります。このクラスの変更に関しては、最初にツール固有のクラスをインポートし、新しいチェックツール固有のクラスインスタンスを作成し、def init_checks(self)内のIaCチェックの辞書に追加する必要があります。
A. チェックツールクラスのインポート
from iac_scan_runner.checks.tfsec import TfsecCheck
B. init_checks内でチェックツールオブジェクトの新しいインスタンスを作成
"""Initiate predefined check objects"""
new_tool = NewToolCheck()
C. init_checks内のself.iac_checks辞書に追加
self.iac_checks = {
new_tool.name: new_tool,
…
}
一方、src/iac_scan_runner/compatibility.pyファイル内で、互換性マトリックスを表す辞書も拡張する必要があります。2つのケースが考えられます:a) 新しいファイルタイプをキーとして追加し、値として関連ツールのリストを追加する b) 既存のファイルタイプの互換性リストに新しいツールを追加する。
compatibility_matrix = {
"new_type": ["new_tool_1", "new_tool_2"],
…
"old_typeK": ["tool_1", … "tool_N", "new_tool_3"]
}
最後に、スキャンワークフロー拡張のための一連の必要な変更の最後のステップは、クラスResultsSummary(src/iac_scan_runner/results_summary.py)を変更することです。具体的には、そのメソッドsummarize_outcomeに、ツール固有の特定の文字列を探してチェックが合格したか失敗したかを識別できるコードの一部を追加する必要があります。互換性のあるチェックを走査するループ内で、新しいツールごとに次のif-else構造を含める必要があります:
if check == "new_tool":
if outcome.find("Check pass string") > -1:
self.outcomes[check]["status"] = "Passed"
return "Passed"
else:
self.outcomes[check]["status"] = "Problems"
return "Problems"
この作品はApache License 2.0の下でライセンスされています。
xOperaチームには、[email protected]までメールでお問い合わせいただけます。
このプロジェクトは、欧州連合のHorizon 2020研究・イノベーションプログラムからグラント契約番号101000162(PIACERE)の下で資金提供を受けています。