API REST y Automatización

SUSE® Security Automatización

Hay muchas funciones de automatización en SUSE® Security para soportar todo el flujo de trabajo de CI/CD, incluyendo:

  • Complemento de Jenkins para escaneo automatizado durante la compilación

  • Escaneo de registro para automatizar la monitorización de repositorios

  • Políticas de Control de Admisión para permitir/denegar despliegues no autorizados

  • Los benchmarks de CIS se ejecutan automáticamente en los hosts

  • Helm chart en GitHub para despliegue automatizado en Kubernetes

  • Reglas de respuesta para automatizar respuestas a eventos de seguridad

  • API REST para construir la automatización de cualquier función de SUSE® Security

API REST

La solución SUSE® Security se puede gestionar utilizando la API REST. A continuación se presentan ejemplos comunes de automatización utilizando la API REST. El documento yaml de la API REST se visualiza mejor en el visor Swagger 2.0. La documentación de la API REST se encuentra a continuación en un archivo yaml que se visualiza mejor en un lector como swagger.io.

La última actualización se puede encontrar aquí. También en el SUSE® Security código fuente de GitHub repositorio. El apis.yaml de la rama principal puede incluir funciones no publicadas. Se recomienda descargar la versión de código fuente liberada apropiada y extraer el apis.yaml de la carpeta controller/api.

Si estás realizando llamadas a la API REST con nombre de usuario/contraseña, asegúrate de hacer una llamada DELETE a /v1/auth cuando termines. Hay un máximo de 32 sesiones concurrentes para cada usuario. Si se supera este límite, ocurrirá un fallo de autenticación.

SUSE® Security también soporta Reglas de Respuesta para automatizar respuestas comunes a eventos de seguridad o vulnerabilidades detectadas. Por favor, consulta la sección Política de Seguridad → Reglas de Respuesta para más detalles.

Exponer la API REST en Kubernetes

Para exponer la API REST para acceso desde fuera del clúster de Kubernetes, habilita el puerto 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 también puede ser utilizado en lugar de LoadBalancer.

Si utilizas el tipo LoadBalancer, establece el controllerIP en los ejemplos a continuación en la IP externa o URL para el balanceador de carga.

Autenticación para la API REST

La API REST soporta dos tipos de autenticación: nombre de usuario/contraseña y token. Ambos pueden ser configurados en Configuración → Usuarios, Claves API y Roles, y ser asociados con roles predeterminados o personalizados para limitar los privilegios de acceso. Los ejemplos a continuación muestran la autenticación basada en nombre de usuario/contraseña donde se crea primero un token, que luego se utiliza en llamadas posteriores a la API REST. Si utilizas un token, se puede usar directamente en cada llamada a la API REST. Nota: las conexiones basadas en nombre de usuario tienen un número limitado de sesiones concurrentes, por lo que es importante eliminar el token de nombre de usuario como se muestra a continuación cuando termines. La autenticación basada en token no tiene un límite, pero expira según el límite de tiempo seleccionado al ser creado.

Para la autenticación basada en token, consulta las siguientes capturas de pantalla y llamada de ejemplo. Asegúrate de copiar el secreto y el token una vez creados, ya que no hay forma de recuperarlos después de que se cierre la pantalla.

token

token

token

Iniciar el escaneo de vulnerabilidades desde un script

SUSE® Security puede ser activado automáticamente para escanear una imagen en busca de vulnerabilidades. Esto se puede hacer configurando un registro/repositorio para ser monitorizado, utilizando el SUSE® Security complemento de Jenkins, o usando la API REST. Por favor, consulta la sección sobre Escaneo y Cumplimiento para más detalles.

El script de muestra a continuación muestra cómo extraer el contenedor de forma remota, ejecutarlo y escanearlo. Puede ser activado desde una tarea de Jenkins (shell remoto) o cualquier herramienta de CI/CD. También se utiliza una herramienta de análisis JSON (jq).

Asegúrate de introducir la dirección IP del controlador en el script y cambiar el nombre de la imagen del contenedor por el que deseas escanear. Además, actualiza los campos de nombre de usuario/contraseña.

Haga clic aquí para obtener más información
_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_

Puede que necesites instalar jq.

sudo zypper install jq

Para implementaciones basadas en Kubernetes, puedes establecer la IP del controlador de la siguiente manera:

_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}'`

En una implementación de múltiples controladores, las solicitudes deben enviarse a una única IP de controlador para que múltiples solicitudes de estado de escaneos de imágenes de larga duración vayan al controlador que realiza el escaneo.

Para escanear localmente en lugar de en un registro:

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"

Salida de muestra:

Haga clic aquí para obtener más información
{
  "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
      }
    ]
  }
}

Crear Reglas de Directiva Automáticamente

Para crear una nueva regla en el SUSE® Security controlador de directivas, los grupos para los campos FROM y TO deben existir primero. El siguiente ejemplo crea un nuevo Grupo basado en la etiqueta del contenedor nv-service-type=data, y otro Grupo para la etiqueta nv-service-type=website. Luego se crea una regla para permitir el tráfico del contenedor de wordpress al contenedor de mysql utilizando solo el protocolo mysql.

Asegúrate de actualizar el nombre de usuario y la contraseña para acceder al controlador.

#!/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"

Si los Grupos ya existen en SUSE® Security, entonces se puede crear la nueva regla, omitiendo los pasos de creación de Grupos. Este ejemplo también elimina el token de autenticación al final. Ten en cuenta que se puede especificar un número de ID de regla y SUSE® Security ejecuta las reglas en orden numérico de menor a mayor.

Archivo de configuración de exportación/importación

Aquí hay muestras para hacer una copia de seguridad del archivo de configuración SUSE® Security automáticamente. Puedes seleccionar si exportar todos los ajustes de configuración (directiva, usuarios, ajustes, etc.), o solo la directiva.

Estas muestras se proporcionan solo como ejemplos y no están oficialmente soportadas a menos que se haya establecido un acuerdo de soporte empresarial específico.

Para exportar toda la configuración:

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

Para exportar solo la directiva:

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

Para importar el archivo:

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

Archivos de muestra de Python Contiene config.py, client.py y multipart.py. Descargar archivos de muestra: ImportarExportar. Por favor, coloca los tres archivos en una carpeta para ejecutar los comandos anteriores. Es posible que necesites instalar algunos módulos de Python para poder ejecutar el script.

sudo pip install requests six

Establecer o cambiar la contraseña de usuario

Utiliza las llamadas a la API REST para la gestión de usuarios.

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"}}'

Iniciando la captura de paquetes en un contenedor

Cuando un contenedor exhibe un comportamiento sospechoso, inicia una captura de paquetes.

#!/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`"

No olvides detener la sesión del sniffer después de un tiempo para que no se ejecute indefinidamente. El número de archivos a rotar tiene un valor máximo de 50.

Revisa y acepta el EULA (nuevos despliegues)

Obtén el testigo de autenticación como se indicó anteriormente. También reemplaza la dirección IP del controlador por la tuya según corresponda.

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
  }
}

Acepta el 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

Luego revisa el EULA nuevamente.

Configura el escaneo del registro

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"

Habilita la captura de paquetes en todos los pods en un espacio de nombres

Haga clic aquí para obtener más información
#!/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

Habilitar o deshabilitar la cuarentena de contenedores

La llamada a la API para poner en cuarentena es a través de PATCH a /v1/workload/:id con el siguiente cuerpo. El id del workload es el id del contenedor/pod.

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

Habilita el modo de depuración para el soporte de SUSE® Security

Establece el token de acceso con tu IP, usuario, contraseña:

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

Obtén el token de autenticación

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'`

Habilita el modo de depuración

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

Desactiva la depuración en todos los controladores en un clúster

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

Verifica el estado de depuración del controlador en un clúster

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

Cerrar sesión

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

Informa si hay una vulnerabilidad en las capas de la imagen base

Para identificar CVE en la imagen base al usar la API REST para escanear imágenes, la imagen base debe ser identificada en la llamada a la API, como en el ejemplo a continuación.

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}

limitaciones

Si la imagen a escanear es una imagen remota, con "registry" especificado, la imagen base también debe ser una imagen remota, y el nombre debe comenzar con http o https. Si la imagen a escanear es una imagen local, entonces la imagen base también debe ser una imagen local.

Por ejemplo,

{"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”}}

Obtén la versión y la fecha de la base de datos de CVE

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

Salida:

{
    "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"
        }
    ]
}

Gestionar la Federación para Clústeres Maestros y Remotos (Trabajadores)

En general, listar los miembros de la Federación puede utilizar un GET al siguiente endpoint (ver ejemplos para la sintaxis específica): https://neuvector-svc-controller.neuvector:10443/v1/fed/member

Para información sobre la automatización de la Federación a través de ConfigMap, consulta la documentación de Ejemplos de ConfigMap Federados.

APIs de Gestión de la Federación seleccionadas:

Haga clic aquí para obtener más información
_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
#######################################################################