Kubernetes Agent・Ingress Controller・モジュール

この例では、Next-Gen WAF エージェントは Docker サイドカーとしてインストールされ、ingress-nginx Kubernetes Ingress Controller にインストールされた NGINX 用の Next-Gen WAF ネイティブモジュールと通信します。

Next-Gen WAF エージェントをインフラストラクチャコントローラーに統合する

アプリケーションごとにNext-Gen WAFをインストールするだけでなく、アプリケーションへのすべての外部トラフィックを受信するKubernetesイングレスコントローラーにNext-Gen WAFをインストールすることも可能です。これは、Next-Gen WAFモジュールを搭載したアプリケーションにインストールするのと似ています。

  • Next-Gen WAF モジュールを Ingress Controller にインストールして設定します。

  • sigsci-agentコンテナをIngressポッドに追加し、sigsci-agentのボリュームをマウントします。

  • emptyDir{} ボリュームを追加して、sigsci-agent が一時的なデータを書き込む場所とします。

Kubernetes NGINX ingress controller

Kubernetes NGINX Ingress Controller は、Ingress API の NGINX ベースの実装です。Next-Gen WAF は、NGINX のネイティブモジュールをサポートしています。これにより、既存の ingress-nginx コントローラーに Next-Gen WAF モジュールを簡単にインストールできます。

ベース nginx-ingress-controller をラップして Next-Gen WAF モジュールをインストールする

nginx-ingress-controller をラップするには、ベースコントローラーを使用し、Next-Gen WAF ネイティブ NGINX モジュールをインストールします。sigsci-nginx-ingress-controller リポジトリにはこの例が2つ含まれています。

ビルド済みのコンテナは、次のものを使用してで Docker Hub からプルできます : docker pull signalsciences/sigsci-nginx-ingress-controller:latest

インストール

インストール方法は2つあります。

前提条件

エージェントにアクセスさせたいサイトのエージェントキーをコピーします。エージェントキーは、Next-Gen WAF エージェントパッケージを設定する際に使用します。

オーバーライドを使った Helm 経由のインストール

以下の手順では、オーバーライドファイルを使用して、sigsci-nginx-ingress-controller + sigsci-agent を公式の ingress-nginx チャート経由でインストールする方法を説明します。

  1. ingress-nginxリポジトリを追加します :

    $ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
  2. sigsci-values.yaml ファイルに、エージェントキーSIGSCI_ACCESSKEYIDSIGSCI_SECRETACCESSKEY として追加します。

  3. リリース名 my-ingressdefault 名前空間にインストールします :

    $ helm install -f values-sigsci.yaml my-ingress ingress-nginx/ingress-nginx

    -n フラグを使用して名前空間を指定できます :

    $ helm install -n NAMESPACE -f values-sigsci.yaml my-ingress ingress-nginx/ingress-nginx
  4. 数分後、エージェントが Next-Gen WAF コンソールに表示されます。

  5. Ingress リソースを作成します。この手順はセットアップによって異なり、多くの設定方法に対応しています。基本使用法 - ホストベースのルーティングに関する公式ドキュメントを参照してください。

    Ingress ファイルの例は次のとおりです。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    name: hello-kubernetes-ingress
    #namespace: SET THIS IF NOT IN DEFAULT NAMESPACE
    spec:
    rules:
    - host: example.com
    http:
    paths:
    - pathType: Prefix
    path: /testpath
    backend:
    service:
    name: NAME OF SERVICE
    port:
    number: 80

オーバーライドファイルを使用した Helm のアップグレード

  1. sigsci-values.yaml ファイルで、sigsci-nginx-ingress-controller を最新バージョンに更新して ingress-nginx チャートを更新します :

    controller:
    # Replaces the default nginx-controller image with a custom image that contains the Next-Gen WAF NGINX module
    image:
    repository: signalsciences/sigsci-nginx-ingress-controller
    tag: "latest"
    pullPolicy: IfNotPresent
  2. オーバーライドするファイルを使用して helm upgrade を実行します。この例では、前のセクションで作成した my-ingress リリースに対して helm upgrade を実行しています。

    $ helm upgrade -f sigsci-values.yaml my-ingress ingress-nginx/ingress-nginx

    または

    $ helm upgrade -f sigsci-nginxinc-values.yaml my-ingress ingress-nginx/ingress-nginx

    Ingress がデフォルトの名前空間にない場合は、-n を使用して名前空間を指定します :

    $ helm upgrade -n NAMESPACE -f sigsci-values.yaml my-ingress ingress-nginx/ingress-nginx

    または

    $ helm upgrade -n NAMESPACE -f sigsci-nginxinc-values.yaml my-ingress ingress-nginx/ingress-nginx

リリースをアンインストールする

  1. リリースmy-ingressをアンインストールしてください。

    $ helm uninstall my-ingress
  2. デフォルト名前空間にない場合は、-nを使って名前空間を指定します:

    $ helm uninstall -n NAMESPACE my-ingress

カスタムファイルでインストールする

Next-Gen WAF エージェントを統合する

Next-Gen WAF エージェントは、各 Pod にサイドカーとしてインストールすることも、特定の要件向けにサービスとしてインストールすることもできます。

Kubernetes における Next-Gen WAF エージェントの推奨インストール方法は、sigsci-agent を Pod にサイドカーとして統合することです。これは、sigsci-agent を Kubernetes Pod の追加コンテナとして追加することを意味します。サイドカーとして動作することで、エージェントは Pod 内のアプリケーション/サービスと共にスケーリングすることになり、個別にスケーリングする必要がなくなります。ただし、状況によっては sigsci-agent コンテナをサービスとしてインストールし、アプリケーションとは別にスケーリングした方が適している場合もあります。

sigsci-agentコンテナは、インストールタイプや使用するモジュールに応じてさまざまな方法で構成できます。

コンテナフック preStop を使用して、ポッドのシャットダウンを遅らせ、ドレインタイムアウトを確実に満たすことができます。

preStop:
exec:
command:
- sleep
- "30"

デフォルトでは、エージェントは迅速な起動と、予備的な検査のためのパフォーマンス準備を優先します。ただし、ルールや設定データをロードした後のみトラフィックを検査したい場合、迅速な起動が必ずしも望ましいとは限りません。その場合は、Startup Probe を設定してエージェントの起動を遅延させることを検討してください。

エージェントコンテナイメージの取得と更新

公式の signalsciences/sigsci-agent コンテナイメージが Docker Hubで利用可能です。

独自のイメージをビルドしたい場合や、イメージをカスタマイズする必要がある場合は、sigsci-agent のビルド手順に従ってください。

これらの指示は、latest バージョンのエージェントと imagePullPolicy: Always を参照しており、ローカルに既に存在する場合でも最新のエージェントバージョンを取得します。これは、ドキュメントが古くならないよう、そしてこれを使用している誰もが停滞したままのエージェントを持つことがないようにするためです。ただし、インストールの一貫性を維持する必要がある場合や、エージェントの特定のバージョンを維持する必要がある場合は、この方法はニーズに合わない可能性があります。このような場合は、エージェントのバージョンを指定する必要があります。Docker Hub 上のイメージにはバージョンがタグ付けされており、バージョンのリストは Docker Hub で確認できます

latest イメージを使用するか特定のバージョンを使用するかにかかわらず、エージェントを最新の状態に保つために考慮すべき点がいくつかあります。

latest コンテナイメージを使用する

latest イメージを使用することを選択した場合は、エージェントを最新の状態に保つ方法を検討する必要があります。

  • imagePullPolicy: Always オプションを使用した場合、起動のたびに最新のイメージが取得され、エージェントは継続的に更新を受け取ります。

  • あるいは、起動時に常にプルするのではなく、定期的に手動でローカルキャッシュを更新する方法もあります。

    $ docker pull signalsciences/sigsci-agent:latest

    次に、latestimagePullPolicy: Never 設定で使用して、スタートアップ企業にプルが実行されないようにします (上記のように手動でのみ):

    - name: sigsci-agent
    image: signalsciences/sigsci-agent:latest
    imagePullPolicy: Never
    ...

バージョン管理されたコンテナイメージをご利用ください

特定のバージョンのエージェントを使用するには、latest をエージェントのバージョン(ここでは x.xx.x で表されます)に置き換えてください。この場合、画像は変わらないはずなので、imagePullPolicy: IfNotPresent を変更することもおすすめします。

- name: sigsci-agent
image: signalsciences/sigsci-agent:x.xx.x
imagePullPolicy: IfNotPresent
...

この方法では、指定したエージェントバージョンがプルされ、ローカルにキャッシュされます。この方法を使用する場合、後からエージェントイメージを更新しやすくするため、Helm などを使ってエージェントイメージをパラメータ化することを推奨します。

コンテナイメージにカスタムタグを使用する

ローカルエージェントイメージにカスタムタグを適用することも可能です。これを行うには、エージェントイメージを (バージョンまたは latest で) プルし、カスタムタグを適用し、そのカスタムタグを設定で使用します。ローカルイメージは手動でのみ更新されるように imagePullPolicy: Never を指定する必要があります。その後、エージェントを最新の状態に保つために、ローカルイメージを定期的に更新する必要があります。

例:

$ docker pull signalsciences/sigsci-agent:latest
$ docker tag signalsciences/sigsci-agent:latest signalsciences/sigsci-agent:testing

次に、このイメージタグを設定で使用します。

- name: sigsci-agent
image: signalsciences/sigsci-agent:testing
imagePullPolicy: Never
...

エージェントコンテナを設定する

エージェントの設定は通常、環境変数を通じて行います。ほとんどの設定オプションは環境変数として利用可能です。環境変数名は、設定オプション名をすべて大文字にし、SIGSCI_ を接頭辞として付け、ダッシュ (-) をアンダースコア (_) に置き換えたものになります。たとえば、max-procs オプションは SIGSCI_MAX_PROCS 環境変数になります。利用可能なオプションの詳細については、エージェント設定ドキュメントを参照してください。

sigsci-agent コンテナには設定が必要ないくつかのオプションがあります :

  • エージェント認証情報(Agent Access KeyAgent Secret Key)。

  • 一時ファイルを書き込むためのボリューム。

エージェントの認証情報

sigsci-agent の認証情報は、2 つの環境変数で設定されます。これらの変数を設定しなければ、エージェントは起動しません。

  • SIGSCI_ACCESSKEYID : Agent Access Key は、エージェントが設定されている Next-Gen WAF コントロールパネル上のサイト (ワークスペース) を識別します。

  • SIGSCI_SECRETACCESSKEY: Agent Secret Key はエージェントを認証・認可するための共有秘密鍵です。

これらの値は非常に機密性が高いため、Kubernetes の組み込み secrets 機能を使用することを推奨します。この構成では、エージェントはデプロイ設定内にハードコードされた値を読み取るのではなく、Secrets データから値を取得します。これにより、エージェント認証情報のローテーションも、1か所を変更するだけで管理しやすくなります。

secrets 機能を使うには、value オプションではなく valueFrom オプションを使用します。例 :

env:
- name: SIGSCI_ACCESSKEYID
valueFrom:
secretKeyRef:
# Update my-site-name-here to the correct site (workspace) name or similar identifier
name: sigsci.my-site-name-here
key: accesskeyid
- name: SIGSCI_SECRETACCESSKEY
valueFrom:
secretKeyRef:
# Update my-site-name-here to the correct site (workspace) name or similar identifier
name: sigsci.my-site-name-here
key: secretaccesskey

secrets 機能は、Kubernetes 内のさまざまなストアに秘密を保持します。このガイドでは例として汎用の secret store を使用していますが、同等のストアであればどれでも使用できます。エージェントのシークレットは、以下の例のような YAML を使用して汎用 secret store に追加できます。

apiVersion: v1
kind: Secret
metadata:
name: sigsci.my-site-name-here
stringData:
accesskeyid: 12345678-abcd-1234-abcd-1234567890ab
secretaccesskey: abcdefg_hijklmn_opqrstuvwxy_z0123456789ABCD

これは、次のように kubectl を使用してコマンドラインから作成することもできます。

$ kubectl create secret generic sigsci.my-site-name-here \
--from-literal=accesskeyid=12345678-abcd-1234-abcd-1234567890ab \
--from-literal=secretaccesskey=abcdefg_hijklmn_opqrstuvwxy_z0123456789ABCD

Kubernetes secrets の機能に関する追加情報は、Kubernetes ドキュメントで確認できます。

エージェント一時ボリューム

セキュリティ強化のため、sigsci-agent コンテナはルートファイルシステムを読み取り専用にマウントして実行することを推奨します。ただし、エージェントは RPC 通信用のソケットファイルなどの一時ファイルや、位置情報データなどの定期的に更新されるファイルを書き込む必要があります。

読み取り専用のルートファイルシステムでこれを実現するには、書き込み可能なボリュームをマウントする必要があります。この書き込み可能なボリュームは、同じポッド内の他のコンテナに RPC ソケットファイルを公開するために共有することもできます。

書き込み可能なボリュームを作成する推奨方法は、組み込みの emptyDir ボリュームタイプを使用することです。これは通常、次の例のようにデプロイの volumes セクションで設定します。

volumes:
- name: sigsci-tmp
emptyDir: {}

その後、コンテナはこのボリュームを /sigsci/tmp にマウントします。

volumeMounts:
- name: sigsci-tmp
mountPath: /sigsci/tmp

公式エージェントコンテナイメージのデフォルトでは、一時ボリュームが /sigsci/tmp にマウントされます。エージェントコンテナのために移動する必要がある場合、次のエージェント設定オプションもデフォルトから新しいマウント場所に合わせて変更する必要があります :

  • rpc-address はデフォルトで /sigsci/tmp/sigsci.sock です

  • shared-cache-dir はデフォルトで /sigsci/tmp/cache です

NGINX Ingress controller は、mandatory.yaml ファイルを使用してインストールされます。このファイルには、Generic Ingress Controller デプロイの修正されたテンプレートが含まれています。主な追加点は次のとおりです。

  1. Ingress コンテナを変更してカスタム Ingress コンテナをロードし、モジュール/Ingress コンテナとエージェントサイドカーコンテナ間のソケットファイル通信用のボリュームマウントを追加します。

    ...
    containers:
    - name: nginx-ingress-controller
    image: signalsciences/sigsci-nginx-ingress-controller:latest
    ...
    volumeMounts:
    - name: sigsci-tmp
    mountPath: /sigsci/tmp
    ...
  2. NGINX の設定ファイル (nginx.conf) の Next-Gen WAF モジュールを ConfigMap から読み込みます。

    kind: ConfigMap
    apiVersion: v1
    data:
    main-snippet: load_module /usr/lib/nginx/modules/ngx_http_sigsci_nxo_module-1.17.7.so;
    http-snippet: sigsci_agent_host unix:/sigsci/tmp/sigsci.sock;
    metadata:
    name: nginx-configuration
    namespace: ingress-nginx
    labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  3. Next-Gen WAF エージェント用のコンテナを追加します。

    ...
    containers:
    ...
    # Next-Gen WAF agent running in default RPC mode
    - name: sigsci-agent
    image: signalsciences/sigsci-agent:latest
    imagePullPolicy: IfNotPresent
    env:
    - name: SIGSCI_ACCESSKEYID
    valueFrom:
    secretKeyRef:
    # This secret needs added (see docs on sigsci secrets)
    name: sigsci.my-site-name-here
    key: accesskeyid
    - name: SIGSCI_SECRETACCESSKEY
    valueFrom:
    secretKeyRef:
    # This secret needs added (see docs on sigsci secrets)
    name: sigsci.my-site-name-here
    key: secretaccesskey
    securityContext:
    # The sigsci-agent container should run with its root filesystem read only
    readOnlyRootFilesystem: true
    volumeMounts:
    # Default volume mount location for sigsci-agent writeable data (do not change mount path)
    - name: sigsci-tmp
    mountPath: /sigsci/tmp
    ...
  4. 上記で使用したボリュームを定義します。

    ...
    volumes:
    # Define a volume where sigsci-agent will write temp data and share the socket file,
    # which is required with the root filesystem is mounted read only
    - name: sigsci-tmp
    emptyDir: {}
    ...

セットアップ

mandatory.yaml ファイルは ingress-nginx 名前空間内のリソースを作成します。エージェントのアクセスキーを保存するために Kubernetes Secrets を使用する場合は、mandatory.yaml ファイルを実行する前に名前空間とアクセスキーを作成する必要があります。

  1. エージェントキーのシークレットの名前を mandatory.yaml で設定します。

    ...
    env:
    - name: SIGSCI_ACCESSKEYID
    valueFrom:
    secretKeyRef:
    # This secret needs added (see docs on sigsci secrets)
    name: sigsci.my-site-name-here
    key: accesskeyid
    - name: SIGSCI_SECRETACCESSKEY
    valueFrom:
    secretKeyRef:
    # This secret needs added (see docs on sigsci secrets)
    name: sigsci.my-site-name-here
    key: secretaccesskey
    ...
  2. NGINX ingress + Signal Sciences モジュールコンテナをプルまたはビルドします。任意のレジストリとリポジトリ名を設定し、mandatory.yaml に一致するイメージを設定します :

    $ docker pull signalsciences/sigsci-nginx-ingress-controller:latest
  3. 修正された汎用デプロイ (GM) によるデプロイ :

    $ kubectl apply -f mandatory.yaml
  4. Ingress Controller を公開するためのサービスを作成します。必要な手順はクラウドプロバイダーによって異なります。公式の手順については、https://kubernetes.github.io/ingress-nginx/deploy/#environment-specific-instructions をご覧ください。

    以下は service.yaml ファイルの例です。

    kind: Service
    apiVersion: v1
    metadata:
    name: ingress-nginx
    namespace: ingress-nginx
    spec:
    externalTrafficPolicy: Cluster
    selector:
    app.kubernetes.io/name: ingress-nginx
    type: LoadBalancer
    ports:
    - name: http
    port: 80
    targetPort: http
    - name: https
    port: 443
    targetPort: https
  5. Ingress リソースを作成します。以下は Ingress リソースの例です。

    apiVersion: extensions/v1
    kind: Ingress
    metadata:
    name: test-ingress
    namespace: ingress-nginx
    annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
    rules:
    - http:
    paths:
    - path: /testpath
    backend:
    serviceName: nginx
    servicePort: 80