Skip to main content

コンテナを使用してNode.jsエージェントをインストール

Node.jsエージェントのコンテナへのインストールは、インストールがコンテナ内で行われることを除いて、基本的に標準のインストール手順と同じです。ベストプラクティスに従うには、環境変数を使用してContrastの認証情報を設定する必要があります。

Node.jsエージェントをコンテナにインストールする場合、環境変数を使用するのが最も安全な方法です。コンテナはQAや本番システムから移行されることが多いため、コンテナ定義に認証情報をハードコーディングしないことをお勧めします。

インストールを行う前に

本項では、Dockerを例として、コンテナ化されたアプリケーションにNode.jsエージェントをインストールするための一般的な手順について説明します。

コンテナや関連ソフトウェアの仕組みを基本的に理解している必要があります。実際の手順は、ご利用の環境に合わせて調整してください。

エージェントをインストール

以下のいずれかの方法で、Nodejsエージェントをインストールします。

  • アプリケーションの開発時にエージェントを追加 (推奨)

    この方法の場合、アプリケーションのpackage.jsonでエージェントを取り込みます。

    次のコマンドを使用して、パイプラインやコンテナイメージにエージェントを追加します。

    npm install @contrast/agent
  • Dockerfileにエージェントを追加

    アプリケーションのイメージを別々に管理したい場合(Contrastエージェントを使用する場合と使用しない場合)は、コンテナのビルド時にエージェントを追加します。

    次のコマンドを使用して、既存のDockerfile、またはアプリケーションのイメージをベースイメージとして使用する新規のDockerfileにエージェントを追加します。

    npm install @contrast/agent

エージェントを設定

Node.jsエージェントをDockerなどのコンテナにデプロイしたアプリケーションで設定する場合は、以下の手順に従ってください(そうでない場合は、通常のNode.jsエージェントの設定を参照してください)。Node.jエージェントの設定には、設定した値が有効になる優先順位があります。

エージェントトークンを使用 する場合

この変数はbase64でエンコードされたJSONオブジェクトで、url、api_key、service_key、user_nameの構成設定が含まれます。これらの値を、この1つの変数で設定できます。

  1. エージェントトークンを使用します。

    CONTRAST__API__TOKEN
  2. 環境変数を使用して、アプリケーション固有の設定値を指定します。これらは、Dockerfile内でENV命令を定義するか、Docker runコマンドの実行時に-eオプションで指定することができます。アプリケーション固有の値を設定するためによく使用される環境変数の一覧を参照して下さい。また、Contrastエージェント設定エディタで変数の全一覧を参照することもできます。view a full list of variables.

    例えば、次のコマンドを使用して、コンテナを構築することができます。

    docker build -t my-app-image

    そして、コンテナの実行時には次のコマンドを使用します。

    docker run -p 3000:3000 --name my-app-instance \
    -e "CONTRAST__API__TOKEN=your-api-token" \
    My-app-image

    クラウドプロバイダの使用時に環境変数を設定するプロセスでは、一般的には、シークレットマネージャを使用し、それらのシークレットの値を環境変数にリンクすることになります。

従来の設定を使用する場合

エージェントの設定で、従来の設定とエージェントトークンの両方を参照している場合(環境変数またはYAMLファイル内)、従来の設定が優先されます。エージェントトークンの値のみを使用するには、従来の設定への参照を削除してください。

  1. 5.15.0より前のバージョンのNode.jsエージェントを使用している場合、以下の変数が必要です。

    export CONTRAST__API__URL
    export CONTRAST__API__API_KEY
    export CONTRAST__API__SERVICE_KEY
    export CONTRAST__API__USER_NAME
  2. 環境変数を使用して、アプリケーション固有の設定値を指定します。これらは、Dockerfile内でENV命令を定義するか、Docker runコマンドの実行時に-eオプションで指定することができます。アプリケーション固有の値を設定するためによく使用される環境変数の一覧を参照して下さい。また、Contrastエージェント設定エディタで変数の全一覧を参照することもできます。

    例えば、次のコマンドを使用して、コンテナを構築することができます。

    docker build -t my-app-image

    そして、コンテナの実行時には次のコマンドを使用します。

    docker run -p 3000:3000 --name my-app-instance \
    -e "CONTRAST__API__URL=your-ts-url" \
    -e "CONTRAST__API__API_KEY=your-api-key" \
    -e "CONTRAST__API__SERVICE_KEY=your-service-key" \
    -e "CONTRAST__API__USER_NAME=your-user-name" \
    My-app-image

    クラウドプロバイダの使用時に環境変数を設定するプロセスでは、一般的には、シークレットマネージャを使用し、それらのシークレットの値を環境変数にリンクすることになります。

実行して確認

  1. Node.js エージェントのリライタCLI を使用する場合は、エージェントのリライタCLIの説明を参照して下さい。

  2. アプリケーションを起動する際に、Contrastエージェントを先にロードしておく必要があります。通常は、これはDockerfileのCMD文で行いますが、package.jsonに定義したnpmスクリプトも使用できます。

    例えば、通常アプリケーションを次のように起動する場合:

    CMD [“node”, “app”]

    次のコマンドを使用すると、Contrastを有効にしてアプリケーションを実行できます。

    CMD [“node”, “--import”, “@contrast/agent”, “app”]
  3. エージェントが起動すると、エージェントの認証キーを使用してContrastサーバへの接続を試みます。

    ヒント

    エージェントの認証情報を保護するために、Docker secretを利用して、デプロイ時に環境変数として渡すこともできます。例:

    docker run 
    -e CONTRAST__API_ 
    -e CONTRAST__API__API_KEY=<value> 
    -e CONTRAST__API__SERVICE_KEY=<value> 
    -e CONTRAST__API__USER_NAME=<value> 
    -e CONTRAST__SERVER__ENVIRONMENT=<value> image_with_contrast
  4. コンテナのログのアクティビティをチェックして、Contrastが実行されていることを確認します。

    例えば、ログアクティビティは以下のようになります。

    2025-01-02 10:54:46 {"level":30,"time":1735833286319,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","msg":"Starting @contrast/agent v5.23.0"}
    2025-01-02 10:54:46 {"level":30,"time":1735833286319,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","config":{"_errors":[],"enable":"true","api":{"enable":"true","url":"https://teamserver-darpa-agents.contsec.com/Contrast","api_key":"contrast-redacted-api.api_key","service_key":"contrast-redacted-api.service_key","user_name":"agent_b47d608e-1971-4560-961c-a55bd4111b61@Alexstestorg","token":"contrast-redacted-api.token","proxy":{"enable":"false","url":"undefined"}},"agent":{"stack_trace_limit":"10","stack_trace_filters":"agent-,@contrast,node-agent","diagnostics":{"enable":"true","report_path":"/juice-shop"},"route_coverage":{"enable":"true"},"reporters":{"file":"undefined"},"heap_dump":{"enable":"false","path":"contrast_heap_dumps","delay_ms":"10000","window_ms":"10000","count":"5"},"polling":{"app_activity_ms":"30000","app_settings_ms":"30000","app_update_ms":"30000","server_settings_ms":"30000"},"logger":{"path":"/juice-shop/contrast.log","level":"info","append":"true","stdout":"true"},"security_logger":{"path":"/juice-shop/security.log","level":"error","stdout":"false","syslog":{"enable":"false","ip":"127.0.0.1","port":"514","facility":"19","severity_exploited":"alert","severity_blocked":"notice","severity_blocked_perimiter":"notice","severity_probed":"warning","severity_suspicious":"warning"}},"node":{"app_root":"/juice-shop","cmd_ignore_list":"","exclusive_entrypoint":"undefined","rewrite":{"enable":"true","cache":{"enable":"true","path":"/juice-shop/.contrast"}},"source_maps":{"enable":"true"},"library_usage":{"reporting":{"enable":"true","interval_ms":"100"}},"metrics":{"enable":"true","warn_ms":"5000"},"npm_path":"npm"}},"inventory":{"analyze_libraries":"true","gather_metadata_via":"undefined"},"assess":{"enable":"false","probabilistic_sampling":{"enable":"false","base_probability":"0.1","route_monitor":{"enable":"true","ttl_ms":"1800000"}},"tags":"undefined","stacktraces":"ALL","max_context_source_events":"150","max_propagation_events":"500","safe_positives":{"enable":"false"},"trust_custom_validators":"false"},"protect":{"enable":"false","probe_analysis":{"enable":"true"},"rules":{"disabled_rules":"","cmd-injection":{"mode":"off"},"cmd-injection-command-backdoors":{"mode":"off"},"cmd-injection-semantic-chained-commands":{"mode":"off"},"cmd-injection-semantic-dangerous-paths":{"mode":"off"},"crypto-bad-mac":{"mode":"off"},"crypto-bad-ciphers":{"mode":"off"},"crypto-weak-randomness":{"mode":"off"},"method-tampering":{"mode":"off"},"nosql-injection":{"mode":"off"},"nosql-injection-mongo":{"mode":"off"},"path-traversal":{"mode":"off"},"path-traversal-semantic-file-security-bypass":{"mode":"off"},"reflected-xss":{"mode":"off"},"sql-injection":{"mode":"off"},"ssjs-injection":{"mode":"off"},"ssrf":{"mode":"off"},"unsafe-code-execution":{"mode":"off"},"unsafe-file-upload":{"mode":"off"},"untrusted-deserialization":{"mode":"off"},"xxe":{"mode":"off"},"unvalidated-redirect":{"mode":"off"}}},"application":{"name":"mw-juice-slim","path":"/","group":"undefined","code":"undefined","version":"undefined","tags":"undefined","metadata":"undefined","session_id":"undefined","session_metadata":"undefined"},"server":{"name":"5d9ee61ac84f","type":"Node.js v20.15.0","environment":"undefined","tags":"undefined","version":"undefined","discover_cloud_resource":"true"}},"msg":"Agent configuration"}
    2025-01-02 10:54:46 {"level":30,"time":1735833286328,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","strategy":1,"msg":"updating assess sampler"}
    2025-01-02 10:54:48 {"level":30,"time":1735833287906,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","msg":"Received new log level: debug from server-features"}
    2025-01-02 10:54:48 {"level":30,"time":1735833287907,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","msg":"assess sampling disabled"}
    2025-01-02 10:54:48 {"level":30,"time":1735833287907,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","enabledRules":["bot-blocker","cmd-injection","cmd-injection-command-backdoors","cmd-injection-semantic-chained-commands","cmd-injection-semantic-dangerous-paths","crypto-bad-mac","crypto-bad-ciphers","crypto-weak-randomness","ip-denylist","method-tampering","nosql-injection","nosql-injection-mongo","path-traversal","path-traversal-semantic-file-security-bypass","reflected-xss","sql-injection","ssjs-injection","ssrf","unsafe-code-execution","unsafe-file-upload","untrusted-deserialization","virtual-patch","xxe","unvalidated-redirect","autocomplete-missing","cache-controls-missing","clickjacking-control-missing","parameter-pollution","csp-header-missing","csp-header-insecure","hsts-header-missing","x-powered-by-header","xcontenttype-header-missing","xxssprotection-header-disabled","httponly","secure-flag-missing"],"msg":"Assess policy enabled rules updated"}
    2025-01-02 10:54:48 {"level":30,"time":1735833287907,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","policy":{"exclusions":{"url":[],"querystring":[],"header":[],"body":[],"cookie":[],"parameter":[]},"bot-blocker":"block_at_perimeter","cmd-injection":"monitor","cmd-injection-command-backdoors":"monitor","cmd-injection-semantic-chained-commands":"monitor","cmd-injection-semantic-dangerous-paths":"monitor","crypto-bad-mac":"off","crypto-bad-ciphers":"off","crypto-weak-randomness":"off","ip-denylist":"off","method-tampering":"monitor","nosql-injection":"monitor","nosql-injection-mongo":"monitor","path-traversal":"monitor","path-traversal-semantic-file-security-bypass":"monitor","reflected-xss":"monitor","sql-injection":"monitor","ssjs-injection":"monitor","ssrf":"off","unsafe-code-execution":"off","unsafe-file-upload":"off","untrusted-deserialization":"monitor","virtual-patch":"off","xxe":"monitor","unvalidated-redirect":"off","rulesMask":510},"msg":"Protect policy updated"}
    2025-01-02 10:54:53 {"level":30,"time":1735833293571,"tid":2,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","msg":"Received new log level: debug from server-features"}
    2025-01-02 10:54:53 {"level":30,"time":1735833293437,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","msg":"The Contrast Node Agent collects usage data in order to help us improve compatibility and security coverage.\nThe data is anonymous and does not contain application data. It is collected by Contrast and is never shared.\nYou can opt-out of telemetry by setting the CONTRAST_AGENT_TELEMETRY_OPTOUT environment variable to '1' or 'true'.\n"}
    2025-01-02 10:54:53 {"level":20,"time":1735833293504,"tid":0,"pid":1,"hostname":"5d9ee61ac84f","name":"contrast","msg":"deploying function toString patch"}
    2025-01-02 10:55:00 info: Detected Node.js version v20.15.0 (OK)
    2025-01-02 10:55:00 info: Detected OS linux (OK)
    2025-01-02 10:55:00 info: Detected CPU arm64 (OK)
    ....

関連項目

Contrastサポートポータル:KubernetesでのNode.jsエージェント

Contrastサポートポータル:AWS FargateとContrastエージェント