Simplificando a Check Point API com o Python SDK

Simplificando a Check Point API com o Python SDKTodo o poder de interação com APIs é revelado quando utilizado em conjunto com o código do programa, quando se torna possível gerar dinamicamente solicitações de API e ferramentas para análise de respostas de API. No entanto, ainda permanece imperceptível Kit de desenvolvimento de software Python (doravante denominado Python SDK) para API de gerenciamento de pontos de verificação, mas em vão. Simplifica significativamente a vida de desenvolvedores e entusiastas de automação. Python ganhou enorme popularidade ultimamente e decidi preencher a lacuna e revisar os principais recursos. Kit de desenvolvimento Python da API Check Point. Este artigo serve como um excelente complemento para outro artigo sobre Habré Ponto de verificação API R80.10. Controle via CLI, scripts e muito mais. Veremos como escrever scripts usando o Python SDK e daremos uma olhada mais de perto na nova funcionalidade da API de gerenciamento na versão 1.6 (suportada a partir da R80.40). Para entender o artigo, você precisará de conhecimentos básicos de como trabalhar com APIs e Python.

A Check Point está desenvolvendo ativamente a API e no momento o seguinte foi lançado:

Atualmente, o Python SDK oferece suporte apenas à interação com a API de gerenciamento e API Gaia. Veremos as classes, métodos e variáveis ​​mais importantes neste módulo.

Simplificando a Check Point API com o Python SDK

Instalando o módulo

Módulo cpapi instala de forma rápida e fácil a partir de repositório oficial da Check Point no github via pip. Instruções detalhadas de instalação estão disponíveis em README.md. Este módulo está adaptado para funcionar com as versões 2.7 e 3.7 do Python. Neste artigo, serão dados exemplos usando Python 3.7. No entanto, o Python SDK pode ser executado diretamente do Check Point Management Server (Smart Management), mas eles suportam apenas Python 2.7, portanto, a última seção fornecerá o código para a versão 2.7. Imediatamente após instalar o módulo, recomendo olhar os exemplos nos diretórios exemplos_python2 и exemplos_python3.

Introdução

Para podermos trabalhar com os componentes do módulo cpapi, precisamos importar do módulo cpapi pelo menos duas aulas obrigatórias:

ClienteAPI и APIClientArgs

from cpapi import APIClient, APIClientArgs

Classe APIClientArgs é responsável pelos parâmetros de conexão com o servidor API, e a classe ClienteAPI é responsável pela interação com a API.

Determinando parâmetros de conexão

Para definir vários parâmetros de conexão com a API, você precisa criar uma instância da classe APIClientArgs. A princípio seus parâmetros são predefinidos e ao executar o script no servidor de controle não precisam ser especificados.

client_args = APIClientArgs()

Mas ao executar em um host de terceiros, você precisa especificar pelo menos o endereço IP ou o nome do host do servidor API (também conhecido como servidor de gerenciamento). No exemplo abaixo, definimos o parâmetro de conexão do servidor e atribuímos a ele o endereço IP do servidor de gerenciamento como uma string.

client_args = APIClientArgs(server='192.168.47.241')

Vejamos todos os parâmetros e seus valores padrão que podem ser usados ​​ao se conectar ao servidor API:

Argumentos do método __init__ da classe APIClientArgs

class APIClientArgs:
    """
    This class provides arguments for APIClient configuration.
    All the arguments are configured with their default values.
    """

    # port is set to None by default, but it gets replaced with 443 if not specified
    # context possible values - web_api (default) or gaia_api
    def __init__(self, port=None, fingerprint=None, sid=None, server="127.0.0.1", http_debug_level=0,
                 api_calls=None, debug_file="", proxy_host=None, proxy_port=8080,
                 api_version=None, unsafe=False, unsafe_auto_accept=False, context="web_api"):
        self.port = port
        # management server fingerprint
        self.fingerprint = fingerprint
        # session-id.
        self.sid = sid
        # management server name or IP-address
        self.server = server
        # debug level
        self.http_debug_level = http_debug_level
        # an array with all the api calls (for debug purposes)
        self.api_calls = api_calls if api_calls else []
        # name of debug file. If left empty, debug data will not be saved to disk.
        self.debug_file = debug_file
        # HTTP proxy server address (without "http://")
        self.proxy_host = proxy_host
        # HTTP proxy port
        self.proxy_port = proxy_port
        # Management server's API version
        self.api_version = api_version
        # Indicates that the client should not check the server's certificate
        self.unsafe = unsafe
        # Indicates that the client should automatically accept and save the server's certificate
        self.unsafe_auto_accept = unsafe_auto_accept
        # The context of using the client - defaults to web_api
        self.context = context

Acredito que os argumentos que podem ser utilizados nas instâncias da classe APIClientArgs são intuitivos para os administradores do Check Point e não requerem comentários adicionais.

Conectando via APIClient e gerenciador de contexto

Classe ClienteAPI A maneira mais conveniente de usá-lo é através do gerenciador de contexto. Tudo o que precisa ser passado para uma instância da classe APIClient são os parâmetros de conexão que foram definidos na etapa anterior.

with APIClient(client_args) as client:

O gerenciador de contexto não fará automaticamente uma chamada de login para o servidor API, mas fará uma chamada de logout ao sair dele. Se por algum motivo o logout não for necessário após terminar de trabalhar com chamadas de API, você precisará começar a trabalhar sem usar o gerenciador de contexto:

client = APIClient(clieng_args)

Verificação de conexão

A maneira mais fácil de verificar se a conexão atende aos parâmetros especificados é usando o método verificação_impressão digital. Se a verificação da soma de hash sha1 para a impressão digital do certificado API do servidor falhar (o método retornado Falso), então isso geralmente é causado por problemas de conexão e podemos interromper a execução do programa (ou dar ao usuário a oportunidade de corrigir os dados de conexão):

    if client.check_fingerprint() is False:
        print("Could not get the server's fingerprint - Check connectivity with the server.")
        exit(1)

Observe que no futuro a classe ClienteAPI verificará cada chamada de API (métodos chamada_api и consulta_api, falaremos sobre eles um pouco mais adiante) certificado de impressão digital sha1 no servidor API. Mas se, ao verificar a impressão digital sha1 do certificado do servidor API, for detectado um erro (o certificado é desconhecido ou foi alterado), o método verificação_impressão digital fornecerá a oportunidade de adicionar/alterar informações sobre ele na máquina local automaticamente. Esta verificação pode ser desabilitada completamente (mas isso só pode ser recomendado se os scripts forem executados no próprio servidor API, ao conectar-se ao 127.0.0.1), usando o argumento APIClientArgs - inseguro_auto_accept (veja mais sobre APIClientArgs anteriormente em “Definindo parâmetros de conexão”).

client_args = APIClientArgs(unsafe_auto_accept=True)

Faça login no servidor API

У ClienteAPI existem até 3 métodos para fazer login no servidor API, e cada um deles entende o significado sid(session-id), que é usado automaticamente em cada chamada de API subsequente no cabeçalho (o nome no cabeçalho deste parâmetro é X-chkp-sid), portanto não há necessidade de processar ainda mais esse parâmetro.

método de login

Opção utilizando login e senha (no exemplo, o nome de usuário admin e a senha 1q2w3e são passados ​​como argumentos posicionais):

     login = client.login('admin', '1q2w3e')  

Parâmetros opcionais adicionais também estão disponíveis no método de login; aqui estão seus nomes e valores padrão:

continue_last_session=False, domain=None, read_only=False, payload=None

Método Login_with_api_key

Opção usando uma chave API (suportada a partir da versão de gerenciamento R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" este é o valor da chave API para um dos usuários no servidor de gerenciamento com o método de autorização da chave API):

     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==') 

No método login_with_api_key os mesmos parâmetros opcionais estão disponíveis como no método entrar.

método login_as_root

Opção para fazer login em uma máquina local com um servidor API:

     login = client.login_as_root()

Existem apenas dois parâmetros opcionais disponíveis para este método:

domain=None, payload=None

E finalmente a API chama a si mesma

Temos duas opções para fazer chamadas de API através de métodos chamada_api и consulta_api. Vamos descobrir qual é a diferença entre eles.

chamada_api

Este método é aplicável a qualquer chamada. Precisamos passar a última parte da chamada da API e da carga útil no corpo da solicitação, se necessário. Se a carga útil estiver vazia, ela não poderá ser transmitida:

api_versions = client.api_call('show-api-versions') 

Saída para esta solicitação abaixo do corte:

In [23]: api_versions                                                           
Out[23]: 
APIResponse({
    "data": {
        "current-version": "1.6",
        "supported-versions": [
            "1",
            "1.1",
            "1.2",
            "1.3",
            "1.4",
            "1.5",
            "1.6"
        ]
    },
    "res_obj": {
        "data": {
            "current-version": "1.6",
            "supported-versions": [
                "1",
                "1.1",
                "1.2",
                "1.3",
                "1.4",
                "1.5",
                "1.6"
            ]
        },
        "status_code": 200
    },
    "status_code": 200,
    "success": true
})
show_host = client.api_call('show-host', {'name' : 'h_8.8.8.8'})

Saída para esta solicitação abaixo do corte:

In [25]: show_host                                                              
Out[25]: 
APIResponse({
    "data": {
        "color": "black",
        "comments": "",
        "domain": {
            "domain-type": "domain",
            "name": "SMC User",
            "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
        },
        "groups": [],
        "icon": "Objects/host",
        "interfaces": [],
        "ipv4-address": "8.8.8.8",
        "meta-info": {
            "creation-time": {
                "iso-8601": "2020-05-01T21:49+0300",
                "posix": 1588358973517
            },
            "creator": "admin",
            "last-modifier": "admin",
            "last-modify-time": {
                "iso-8601": "2020-05-01T21:49+0300",
                "posix": 1588358973517
            },
            "lock": "unlocked",
            "validation-state": "ok"
        },
        "name": "h_8.8.8.8",
        "nat-settings": {
            "auto-rule": false
        },
        "read-only": false,
        "tags": [],
        "type": "host",
        "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
    },
    "res_obj": {
        "data": {
            "color": "black",
            "comments": "",
            "domain": {
                "domain-type": "domain",
                "name": "SMC User",
                "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
            },
            "groups": [],
            "icon": "Objects/host",
            "interfaces": [],
            "ipv4-address": "8.8.8.8",
            "meta-info": {
                "creation-time": {
                    "iso-8601": "2020-05-01T21:49+0300",
                    "posix": 1588358973517
                },
                "creator": "admin",
                "last-modifier": "admin",
                "last-modify-time": {
                    "iso-8601": "2020-05-01T21:49+0300",
                    "posix": 1588358973517
                },
                "lock": "unlocked",
                "validation-state": "ok"
            },
            "name": "h_8.8.8.8",
            "nat-settings": {
                "auto-rule": false
            },
            "read-only": false,
            "tags": [],
            "type": "host",
            "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
        },
        "status_code": 200
    },
    "status_code": 200,
    "success": true
})

consulta_api

Deixe-me fazer uma reserva imediatamente que este método é aplicável apenas para chamadas cuja saída envolve deslocamento. Tal inferência ocorre quando contém ou pode conter uma grande quantidade de informações. Por exemplo, poderia ser uma solicitação de uma lista de todos os objetos de host criados no servidor de gerenciamento. Para tais solicitações, a API retorna uma lista de 50 objetos por padrão (você pode aumentar o limite para 500 objetos na resposta). E para não puxar a informação diversas vezes, alterando o parâmetro offset na requisição da API, existe um método api_query que faz esse trabalho automaticamente. Exemplos de chamadas onde este método é necessário: sessões de show, apresentadores de show, redes de show, curingas de show, grupos de show, intervalos de endereços de show, gateways simples de show, clusters simples de show, funções de acesso de show, clientes confiáveis ​​de show, pacotes de show. Na verdade, vemos palavras no plural no nome dessas chamadas de API, portanto, será mais fácil lidar com elas por meio de consulta_api

show_hosts = client.api_query('show-hosts') 

Saída para esta solicitação abaixo do corte:

In [21]: show_hosts                                                             
Out[21]: 
APIResponse({
    "data": [
        {
            "domain": {
                "domain-type": "domain",
                "name": "SMC User",
                "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
            },
            "ipv4-address": "192.168.47.1",
            "name": "h_192.168.47.1",
            "type": "host",
            "uid": "5d7d7086-d70b-4995-971a-0583b15a2bfc"
        },
        {
            "domain": {
                "domain-type": "domain",
                "name": "SMC User",
                "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
            },
            "ipv4-address": "8.8.8.8",
            "name": "h_8.8.8.8",
            "type": "host",
            "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
        }
    ],
    "res_obj": {
        "data": {
            "from": 1,
            "objects": [
                {
                    "domain": {
                        "domain-type": "domain",
                        "name": "SMC User",
                        "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
                    },
                    "ipv4-address": "192.168.47.1",
                    "name": "h_192.168.47.1",
                    "type": "host",
                    "uid": "5d7d7086-d70b-4995-971a-0583b15a2bfc"
                },
                {
                    "domain": {
                        "domain-type": "domain",
                        "name": "SMC User",
                        "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
                    },
                    "ipv4-address": "8.8.8.8",
                    "name": "h_8.8.8.8",
                    "type": "host",
                    "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
                }
            ],
            "to": 2,
            "total": 2
        },
        "status_code": 200
    },
    "status_code": 200,
    "success": true
})

Processando os resultados de chamadas de API

Depois disso você pode usar as variáveis ​​e métodos da classe Resposta API(tanto dentro quanto fora do gerenciador de contexto). Na aula Resposta API 4 métodos e 5 variáveis ​​​​estão predefinidos; nos deteremos nos mais importantes com mais detalhes.

Simplificando a Check Point API com o Python SDK

sucesso

Para começar, seria uma boa ideia certificar-se de que a chamada da API foi bem-sucedida e retornou um resultado. Existe um método para isso sucesso:

In [49]: api_versions.success                                                   
Out[49]: True

Retorna True se a chamada da API foi bem-sucedida (código de resposta - 200) e False se não tiver êxito (qualquer outro código de resposta). É conveniente usar imediatamente após uma chamada de API para exibir informações diferentes dependendo do código de resposta.

if api_ver.success: 
    print(api_versions.data) 
else: 
    print(api_versions.err_message) 

código de status

Retorna o código de resposta após uma chamada de API ter sido feita.

In [62]: api_versions.status_code                                               
Out[62]: 400

Possíveis códigos de resposta: 200,400,401,403,404,409,500,501.

set_success_status

Neste caso, pode ser necessário alterar o valor do status de sucesso. Tecnicamente, você pode colocar qualquer coisa lá, até mesmo uma string normal. Mas um exemplo real seria redefinir este parâmetro para False sob certas condições concomitantes. Abaixo, preste atenção no exemplo quando há tarefas em execução no servidor de gerenciamento, mas consideraremos esta solicitação malsucedida (definiremos a variável de sucesso como Falso, apesar de a chamada da API ter sido bem-sucedida e ter retornado o código 200).

for task in task_result.data["tasks"]:
    if task["status"] == "failed" or task["status"] == "partially succeeded":
        task_result.set_success_status(False)
        break

resposta()

O método de resposta permite visualizar o dicionário com o código de resposta (status_code) e o corpo da resposta (body).

In [94]: api_versions.response()                                                
Out[94]: 
{'status_code': 200,
 'data': {'current-version': '1.6',
  'supported-versions': ['1', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6']}}

dados,

Permite ver apenas o corpo da resposta (corpo) sem informações desnecessárias.

In [93]: api_versions.data                                                      
Out[93]: 
{'current-version': '1.6',
 'supported-versions': ['1', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6']}

mensagem de erro

Esta informação está disponível somente quando ocorreu um erro durante o processamento da solicitação da API (código de resposta não 200). Exemplo de saída

In [107]: api_versions.error_message                                            
Out[107]: 'code: generic_err_invalid_parameter_namenmessage: Unrecognized parameter [1]n'

Exemplos úteis

A seguir estão exemplos que usam as chamadas de API que foram adicionadas na API de gerenciamento 1.6.

Primeiro, vamos ver como funcionam as chamadas adicionar-host и adicionar intervalo de endereços. Digamos que precisamos criar todos os endereços IP da sub-rede 192.168.0.0/24, cujo último octeto é 5, como objetos do tipo host, e escrever todos os outros endereços IP como objetos do tipo intervalo de endereços. Neste caso, exclua o endereço de sub-rede e o endereço de broadcast.

Então, segue abaixo um script que resolve esse problema e cria 50 objetos do tipo host e 51 objetos do tipo intervalo de endereços. Para resolver o problema, são necessárias 101 chamadas de API (sem contar a chamada de publicação final). Além disso, usando o módulo timeit, calculamos o tempo que leva para executar o script até que as alterações sejam publicadas.

Script usando add-host e add-address-range

import timeit
from cpapi import APIClient, APIClientArgs

start = timeit.default_timer()

first_ip = 1
last_ip = 4

client_args = APIClientArgs(server="192.168.47.240")

with APIClient(client_args) as client: 
     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
     for ip in range(5,255,5):
         add_host = client.api_call("add-host", {"name" : f"h_192.168.0.{ip}", "ip-address": f'192.168.0.{ip}'})
     while last_ip < 255:
         add_range = client.api_call("add-address-range", {"name": f"r_192.168.0.{first_ip}-{last_ip}", "ip-address-first": f"192.168.0.{first_ip}", "ip-address-last": f"192.168.0.{last_ip}"})
         first_ip+=5
         last_ip+=5
     stop = timeit.default_timer() 
     publish = client.api_call("publish")
     
print(f'Time to execute batch request: {stop - start} seconds')

No meu ambiente de laboratório, esse script leva de 30 a 50 segundos para ser executado, dependendo da carga no servidor de gerenciamento.

Agora vamos ver como resolver o mesmo problema usando uma chamada de API adicionar-objetos-lote, cujo suporte foi adicionado na versão 1.6 da API. Esta chamada permite criar vários objetos de uma só vez em uma solicitação de API. Além disso, podem ser objetos de diferentes tipos (por exemplo, hosts, sub-redes e intervalos de endereços). Assim, nossa tarefa pode ser resolvida dentro de uma chamada de API.

Script usando add-objects-batch

import timeit
from cpapi import APIClient, APIClientArgs

start = timeit.default_timer()

client_args = APIClientArgs(server="192.168.47.240")

objects_list_ip = []
objects_list_range = []

for ip in range(5,255,5):
    data = {"name": f'h_192.168.0.{ip}', "ip-address": f'192.168.0.{ip}'}
    objects_list_ip.append(data)
    
first_ip = 1
last_ip = 4


while last_ip < 255:
    data = {"name": f"r_192.168.0.{first_ip}-{last_ip}", "ip-address-first": f"192.168.0.{first_ip}", "ip-address-last": f"192.168.0.{last_ip}"}
    objects_list_range.append(data)
    first_ip+=5
    last_ip+=5

data_for_batch = {
  "objects" : [ {
    "type" : "host",
    "list" : objects_list_ip
}, {
    "type" : "address-range",
    "list" : objects_list_range
  }]
}


with APIClient(client_args) as client: 
     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
     add_objects_batch = client.api_call("add-objects-batch", data_for_batch)
     stop = timeit.default_timer() 
     publish = client.api_call("publish")
     
print(f'Time to execute batch request: {stop - start} seconds')

E executar esse script no meu ambiente de laboratório leva de 3 a 7 segundos, dependendo da carga no servidor de gerenciamento. Ou seja, em média, em 101 objetos de API, uma chamada do tipo lote é executada 10 vezes mais rápido. Num número maior de objetos a diferença será ainda mais impressionante.

Agora vamos ver como trabalhar com definir-objetos-lote. Usando esta chamada de API, podemos alterar qualquer parâmetro em massa. Vamos definir a primeira metade dos endereços do exemplo anterior (até 124 hosts e intervalos também) para a cor sienna e atribuir a cor cáqui à segunda metade dos endereços.

Alterando a cor dos objetos criados no exemplo anterior

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

objects_list_ip_first = []
objects_list_range_first = []
objects_list_ip_second = []
objects_list_range_second = []

for ip in range(5,125,5):
    data = {"name": f'h_192.168.0.{ip}', "color": "sienna"}
    objects_list_ip_first.append(data)
    
for ip in range(125,255,5):
    data = {"name": f'h_192.168.0.{ip}', "color": "khaki"}
    objects_list_ip_second.append(data)
    
first_ip = 1
last_ip = 4
while last_ip < 125:
    data = {"name": f"r_192.168.0.{first_ip}-{last_ip}", "color": "sienna"}
    objects_list_range_first.append(data)
    first_ip+=5
    last_ip+=5
    
while last_ip < 255:
    data = {"name": f"r_192.168.0.{first_ip}-{last_ip}", "color": "khaki"}
    objects_list_range_second.append(data)
    first_ip+=5
    last_ip+=5

data_for_batch_first  = {
  "objects" : [ {
    "type" : "host",
    "list" : objects_list_ip_first
}, {
    "type" : "address-range",
    "list" : objects_list_range_first
  }]
}

data_for_batch_second  = {
  "objects" : [ {
    "type" : "host",
    "list" : objects_list_ip_second
}, {
    "type" : "address-range",
    "list" : objects_list_range_second
  }]
}

with APIClient(client_args) as client: 
     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==') 
     set_objects_batch_first = client.api_call("set-objects-batch", data_for_batch_first)
     set_objects_batch_second = client.api_call("set-objects-batch", data_for_batch_second)
     publish = client.api_call("publish")

Você pode excluir vários objetos em uma chamada de API usando excluir-objetos-lote. Agora vamos ver um exemplo de código que exclui todos os hosts criados anteriormente via adicionar-objetos-lote.

Excluindo objetos usando delete-objects-batch

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

objects_list_ip = []
objects_list_range = []

for ip in range(5,255,5):
    data = {"name": f'h_192.168.0.{ip}'}
    objects_list_ip.append(data)

first_ip = 1
last_ip = 4
while last_ip < 255:
    data = {"name": f"r_192.168.0.{first_ip}-{last_ip}"}
    objects_list_range.append(data)
    first_ip+=5
    last_ip+=5

data_for_batch = {
  "objects" : [ {
    "type" : "host",
    "list" : objects_list_ip
}, {
    "type" : "address-range",
    "list" : objects_list_range
  }]
}

with APIClient(client_args) as client: 
     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
     delete_objects_batch = client.api_call("delete-objects-batch", data_for_batch)
     publish = client.api_call("publish")

print(delete_objects_batch.data)

Todas as funções que aparecem nas novas versões do software Check Point adquirem imediatamente chamadas de API. Assim, no R80.40 apareceram “recursos” como Reverter para revisão e Tarefa Inteligente, e chamadas de API correspondentes foram imediatamente preparadas para eles. Além disso, todas as funcionalidades ao passar dos consoles legados para o modo de política unificada também adquirem suporte de API. Por exemplo, a tão esperada atualização na versão de software R80.40 foi a mudança da política de inspeção HTTPS do modo legado para o modo de política unificada, e essa funcionalidade recebeu imediatamente chamadas de API. Aqui está um exemplo de código que adiciona uma regra à posição superior da política de inspeção HTTPS que exclui 3 categorias da inspeção (Saúde, Finanças, Serviços Governamentais), que são proibidas de inspeção de acordo com a lei em vários países.

Adicione uma regra à política de inspeção HTTPS

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

data = {
  "layer" : "Default Layer",
  "position" : "top",
  "name" : "Legal Requirements",
  "action": "bypass",
  "site-category": ["Health", "Government / Military", "Financial Services"]
}

with APIClient(client_args) as client: 
     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
     add_https_rule = client.api_call("add-https-rule", data)
     publish = client.api_call("publish")

Executando scripts Python no servidor de gerenciamento Check Point

É tudo a mesma coisa README.md contém informações sobre como executar scripts Python diretamente do servidor de controle. Isso pode ser conveniente quando você não consegue se conectar ao servidor API de outra máquina. Gravei um vídeo de seis minutos no qual vejo a instalação do módulo cpapi e recursos de execução de scripts Python no servidor de controle. Por exemplo, é executado um script que automatiza a configuração de um novo gateway para uma tarefa como auditoria de rede Verificação de segurança. Entre os recursos que tive que lidar: a função ainda não apareceu no Python 2.7 entrada, então para processar as informações que o usuário insere, uma função é usada entrada_crua. Caso contrário, o código é o mesmo para iniciar em outras máquinas, só que é mais conveniente usar a função login_as_root, para não especificar novamente seu próprio nome de usuário, senha e endereço IP do servidor de gerenciamento.

Script para configuração rápida do Security CheckUp

from __future__ import print_function
import getpass
import sys, os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from cpapi import APIClient, APIClientArgs

def main():
    with APIClient() as client:
       # if client.check_fingerprint() is False:
       #     print("Could not get the server's fingerprint - Check connectivity with the server.")
       #     exit(1)
        login_res = client.login_as_root()

        if login_res.success is False:
            print("Login failed:n{}".format(login_res.error_message))
            exit(1)

        gw_name = raw_input("Enter the gateway name:")
        gw_ip = raw_input("Enter the gateway IP address:")
        if sys.stdin.isatty():
            sic = getpass.getpass("Enter one-time password for the gateway(SIC): ")
        else:
            print("Attention! Your password will be shown on the screen!")
            sic = raw_input("Enter one-time password for the gateway(SIC): ")
        version = raw_input("Enter the gateway version(like RXX.YY):")
        add_gw = client.api_call("add-simple-gateway", {'name' : gw_name, 'ipv4-address' : gw_ip, 'one-time-password' : sic, 'version': version.capitalize(), 'application-control' : 'true', 'url-filtering' : 'true', 'ips' : 'true', 'anti-bot' : 'true', 'anti-virus' : 'true', 'threat-emulation' : 'true'})
        if add_gw.success and add_gw.data['sic-state'] != "communicating":
            print("Secure connection with the gateway hasn't established!")
            exit(1)
        elif add_gw.success:
            print("The gateway was added successfully.")
            gw_uid = add_gw.data['uid']
            gw_name = add_gw.data['name']
        else:
            print("Failed to add the gateway - {}".format(add_gw.error_message))
            exit(1)

        change_policy = client.api_call("set-access-layer", {"name" : "Network", "applications-and-url-filtering": "true", "content-awareness": "true"})
        if change_policy.success:
            print("The policy has been changed successfully")
        else:
            print("Failed to change the policy- {}".format(change_policy.error_message))
        change_rule = client.api_call("set-access-rule", {"name" : "Cleanup rule", "layer" : "Network", "action": "Accept", "track": {"type": "Detailed Log", "accounting": "true"}})
        if change_rule.success:
            print("The cleanup rule has been changed successfully")
        else:
            print("Failed to change the cleanup rule- {}".format(change_rule.error_message))

        # publish the result
        publish_res = client.api_call("publish", {})
        if publish_res.success:
            print("The changes were published successfully.")
        else:
                print("Failed to publish the changes - {}".format(install_tp_policy.error_message))

        install_access_policy = client.api_call("install-policy", {"policy-package" : "Standard", "access" : 'true',  "threat-prevention" : 'false', "targets" : gw_uid})
        if install_access_policy.success:
            print("The access policy has been installed")
        else:
                print("Failed to install access policy - {}".format(install_tp_policy.error_message))

        install_tp_policy = client.api_call("install-policy", {"policy-package" : "Standard", "access" : 'false',  "threat-prevention" : 'true', "targets" : gw_uid})
        if install_tp_policy.success:
            print("The threat prevention policy has been installed")
        else:
            print("Failed to install threat prevention policy - {}".format(install_tp_policy.error_message))
        
        # add passwords and passphrases to dictionary
        with open('additional_pass.conf') as f:
            line_num = 0
            for line in f:
                line_num += 1
                add_password_dictionary = client.api_call("run-script", {"script-name" : "Add passwords and passphrases", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
                if add_password_dictionary.success:
                    print("The password dictionary line {} was added successfully".format(line_num))
                else:
                    print("Failed to add the dictionary - {}".format(add_password_dictionary.error_message))

main()

Um arquivo de exemplo com um dicionário de senha adicional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Conclusão

Este artigo examina apenas as possibilidades básicas de trabalho SDK do Python e módulo cpapi(como você deve ter adivinhado, na verdade são sinônimos) e, ao estudar o código deste módulo, você descobrirá ainda mais oportunidades para trabalhar com ele. É possível que você queira complementá-lo com suas próprias classes, funções, métodos e variáveis. Você sempre pode compartilhar seu trabalho e ver outros scripts do Check Point na seção codehub na comunidade CheckMates, que reúne desenvolvedores de produtos e usuários.

Boa codificação e obrigado por ler até o fim!

Fonte: habr.com

Adicionar um comentário