API REST e Automação
SUSE® Security Automação
Existem muitos recursos de automação no SUSE® Security para suportar todo o fluxo de trabalho CI/CD, incluindo:
-
Plug-in do Jenkins para escaneamento automatizado durante a construção
-
Escaneamento de registro para automatizar o monitoramento de repositórios
-
Políticas de controle de acesso para permitir ou negar implantações não autorizadas
-
Benchmarks CIS executados automaticamente em hosts
-
Gráfico Helm no GitHub para implantação automatizada no Kubernetes
-
Regras de resposta para automatizar respostas a eventos de segurança
-
API REST para construir automação de qualquer função do SUSE® Security
API REST
A SUSE® Security solução pode ser gerenciada usando a API REST. Abaixo estão exemplos comuns de automação usando a API REST. O documento yaml da API REST é melhor visualizado no visualizador Swagger 2.0. A documentação da API REST está abaixo em um arquivo yaml que é melhor visualizado em um leitor como swagger.io.
A última atualização pode ser encontrada aqui. Também no SUSE® Security código-fonte do GitHub repositório. O apis.yaml do ramo principal pode incluir recursos não lançados. Recomenda-se baixar a versão apropriada do código-fonte liberado e extrair o apis.yaml da pasta controller/api.
|
Se você estiver fazendo chamadas de API REST com nome de usuário/senha, certifique-se de fazer uma chamada DELETE para /v1/auth quando terminar. Há um máximo de 32 sessões simultâneas para cada usuário. Se isso for excedido, ocorrerá uma falha de autenticação. |
SUSE® Security também suporta Regras de Resposta para automatizar respostas comuns a eventos de segurança ou vulnerabilidades detectadas. Consulte a seção Política de Segurança → Regras de Resposta para mais detalhes.
Expor a API REST no Kubernetes
Para expor a API REST para acesso de fora do cluster Kubernetes, habilite a porta 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
|
|
|
Se estiver usando o tipo LoadBalancer, defina o controllerIP nos exemplos abaixo para o IP externo ou URL do loadbalancer. |
Autenticação para API REST
A API REST suporta dois tipos de autenticação: nome de usuário/senha e token. Ambos podem ser configurados em Configurações → Usuários, Chaves de API e Funções, e associados a funções padrão ou personalizadas para limitar privilégios de acesso. Os exemplos abaixo mostram a autenticação baseada em nome de usuário/senha, onde um token é criado primeiro e depois usado em chamadas subsequentes da API REST. Se estiver usando um token, ele pode ser usado diretamente em cada chamada da API REST. Nota: conexões baseadas em nome de usuário têm um número limitado de sessões simultâneas, portanto, é importante excluir o token de nome de usuário conforme mostrado abaixo quando terminar. A autenticação baseada em token não tem limite, mas expira de acordo com o limite de tempo selecionado ao ser criada.
Para autenticação baseada em token, veja as seguintes capturas de tela e chamada de exemplo. Certifique-se de copiar o segredo e o token uma vez criados, pois não há como recuperá-los após a tela ser fechada.



Acionar a varredura de vulnerabilidades a partir de um script
SUSE® Security pode ser acionado automaticamente para varrer uma imagem em busca de vulnerabilidades. Isso pode ser feito configurando um registro/repositório para ser monitorado, usando o plug-in SUSE® Security do Jenkins ou utilizando a API REST. Por favor, consulte a seção sobre Varredura e Conformidade para mais detalhes.
O script de exemplo abaixo mostra como puxar o contêiner remotamente, executá-lo e escaneá-lo. Ele pode ser acionado a partir de uma tarefa do Jenkins (shell remoto) ou de qualquer ferramenta de CI/CD. Uma ferramenta de análise JSON (jq) também é utilizada.
Certifique-se de inserir o endereço IP do controlador no script e alterar o nome da imagem do contêiner para aquele que você deseja escanear. Além disso, atualize os campos de nome de usuário/senha.
Clique aqui para ver os detalhes
_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_
|
Você pode precisar instalar o jq
|
Para implantações baseadas em Kubernetes, você pode definir o IP do Controlador da seguinte forma:
_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}'`
|
Em uma implantação com múltiplos controladores, as requisições devem ser enviadas para um único IP de controlador, para que múltiplas requisições de status de varreduras de imagem de longa duração sejam direcionadas ao controlador que está realizando a varredura. |
Para escanear localmente em vez de em um 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"
Saída de exemplo:
Clique aqui para ver os detalhes
{
"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
}
]
}
}
Criar Regras de Política Automaticamente
Para criar uma nova regra no SUSE® Security controlador de políticas, os grupos para os campos DE e PARA devem existir primeiro. O seguinte exemplo cria um novo Grupo com base no rótulo do contêiner nv-service-type=data, e outro Grupo para o rótulo nv-service-type=website. Uma regra é então criada para permitir o tráfego do contêiner wordpress para o contêiner mysql usando apenas o protocolo mysql.
Certifique-se de atualizar o nome de usuário e a senha para acesso ao 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"
Se os Grupos já existirem em SUSE® Security, então a nova regra pode ser criada, pulando as etapas de criação do Grupo. Este exemplo também remove o token de autenticação no final. Observe que um número de ID de Regra pode ser especificado e SUSE® Security executa as regras em ordem numérica, do menor para o maior.
Arquivo de Configuração de Exportação / Importação
Aqui estão amostras para fazer backup do SUSE® Security arquivo de configuração automaticamente. Você pode selecionar se deseja exportar todas as configurações (política, usuários, etc.) ou apenas a política
|
Essas amostras são fornecidas apenas como exemplos e não são oficialmente suportadas, a menos que um acordo específico de suporte empresarial tenha sido estabelecido. |
Para exportar todas as configurações:
./config.py export -u admin -w admin -s $_controllerIP_ -p $_controllerPort_ -f $_FILENAME_ # exporting the configuration with all settings
Para exportar apenas a política:
./config.py export -u admin -w admin -s $_controllerIP_ -p $_controllerPort_ -f $_FILENAME_ --section policy # exporting the configuration with policy only
Para importar o arquivo:
./config.py import -u admin -w admin -s $_controllerIP_ -p $_controllerPort_ -f $_FILENAME_ # importing the configuration
Arquivos de exemplo em Python Contém config.py, client.py e multipart.py. Baixar arquivos de exemplo: ImportExport. Por favor, coloque todos os três arquivos em uma pasta para executar os comandos acima. Você pode precisar instalar alguns módulos Python para executar o script.
sudo pip install requests six
Definindo ou Alterando a Senha do Usuário
Use as chamadas da API REST para gerenciamento de usuários.
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 a Captura de Pacotes em um Contêiner
Quando um contêiner apresentar comportamento suspeito, inicie uma captura de pacotes.
#!/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`"
Não se esqueça de parar a sessão do sniffer após algum tempo para que não fique rodando para sempre. O número de arquivos a serem rotacionados tem um valor máximo de 50.
Verifique e aceite o EULA (novas implantações)
Obtenha o token de autenticação conforme acima. Substitua também o endereço IP do controlador pelo seu, conforme apropriado.
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
}
}
Aceitar 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
Em seguida, verifique o EULA novamente.
Configurar a varredura do 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"
Ativar captura de pacotes em todos os pods em um namespace
Clique aqui para ver os detalhes
#!/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
Ativar/desativar quarentena de contêiner
A chamada da API para quarentena é via PATCH para /v1/workload/:id com o seguinte corpo. O id do workload é o id do contêiner/pod.
--data-raw '{
"config": {
"quarantine": true,
"wire": "default",
"quarantine_reason": "violation"
}
}'
Ativar o modo de depuração para o SUSE® Security suporte
Defina o token de acesso com seu IP, usuário, senha:
_controllerIP_="<your_controller_ip>"
_controllerRESTAPIPort_="10443"
_neuvectorUsername_="admin"
_neuvectorPassword_="admin"
Obtenha o token de autenticação
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'`
Ativar modo de depuração
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
Desativar depuração em todos os controladores em um cluster
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
Verifique o status de depuração do controlador em um cluster
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
Relatar se uma vulnerabilidade está nas camadas da imagem base
Para identificar CVEs na imagem base ao usar a API REST para escanear imagens, a imagem base deve ser identificada na chamada da API, como no exemplo abaixo.
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}
Limitações
Se a imagem a ser escaneada for uma imagem remota, com "registry" especificado, a imagem base também deve ser uma imagem remota, e o nome deve começar com http ou https. Se a imagem a ser escaneada for uma imagem local, então a imagem base também deve ser uma imagem local.
Por exemplo,
{"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”}}
Obtenha a versão e a data do banco de dados CVE
curl -k -H "Content-Type: application/json" -H "X-Auth-Token: $_TOKEN_" "https://127.0.0.1:10443/v1/scan/scanner"
Saída:
{
"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"
}
]
}
Gerenciar a federação para clusters mestres e remotos (trabalhadores)
Geralmente, listar os membros da Federação pode usar um GET para o seguinte endpoint (veja os exemplos para a sintaxe específica):
https://neuvector-svc-controller.neuvector:10443/v1/fed/member
Para informações sobre automação da Federação via ConfigMap, consulte a documentação Exemplos de ConfigMap Federados.
APIs de gerenciamento de federação selecionadas:
Clique aqui para ver os detalhes
_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
#######################################################################