日本語

Dev Containers 内の Device Protection

Device ProtectionをFeatureとしてDev Containerに追加すると、どのdevcontainer.jsonからでも、カスタムDockerfileを用意せずに任意のベースイメージへ追加できます。

まずコンテナでのDevice Protectionをお読みください。このFeatureは同じパッケージを同じ--containerモードでインストールするため、エントリーポイント、Aikido CA変数、トークンのルールはすべて同じように機能します。

Featureを追加する

プロジェクト内に、たとえば.devcontainer/features/device-protection/として以下を作成します。

.devcontainer/features/device-protection/devcontainer-feature.json
{
  "id": "device-protection",
  "version": "1.0.0",
  "name": "Aikido Device Protection",
  "description": "Installs Aikido Device Protection in --container mode so package manager traffic inside the container is inspected for malware.",
  "entrypoint": "aikido-endpoint-protection-container-entrypoint"
}

entrypointは、イメージ本来のエントリーポイントを置き換えるのではなく、それと並行してエージェントのスーパーバイザーを実行します。

.devcontainer/features/device-protection/install.sh
#!/usr/bin/env bash
set -euo pipefail

case "$(uname -m)" in
  x86_64) ARCH=amd64 ;;
  aarch64) ARCH=arm64 ;;
  *) echo "Aikido Device Protection: unsupported architecture $(uname -m)" >&2; exit 1 ;;
esac

if command -v apt-get >/dev/null 2>&1; then
  apt-get update
  apt-get install -y --no-install-recommends curl ca-certificates
  curl -fLO "https://github.com/AikidoSec/safechain-internals/releases/latest/download/EndpointProtection-${ARCH}.deb"
  AIKIDO_CONTAINER=1 AIKIDO_CI_CD=1 apt-get install -y --no-install-recommends "./EndpointProtection-${ARCH}.deb"
  rm -f "EndpointProtection-${ARCH}.deb"
  rm -rf /var/lib/apt/lists/*
elif command -v dnf >/dev/null 2>&1; then
  . /etc/os-release
  EL="el${VERSION_ID%%.*}"
  dnf install -y --setopt=install_weak_deps=False curl ca-certificates
  curl -fLO "https://github.com/AikidoSec/safechain-internals/releases/latest/download/EndpointProtection-${ARCH}.${EL}.rpm"
  AIKIDO_CONTAINER=1 AIKIDO_CI_CD=1 dnf install -y --setopt=install_weak_deps=False "./EndpointProtection-${ARCH}.${EL}.rpm"
  rm -f "EndpointProtection-${ARCH}.${EL}.rpm"
else
  echo "Aikido Device Protection: no apt-get or dnf found, unsupported base image" >&2
  exit 1
fi

これは「コンテナでのDevice Protection」にあるパッケージファイル方式なので、イメージにトークンが組み込まれることはありません。ベースイメージのパッケージマネージャーとアーキテクチャに合った.debまたは.rpmを選択します。これらは手動でのLinuxインストールで使用するものと同じファイルです。

tokenをFeatureのオプションとして追加しないでください。オプションは、イメージビルド中にインストールスクリプトが読み込むdevcontainer-features.envファイルに書き込まれるため、その方法で渡したトークンはビルドレイヤーに残ってしまう可能性があります。代わりに、以下のcontainerEnvを使って、コンテナ起動時にAIKIDO_TOKENを渡してください。

devcontainer.jsonで設定する

.devcontainer/devcontainer.json
{
  "name": "my-app",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "features": {
    "./features/device-protection": {}
  },
  "containerEnv": {
    "AIKIDO_TOKEN": "${localEnv:AIKIDO_TOKEN}"
  },
  "postCreateCommand": "echo 'for f in /etc/profile.d/aikido-*.sh; do [ -e \"$f\" ] && . \"$f\"; done' >> ~/.bashrc"
}
  • featuresは、devcontainer.jsonからの相対的なローカルパスでFeatureを参照します。
  • containerEnvは、コンテナの起動時にトークンを渡します。Dev Containerを開く前に、シェル(またはCodespacesのシークレット)でAIKIDO_TOKENを設定してください。
  • postCreateCommandはCAの読み込み処理を~/.bashrcに追記します。これにより、後からコンテナ内で開いたターミナル(VS Codeの統合ターミナル、Codespaces)がAikido CAを読み込み、インストールがSELF_SIGNED_CERT_IN_CHAINで失敗することを防ぎます。

Dev Containerのデフォルトシェルがbashではなくzshの場合は、代わりに~/.zshrcに追記してください。

"postCreateCommand": "echo 'for f in /etc/profile.d/aikido-*.sh; do [ -e \"$f\" ] && . \"$f\"; done' >> ~/.bashrc"

他の理由ですでにカスタムDockerfileをビルドしている場合でも、featuresはその上に適用されます。エージェントのインストールやENTRYPOINTの行をそのDockerfileに自分で追加する必要はなくなり、Featureがそれを行います。

各リポジトリにフォルダーをコピーして含める代わりに、複数のリポジトリでFeatureを再利用するには、devcontainer features publishを使ってチームが管理するレジストリに一度公開し、パスではなくghcr.io/<your-org>/devcontainer-features/device-protection:1として参照します。publishコマンドについてはDev Containers CLIのドキュメントを参照してください。

GitHub Codespacesのシークレット

Codespacesでは、AIKIDO_TOKENをコミットするのではなく、リポジトリまたは組織のCodespacesシークレットとして追加してください。${localEnv:AIKIDO_TOKEN}は、ローカルのシェル変数と同じように、環境変数として公開されたシークレットを読み込みます。

動作を確認する

Dev Containerで新しいターミナルを開き(postCreateCommandの変更を反映させるため、新規のものを開きます)、以下を実行します。

curl -sS -o /dev/null -w "%{http_code}\n" --max-time 15 https://registry.npmjs.org/safe-chain-test/-/safe-chain-test-0.0.1-security.tgz
aikidoctl version

curlは403を出力します。これはエージェントがマルウェアのテストパッケージを拒否したことを示します。aikidoctl versionは、インストールされているバージョンとエージェントの状態を表示します。

トラブルシューティング

エントリーポイントとインストール手順は他のLinuxコンテナと同じなので、まず「コンテナでのDevice Protection」のトラブルシューティング表を確認してください。Dev Containers固有の追加事項が2つあります。

問題解決策
統合ターミナルでパッケージのインストールがSELF_SIGNED_CERT_IN_CHAINで失敗するが、postCreateCommand経由で実行すると成功するpostCreateCommandが完了する前にターミナルが開かれていたか、追記先とは別のシェルを使用しています。新しいターミナルを開き、~/.bashrc(または~/.zshrc)にaikido-*.shの読み込み行があるか確認してください
no apt-get or dnf found, unsupported base imageベースイメージが、Featureがまだ対応していないパッケージマネージャー(たとえばAlpineのapk)を使用しています。そのための分岐を追加するか、「コンテナでのDevice Protection」に示されている手順でエージェントを手動でインストールしてください