REST API と自動化

SUSE® Security 自動化

には、CI/CD ワークフロー全体をサポートする多くの自動化機能SUSE® Securityがあります。具体的には、以下のものが含まれます:

  • ビルド中の自動スキャンのための Jenkins プラグイン

  • リポジトリ監視を自動化するためのレジストリスキャン

  • 不正なデプロイを許可/拒否するための入場管理ポリシー

  • ホスト上で自動的に実行される CIS ベンチマーク

  • Kubernetes への自動デプロイのための GitHub 上の Helm チャート

  • セキュリティイベントへの応答を自動化するための応答ルール

  • 任意の SUSE® Security 機能の自動化を構築するための REST API

REST API

SUSE® Security ソリューションは REST API を使用して管理できます。以下は、REST API を使用した自動化の一般的な例です。REST API の yaml ドキュメントは、Swagger 2.0 ビューアで最もよく表示されます。REST API ドキュメントは、swagger.io などのリーダーで最もよく表示される yaml ファイルにあります。

最新の更新は こちら で見つけることができます。また、SUSE® Security GitHub ソースコード リポジトリ にもあります。 メイントラックの apis.yaml には、未リリースの機能が含まれている場合があります。 適切なリリースバージョンのソースコードをダウンロードし、controller/api フォルダーから apis.yaml を抽出することをお勧めします。

ユーザー名/パスワードを用いた REST API 呼び出しの場合は、完了後に必ず /v1/auth に対して DELETE 呼び出しを行ってください。各ユーザーに対して最大32の同時セッションがあります。これを超えると、認証エラーが発生します。

SUSE® Securityは、検出されたセキュリティイベントや脆弱性に対する一般的な応答を自動化するための応答ルールもサポートしています。詳細については、セキュリティポリシー → 応答ルールのセクションを参照してください。

KubernetesでREST APIを公開する

Kubernetesクラスターの外部からアクセスするためにREST APIを公開するには、ポート10443を有効にします。

apiVersion: v1
kind: Service
metadata:
  name: neuvector-svc-controller-api
  namespace: neuvector
spec:
  ports:
    - port: 10443
      name: controller-api
      protocol: TCP
  type: LoadBalancer
  selector:
    app: neuvector-controller-pod

`type: NodePort`はLoadBalancerの代わりに使用することもできます。

LoadBalancerタイプを使用する場合は、以下の例で_controllerIP_をロードバランサーの外部IPまたはURLに設定してください。

REST APIの認証

REST APIは、ユーザー名/パスワードとトークンの2種類の認証をサポートしています。両方とも設定→ユーザー、APIキーとロールで構成でき、デフォルトまたはカスタムロールに関連付けてアクセス権を制限できます。以下の例は、最初にトークンが作成され、その後のREST API呼び出しで使用されるユーザー名/パスワードベースの認証を示しています。トークンを使用する場合は、各REST API呼び出しで直接使用できます。注意: ユーザー名ベースの接続には同時セッションの数に制限があるため、終了時に以下に示すようにユーザー名トークンを削除することが重要です。トークンベースの認証には制限はありませんが、作成時に選択した時間制限に従って期限切れになります。

トークンベースの認証については、以下のスクリーンショットと例の呼び出しを参照してください。作成後は秘密とトークンを必ずコピーしてください。画面が閉じられた後は、これを取得する方法がありません。

token

token

token

スクリプトから脆弱性スキャンをトリガーする

SUSE® Securityは、自動的に画像の脆弱性をスキャンするようにトリガーできます。これは、監視対象としてレジストリ/リポジトリを構成するか、SUSE® Security Jenkinsプラグインを使用する、またはREST APIを使用することで実行できます。詳細については、スキャンとコンプライアンスのセクションをご覧ください。

以下のサンプルスクリプトは、コンテナをリモートでプルし、実行し、スキャンする方法を示しています。これは、Jenkinsタスク(リモートシェル)または任意のCI/CDツールからトリガーできます。JSONパーサーツール(jq)も使用されます。

スクリプトにコントローラーのIPアドレスを入力し、スキャンしたいコンテナイメージ名に変更することを忘れないでください。また、ユーザー名/パスワードフィールドを更新してください。

詳しくは、ここをクリックしてください。
_curCase_=`echo $0 | awk -F"." '{print $(NF-1)}' | awk -F"/" '{print $NF}'`
_DESC_="able to scan ubuntu:16.04 image"
_ERRCODE_=0
_ERRTYPE_=1
_RESULT_="pass"

# please remember to specify the controller ip address here
_controllerIP_="<your_controller_ip>"
_controllerRESTAPIPort_="10443"
_neuvectorUsername_="admin"
_neuvectorPassword_="admin"
_registryURL_=""
_registryUsername_=""
_registryPassword_=""
_repository_="alpine"
_tag_="latest"

curl -k -H "Content-Type: application/json" -d '{"password": {"username": "'$_neuvectorUsername_'", "password": "'$_neuvectorPassword_'"}}' "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/auth" > /dev/null 2>&1 > token.json
_TOKEN_=`cat token.json | jq -r '.token.token'`
echo `date +%Y%m%d_%H%M%S` scanning an image ...
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"request": {"registry": "'$_registryURL_'", "username": "'$_registryUsername_'", "password": "'$_registryPassword_'", "repository": "'$_repository_'", "tag": "'$_tag_'"}}' "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/scan/repository" > /dev/null 2>&1 > scan_repository.json

while [ `wc -c < scan_repository.json` = "0" ]; do
    echo `date +%Y%m%d_%H%M%S` scanning is still in progress ...
    sleep 5
    curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"request": {"registry": "'$_registryURL_'", "username": "'$_registryUsername_'", "password": "'$_registryPassword_'", "repository": "'$_repository_'", "tag": "'$_tag_'"}}' "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/scan/repository" > /dev/null 2>&1 > scan_repository.json
done

echo `date +%Y%m%d_%H%M%S` log out
curl -k -X 'DELETE' -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/auth" > /dev/null 2>&1
cat scan_repository.json | jq .

rm *.json
echo `date +%Y%m%d_%H%M%S` [$_curCase_] $_DESC_: $_RESULT_-$_ERRCODE_

jqをインストールする必要がある場合があります。

sudo zypper install jq

Kubernetesベースのデプロイメントの場合、コントローラーIPを次のように設定できます:

_podNAME_=`kubectl get pod -n neuvector -o wide | grep "allinone\|controller" | head -n 1 | awk '{print $1}'`
_controllerIP_=`kubectl exec $_podNAME_ -n neuvector -- consul info | grep leader_addr | awk -F":| " '{print $3}'`

複数のコントローラーのデプロイメントでは、リクエストは単一のコントローラーIPに送信される必要があるため、長時間実行されるイメージスキャンのステータスに関する複数のリクエストは、スキャンを実行しているコントローラーに送信されます。

レジストリではなくローカルでスキャンする場合:

curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"request": {"tag": "3.4", "repository": "nvlab/alpine", "scan_layers": true}}' "https://$_controllerIP_:443/v1/scan/repository"

サンプル出力:

詳しくは、ここをクリックしてください。
{
  "report": {
    "image_id": "c7fc7faf8c28d48044763609508ebeebd912ad6141a722386b89d044b62e4d45",
    "registry": "",
    "repository": "nvlab/alpine",
    "tag": "3.4",
    "digest": "sha256:2441496fb9f0d938e5f8b27aba5cc367b24078225ceed82a9a5e67f0d6738c80",
    "base_os": "alpine:3.4.6",
    "cvedb_version": "1.568",
    "vulnerabilities": [
      {
        "name": "CVE-2018-0732",
        "score": 5,
        "severity": "Medium",
        "vectors": "AV:N/AC:L/Au:N/C:N/I:N/A:P",
        "description": "During key agreement in a TLS handshake using a DH(E) based ciphersuite a malicious server can send a very large prime value to the client. This will cause the client to spend an unreasonably long period of time generating a key for this prime resulting in a hang until the client has finished. This could be exploited in a Denial Of Service attack. Fixed in OpenSSL 1.1.0i-dev (Affected 1.1.0-1.1.0h). Fixed in OpenSSL 1.0.2p-dev (Affected 1.0.2-1.0.2o).",
        "package_name": "openssl",
        "package_version": "1.0.2n-r0",
        "fixed_version": "1.0.2o-r1",
        "link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0732",
        "score_v3": 7.5,
        "vectors_v3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
      },
                  ...
    ],
    "layers": [
      {
        "digest": "c68318b6ae6a2234d575c4b6b33844e3e937cf608c988a0263345c1abc236c14",
        "cmds": "/bin/sh",
        "vulnerabilities": [
          {
            "name": "CVE-2018-0732",
            "score": 5,
            "severity": "Medium",
            "vectors": "AV:N/AC:L/Au:N/C:N/I:N/A:P",
            "description": "During key agreement in a TLS handshake using a DH(E) based ciphersuite a malicious server can send a very large prime value to the client. This will cause the client to spend an unreasonably long period of time generating a key for this prime resulting in a hang until the client has finished. This could be exploited in a Denial Of Service attack. Fixed in OpenSSL 1.1.0i-dev (Affected 1.1.0-1.1.0h). Fixed in OpenSSL 1.0.2p-dev (Affected 1.0.2-1.0.2o).",
            "package_name": "openssl",
            "package_version": "1.0.2n-r0",
            "fixed_version": "1.0.2o-r1",
            "link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0732",
            "score_v3": 7.5,
            "vectors_v3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
                                  ...
        ],
        "size": 5060096
      }
    ]
  }
}

ポリシールールを自動的に作成する

SUSE® Securityポリシーコントローラーで新しいルールを作成するには、FROMおよびTOフィールドのグループが最初に存在する必要があります。以下のサンプルは、コンテナラベルnv-service-type=dataに基づいて新しいグループを作成し、ラベルnv-service-type=websiteの別のグループを作成します。次に、mysqlプロトコルのみを使用して、wordpressコンテナからmysqlコンテナへのトラフィックを許可するルールが作成されます。

コントローラーへのアクセスのためにユーザー名とパスワードを更新することを忘れないでください。

#!/bin/sh
TOKEN_JSON=$(curl -k -H "Content-Type: application/json" -d '{"password": {"username": "admin", "password": "admin"}}' "https://`docker inspect neuvector.allinone | jq -r '.[0].NetworkSettings.IPAddress'`:10443/v1/auth")
_TOKEN_=`echo $TOKEN_JSON | jq -r '.token.token'`
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"config": {"name": "mydb", "criteria": [{"value": "data", "key": "nv.service.type", "op": "="}]}}' "https://`docker inspect neuvector.allinone | jq -r '.[0].NetworkSettings.IPAddress'`:10443/v1/group"
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"config": {"name": "mywp", "criteria": [{"value": "website", "key": "nv.service.type", "op": "="}]}}' "https://`docker inspect neuvector.allinone | jq -r '.[0].NetworkSettings.IPAddress'`:10443/v1/group"
curl -k -X "PATCH" -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"insert": {"rules": [{"comment": "Custom WP Rule", "from": "mywp", "applications": ["MYSQL"], "ports": "any", "to": "mydb", "action": "allow", "id": 0}], "after": 0}}' "https://`docker inspect neuvector.allinone | jq -r '.[0].NetworkSettings.IPAddress'`:10443/v1/policy/rule"
curl -k -X "DELETE" -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" "https://`docker inspect neuvector.allinone | jq -r '.[0].NetworkSettings.IPAddress'`:10443/v1/auth"

グループがすでにSUSE® Securityに存在する場合、新しいルールを作成でき、グループ作成手順をスキップできます。この例では、終了時に認証トークンも削除されます。ルールID番号を指定でき、SUSE® Securityはルールを数値順に実行します(最小から最大へ)。

エクスポート/インポート 設定ファイル

ここに SUSE® Security 設定ファイルを自動的にバックアップするサンプルがあります。すべての設定(ポリシー、ユーザー、設定など)をエクスポートするか、ポリシーのみをエクスポートするかを選択できます。

これらのサンプルは例として提供されており、特定のエンタープライズサポート契約が締結されていない限り、公式にサポートされていません。

すべての設定をエクスポートするには:

./config.py export -u admin -w admin -s $_controllerIP_ -p $_controllerPort_ -f $_FILENAME_ # exporting the configuration with all settings

ポリシーのみをエクスポートするには:

./config.py export -u admin -w admin -s $_controllerIP_ -p $_controllerPort_ -f $_FILENAME_ --section policy # exporting the configuration with policy only

ファイルをインポートするには:

./config.py import -u admin -w admin -s $_controllerIP_ -p $_controllerPort_ -f $_FILENAME_ # importing the configuration

サンプルPythonファイル config.py、client.py、およびmultipart.pyが含まれています。サンプルファイルをダウンロード:インポートエクスポート。上記のコマンドを実行するために、すべてのファイルを1つのフォルダーに入れてください。スクリプトを実行するために、いくつかのPythonモジュールをインストールする必要があるかもしれません。

sudo pip install requests six

ユーザーパスワードの設定または変更

ユーザー管理のためにREST API呼び出しを使用してください。

curl -s -k -H 'Content-Type: application/json' -H 'X-Auth-Token: c64125decb31e6d3125da45cba0f5025' https://127.0.0.1:10443/v1/user/admin -X PATCH -d '{"config":{"fullname":"admin","password":"admin","new_password":"NEWPASS"}}'

コンテナでのパケットキャプチャの開始

コンテナが疑わしい動作を示す場合は、パケットキャプチャを開始してください。

#!/bin/sh
TOKEN_JSON=$(curl _k _H "Content_Type: application/json" _d '{"password": {"username": "admin", "password": "admin"}}' "https://`docker inspect neuvector.allinone | jq _r '.[0].NetworkSettings.IPAddress'`:10443/v1/auth")
_TOKEN_=`echo $TOKEN_JSON | jq -r '.token.token'`
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"sniffer":{"file_number":1,"filter":"port 1381"}}' "https://`docker inspect neuvector.allinone | jq -r '.[0].NetworkSettings.IPAddress'`:10443/v1/sniffer?f_workload=`docker inspect neuvector.allinone | jq -r .[0].Id`"

スニファーセッションが永遠に実行されないように、しばらくしてから停止することを忘れないでください。回転するファイルの数は最大50です。

EULAを確認して受け入れてください (新しいデプロイメント)

上記のように認証トークンを取得してください。コントローラーのIPアドレスを適切に自分のものに置き換えてください。

curl -s -k -H 'Content-Type: application/json' -H 'X-Auth-Token: $_TOKEN_' https://127.0.0.1:10443/v1/eula | jq .
{
  "eula": {
    "accepted":false
  }
}

EULAを受け入れる

curl -s -k -H 'Content-Type: application/json' -H 'X-Auth-Token: $_TOKEN_' -d '{"eula":{"accepted":true}}' https://127.0.0.1:10443/v1/eula

その後、再度EULAを確認してください。

レジストリスキャンを設定する

curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"request": {"registry": "https://registry.connect.redhat.com", "username": "username", "password": "password", "tag": "latest", "repository": "neuvector/enforcer"}}' "https://controller:port/v1/scan/repository"

名前空間内のすべてのポッドでパケットキャプチャを有効にする

詳しくは、ここをクリックしてください。
#!/bin/bash
#set -x

hash curl 2>/dev/null || { echo >&2 "Required curl but it's not installed.  Aborting."; exit 1; }
hash jq 2>/dev/null || { echo >&2 "Required jq but it's not installed.  Aborting."; exit 1;}

script="$0"
usage() {
    echo "Usage: $script -n [namespace] -d [pcap duration (seconds)] -l [https://nvserver:10443]" 1>&2;
    exit 1;
}

while getopts ":n:d:l:h" opt; do
    case $opt in
        n)
            NAMESPACE=$OPTARG
            ;;
        d)
            DURATION=$OPTARG
            ;;
        l)  URL="$OPTARG/v1"
            ;;
        h)
            usage
            ;;
        \?)
            echo "Invalid option, $OPTARG.  Try -h for help." 1>&2
            ;;
        :)
            echo "Invalid option: $OPTARG requires an argument" 1>&2
    esac
done

if [ ! "$NAMESPACE" ] || [ ! "$DURATION" ] || [ ! "$URL" ]
then
    usage
    exit 1
fi

count=0
for i in `kubectl -n $NAMESPACE get pods -o wide 2> /dev/null | tail -n +2 | awk '{print $1}' | sed 's|\(.*\)-.*|\1|' | uniq`;
do
    CHOICE1[count]=$i
    count=$count+1
done

if [ -z ${CHOICE1[0]} ]; then
    echo "No pods found in $NAMESPACE."
    exit 1
else
    for i in "${!CHOICE1[@]}"
    do
        echo "$i : ${CHOICE1[$i]}"
    done
    read -p "Packet capture on which pod group? " -r
    if [ -n $REPLY ]; then
        POD_STRING=${CHOICE1[$REPLY]}
        echo $POD_STRING " selected."
    else
        exit 1
    fi
fi

sniffer_start() {
    URI="/sniffer?f_workload=$1"
    sniff_id=$(curl -ks --location --request POST ${URL}${URI} "${curlHeaders[@]}" --data-raw '{ "sniffer": { "file_number": 1, "filter": "" }}' | jq .result.id)
    echo $sniff_id
}

sniffer_stop() {
    URI="/sniffer/stop/${1}"
    status_code=`curl -ks -w "%{http_code}" --location --request PATCH ${URL}${URI} "${curlHeaders[@]}"`
    echo $status_code
}

sniffer_pcap_get() {
    URI="/sniffer/${1}/pcap"
    status_code=`curl -ks -w "%{http_code}" --location --request GET ${URL}${URI} "${curlHeaders[@]}" -o $1.pcap`
    echo $status_code
}

sniffer_pcap_delete() {
    URI="/sniffer/${1}"
    status_code=`curl -ks -w "%{http_code}" --location --request DELETE ${URL}${URI} "${curlHeaders[@]}"`
    echo $status_code
}

show_menu() {
    count=0
    for i in "Exit script" "Start packet capture for $DURATION seconds" "Download packet capture from pods" "Delete packet capture from pods";
    do
        CHOICE2[count]=$i
        count=$count+1
    done
        echo
        echo "Selections:"
    for i in "${!CHOICE2[@]}"
    do
        echo "$i : ${CHOICE2[$i]}"
    done
}

get_token() {
read -p "Enter {product-name} Username: " USER
if [ -z $USER ]; then
    echo "Blank username, exiting..."
    exit 1
fi
read -s -p "Enter password: " PASS
if [ -z $PASS ]; then
    echo
    echo "Blank password, exiting..."
    exit 1
fi

TOKEN=`curl -ks --location --request POST ${URL}/auth \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--data-raw '{"password": {"username": "'$USER'", "password": "'$PASS'"}}'|jq .token.token`
echo $TOKEN
}

TOKEN=$(get_token)
while [ "$TOKEN" = "null" ]; do
    echo
    echo "Authenticating failed, retry."
    TOKEN=$(get_token)
done

TOKEN=${TOKEN:1:${#TOKEN}-2}
echo
declare -a curlHeaders=('-H' "Content-Type: application/json" '-H' "X-Auth-Token: $TOKEN")
echo "Pulling worklods from $URL"
declare -a workloads="($(
    curl -ks --location --request GET ${URL}/workload "${curlHeaders[@]}" \
    | jq '.workloads[] | select(.display_name | startswith("'${POD_STRING}'"))| select(.domain=="'$NAMESPACE'" and .cap_sniff==true) | .display_name + "::" +.id' -r
))"

if [ ${#workloads[@]} -eq 0 ]; then
    echo
    echo "No pods is capable of packet capture.  Only ethernet IP part of Kubernetes CIDR can packet capture."
    exit 1
else
    echo
    echo "List of Pods to perform capture on."
    echo "Pod Name : ID"
    for pods in "${workloads[@]}" ; do
        POD_NAME="${pods%%::*}"
        POD_ID="${pods##*::}"
        echo "$POD_NAME : $POD_ID"
    done
fi

while :; do
    show_menu
    read -p "Choice? " -r
    if [ -n $REPLY ]; then
        case "$REPLY" in
            0)
                exit 0;
                ;;
            1)
                counter=0
                declare -a sniffs;
                for pods in "${workloads[@]}"; do
                    POD_ID="${pods##*::}"
                    sniff_id="$(sniffer_start $POD_ID)";
                    sniffs[$counter]=$sniff_id
                    counter=$((counter+1))
                done
                echo "Running pcap for ~$DURATION seconds.";
                sleep $DURATION;
                for sniff_id in "${sniffs[@]}"; do
                    sniff_id=${sniff_id:1:${#sniff_id}-2}
                    status="$(sniffer_stop $sniff_id)";
                done
                ;;
            2)
                for sniff_id in "${sniffs[@]}"; do
                    sniff_id=${sniff_id:1:${#sniff_id}-2}
                    status="$(sniffer_pcap_get $sniff_id)";
                done
                ;;
            3)
                for sniff_id in "${sniffs[@]}"; do
                    sniff_id=${sniff_id:1:${#sniff_id}-2}
                    status="$(sniffer_pcap_delete $sniff_id)";
                done
                ;;
        esac
    else
        exit 1
    fi
done

コンテナ隔離を有効または無効にする

隔離するためのAPI呼び出しは、次のボディを持つ/v1/workload/:idへのPATCHです。ワークロードIDはコンテナ/ポッドIDです。

--data-raw '{
    "config": {
        "quarantine": true,
        "wire": "default",
        "quarantine_reason": "violation"
    }
}'

SUSE® Securityサポートのためのデバッグモードを有効にする

IP、ユーザー、パスワードでアクセストークンを設定する:

_controllerIP_="<your_controller_ip>"
_controllerRESTAPIPort_="10443"
_neuvectorUsername_="admin"
_neuvectorPassword_="admin"

認証トークンを取得する

curl -k -H "Content-Type: application/json" -d '{"password": {"username": "'$_neuvectorUsername_'", "password": "'$_neuvectorPassword_'"}}' "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/auth" > /dev/null 2>&1 > token.json
_TOKEN_=`cat token.json | jq -r '.token.token'`

デバッグモードを有効にする

curl -X PATCH -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"config": {"controller_debug": ["cpath", "conn"]}}' "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/system/config"  > /dev/null 2>&1   > set_debug.json
#debug options - cpath, conn, mutex, scan, cluster , all

クラスター内のすべてのコントローラーでデバッグを無効にする

curl -X PATCH -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"config": {"controller_debug": []}}' "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/system/config"  > /dev/null 2>&1   > set_debug.json

クラスター内のコントローラーデバッグステータスを確認する

curl  -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_"  "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/system/config"  > /dev/null 2>&1   > system_setting.json

cat system_setting.json | jq .config.controller_debug

Logout (ログアウト)

echo `date +%Y%m%d_%H%M%S` log out
curl -k -X 'DELETE' -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" "https://$_controllerIP_:$_controllerRESTAPIPort_/v1/auth" > /dev/null 2>&1

脆弱性がベースイメージ階層に存在するか報告する

REST APIを使用してイメージをスキャンする際、ベースイメージ内のCVEを特定するためには、API呼び出しでベースイメージを指定する必要があります。以下の例のように指定してください。

curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" -d '{"request": {"registry": "https://registry.hub.docker.com/", "repository": "garricktam/debian", "tag": "latest", "scan_layers": false, "base_image": "2244...../nodejs:3.2......"}}' "https://$RESTURL/v1/scan/repository"
{noformat}

制限

スキャン対象のイメージがリモートイメージで"registry"が指定されている場合、ベースイメージもリモートイメージでなければならず、名前はhttpまたはhttpsで始まる必要があります。 スキャン対象のイメージがローカルイメージの場合、ベースイメージもローカルイメージでなければなりません。

などです。別の例をあげれば、

{"request": {"repository": "neuvector/manager", "tag": "4.0.2", "scan_layers": true, "base_image": "alpine:3.12.0"}}
{"request": {"registry": "https://10.1.127.12:5000/", "repository": "neuvector/manager", "tag": "4.0.0", "scan_layers": true, "base_image": "https://registry.hub.docker.com/alpine:3.12.0"}}
{"request": {"repository": "neuvector/manager", "tag": "4.0.2", "scan_layers": true, "base_image": "10.1.127.12:5000/neuvector/manager:4.0.2”}}

CVEデータベースのバージョンと日付を取得する

curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" "https://127.0.0.1:10443/v1/scan/scanner"

出力:

{
    "scanners": [
        {
            "cvedb_create_time": "2020-07-07T10:34:04Z",
            "cvedb_version": "1.950",
            "id": "0f043705948557828ac1831ee596588a0d050950113117ddd19ecd604982f4d9",
            "port": 18402,
            "server": "127.0.0.1"
        },
        {
            "cvedb_create_time": "2020-07-07T10:34:04Z",
            "cvedb_version": "1.950",
            "id": "9fa02c644d603f59331c95735158d137002d32a75ed1014326f5039f38d4d717",
            "port": 18402,
            "server": "192.168.9.95"
        }
    ]
}

マスターおよびリモート(ワーカー)クラスターのフェデレーションを管理する

一般的に、フェデレーションメンバーの一覧を取得するには、次のエンドポイントにGETリクエストを送信できます(特定の構文についてはサンプルを参照してください):
https://neuvector-svc-controller.neuvector:10443/v1/fed/member

ConfigMapを通じたフェデレーションの自動化に関する情報は、フェデレーションConfigMapの例のドキュメントをご覧ください。

選択されたフェデレーション管理API:

詳しくは、ここをクリックしてください。
_masterClusterIP_=$1
_workerClusterIP_=$2
# this is used if one of clusters is going to be kicked by master cluster
_CLUSTER_name_=$3

echo `date +%Y%m%d_%H%M%S` [$_curCase_] login as default admin user
curl -k -H "Content-Type: application/json" -d '{"password": {"username": "admin", "password": "admin"}}' "https://$_masterClusterIP_:10443/v1/auth" > /dev/null 2>&1 > ./$_LOGFOLDER_/token.json
_TOKEN_M_=`cat ./$_LOGFOLDER_/token.json | jq -r '.token.token'`

echo `date +%Y%m%d_%H%M%S` [$_curCase_] promote to master cluster
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_M_" -d '{"master_rest_info": {"port": 11443, "server": "'$_masterClusterIP_'"}, "name": "master"}' "https://$_masterClusterIP_:10443/v1/fed/promote" > /dev/null 2>&1
echo `date +%Y%m%d_%H%M%S` [$_curCase_] idle 6 seconds for logon session timeout
sleep 6

echo `date +%Y%m%d_%H%M%S` [$_curCase_] login as default admin user on master cluster
curl -k -H "Content-Type: application/json" -d '{"password": {"username": "admin", "password": "admin"}}' "https://$_masterClusterIP_:10443/v1/auth" > /dev/null 2>&1 > ./token.json
_TOKEN_M_=`cat ./token.json | jq -r '.token.token'`

echo `date +%Y%m%d_%H%M%S` [$_curCase_] checking fed join_token on master cluster
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_M_" "https://$_masterClusterIP_:10443/v1/fed/join_token" > /dev/null 2>&1 > ./join_token.json
cat ./join_token.json | jq -c .
_JOIN_TOKEN_=`cat ./join_token.json | jq -r '.join_token'`

echo `date +%Y%m%d_%H%M%S` [$_curCase_] login as default admin user on worker cluster
curl -k -H "Content-Type: application/json" -d '{"password": {"username": "admin", "password": "admin"}}' "https://$_workerClusterIP_:10443/v1/auth" > /dev/null 2>&1 > ./token.json
_TOKEN_W_=`cat ./token.json | jq -r '.token.token'`

echo `date +%Y%m%d_%H%M%S` [$_curCase_] joining the cluster
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_W_" -d '{"join_token": "'$_JOIN_TOKEN_'", "name": "worker", "joint_rest_info": {"port": 10443, "server": "'$_workerClusterIP_'"}}' "https://$_workerClusterIP_:10443/v1/fed/join" > /dev/null 2>&1
echo `date +%Y%m%d_%H%M%S` [$_curCase_] idle 9 seconds for events
sleep 9

########## whenever there is a change on cluster such as a cluster is kicked/left/joined, run this to check the status ############
echo `date +%Y%m%d_%H%M%S` [$_curCase_] checking fed member on master cluster
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_M_" "https://$_masterClusterIP_:10443/v1/fed/member" > /dev/null 2>&1 > ./fedMember.json
cat ./fedMember.json | jq -c .

echo `date +%Y%m%d_%H%M%S` [$_curCase_] checking fed member on worker cluster
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_W_" "https://$_workerClusterIP_:10443/v1/fed/member" > /dev/null 2>&1 > ./fedMember.json
cat ./fedMember.json | jq -c .
_CLUSTER_id_=`cat ./fedMember.json | jq -r --arg _CLUSTER_name_ "$_CLUSTER_name_" '.joint_clusters[] | select(.name == $_CLUSTER_name_).id'`
###################################################################################################################################

########## for ur information to leave or kick the cluster ############
echo `date +%Y%m%d_%H%M%S` [$_curCase_] requesting to leave on worker cluster
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_W_" -d '{"force": false}' "https://$_workerClusterIP_:10443/v1/fed/leave" > /dev/null 2>&1
echo `date +%Y%m%d_%H%M%S` [$_curCase_] idle 9 seconds for events
sleep 9

echo `date +%Y%m%d_%H%M%S` [$_curCase_] requesting to kick on master cluster, $_CLUSTER_id_
curl -k -X "DELETE" -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_M_" "https://$_masterClusterIP_:10443/v1/fed/cluster/$_CLUSTER_id_" > /dev/null 2>&1
echo `date +%Y%m%d_%H%M%S` [$_curCase_] idle 9 seconds for events
sleep 9
#######################################################################