Todo o poder da interação com a API é revelado quando combinado com o código de programação, dando origem à possibilidade de formar dinamicamente solicitações de API e ferramentas para analisar respostas da API. No entanto, permanece pouco reconhecido até agora Kit de Desenvolvimento de Software Python (daqui em diante — Python SDK) para API de Gestão Check Point, e isso é um erro. Ele simplifica consideravelmente a vida dos desenvolvedores e entusiastas da automação. O Python ganhou uma enorme popularidade recentemente e eu decidi preencher essa lacuna e fazer uma visão geral das principais funcionalidades . Este artigo serve como uma excelente complementação a outro artigo no Habr . Nós vamos discutir como escrever scripts utilizando o Python SDK e focar mais nas novas funcionalidades da API de Gestão na versão 1.6 (suportada a partir do R80.40). Para entender o artigo, serão necessários conhecimentos básicos sobre o funcionamento da API e do Python.
A Check Point está ativamente desenvolvendo a API e atualmente surgiram:
- — inclusão de funcionalidade para interagir com o servidor de gestão através da API (e execução de scripts nos dispositivos sob gestão do servidor)
- — gerenciamento de gateways de segurança
- — trabalhar com sandbox na nuvem Check Point
- — gestão da blade de Conscientização de Identidade em gateways
- — gerenciamento do portal de gateways SMB ()
- — interação com controladores IoT
- — gerenciamento de (solução de segurança SD-WAN)
- — gerenciamento de
O SDK Python atualmente suporta interação apenas com a API de Gestão e API Gaia. Vamos examinar as classes, métodos e variáveis mais importantes deste módulo.

Instalação do módulo
Módulo cpapi é rápido e fácil de instalar a partir do com pip. Um guia detalhado de instalação está disponível em . Este módulo é compatível com as versões Python 2.7 e 3.7. Neste artigo, os exemplos serão apresentados usando o Python 3.7. No entanto, o Python SDK pode ser executado diretamente do servidor de gestão Check Point (Smart Management), mas apenas a versão Python 2.7 é suportada, portanto, na última seção, o código será apresentado para a versão 2.7. Logo após a instalação do módulo, recomendo verificar os exemplos nos diretórios examples_python2 e examples_python3.
Início
Para que tenhamos a possibilidade de trabalhar com os componentes do módulo cpapi, precisamos importar do módulo cpapi pelo menos duas classes necessárias:
APIClient e APIClientArgs
from cpapi import APIClient, APIClientArgs
Classe APIClientArgs responsável pelos parâmetros de conexão com o servidor API, enquanto a classe APIClient é responsável pela interação com a API.
Definindo os parâmetros de conexão
Para definir diferentes parâmetros de conexão com a API, é necessário criar uma instância da classe APIClientArgs. Basicamente, seus parâmetros são predefinidos e, ao executar o script no servidor de gerenciamento, não é necessário especificá-los.
client_args = APIClientArgs()Mas ao executar em um host externo, é necessário 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 server e atribuímos a ele, como uma string, o endereço IP do servidor de gerenciamento.
client_args = APIClientArgs(server='192.168.47.241')Vamos dar uma olhada em todos os parâmetros e seus valores padrão que podem ser usados ao conectar-se ao servidor API:
Argumentos do método __init__ da classe APIClientArgs
class APIClientArgs:
"""
Esta classe fornece argumentos para a configuração do APIClient.
Todos os argumentos são configurados com seus valores padrão.
"""
# a porta é definida como None por padrão, mas é substituída por 443 se não for especificada
# valores possíveis do contexto - web_api (padrão) ou 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
# impressora do servidor de gerenciamento
self.fingerprint = fingerprint
# session-id.
self.sid = sid
# nome ou endereço IP do servidor de gerenciamento
self.server = server
# nível de depuração
self.http_debug_level = http_debug_level
# um array com todas as chamadas da API (para fins de depuração)
self.api_calls = api_calls if api_calls else []
# nome do arquivo de depuração. Se deixado vazio, os dados de depuração não serão salvos no disco.
self.debug_file = debug_file
# endereço do servidor proxy HTTP (sem "http://")
self.proxy_host = proxy_host
# porta do proxy HTTP
self.proxy_port = proxy_port
# versão da API do servidor de gerenciamento
self.api_version = api_version
# Indica que o cliente não deve verificar o certificado do servidor
self.unsafe = unsafe
# Indica que o cliente deve aceitar e salvar automaticamente o certificado do servidor
self.unsafe_auto_accept = unsafe_auto_accept
# O contexto de uso do cliente - o padrão é web_api
self.context = contextAcredito que os argumentos que podem ser usados nas instâncias da classe APIClientArgs sejam intuitivos para os administradores do Check Point e não necessitem de comentários adicionais.
Conectando-se através do APIClient e do gerenciador de contexto
Classe APIClient é mais conveniente usar através do gerenciador de contexto. Tudo o que precisa ser passado para a 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 realizará automaticamente a chamada de login na API do servidor, mas ele fará a chamada de logout ao sair. Se, por algum motivo, a chamada de logout não for necessária ao final do trabalho com as chamadas da API, você deve iniciar o trabalho sem usar o gerenciador de contexto:
client = APIClient(clieng_args)Verificação de conexão
É mais fácil verificar se a conexão passa pelos parâmetros especificados usando o método check_fingerprint. Se a verificação do hash sha1 para o certificado fingerprint da API do servidor falhar (o método retornar False), isso geralmente é causado por problemas de conexão e podemos interromper a execução do programa (ou dar ao usuário a chance de corrigir os dados de conexão):
if client.check_fingerprint() is False:
print("Não foi possível obter o fingerprint do servidor - Verifique a conectividade com o servidor.")
exit(1)
Tenha em mente que a classe APIClient verificará a cada chamada da API (métodos api_call e api_query, que serão discutidos mais adiante) o fingerprint sha1 do certificado na API do servidor. Se um erro for detectado durante a verificação do fingerprint sha1 do certificado da API do servidor (certificado desconhecido ou alterado), o método check_fingerprint oferecerá a possibilidade de adicionar/alterar as informações sobre ele no computador local de forma automática. Essa verificação pode ser completamente desativada (mas isso só é recomendado na execução de scripts no próprio servidor da API, ao se conectar a 127.0.0.1), usando o argumento APIClientArgs — unsafe_auto_accept (veja mais sobre APIClientArgs anteriormente em "Definindo parâmetros de conexão").
client_args = APIClientArgs(unsafe_auto_accept=True)Login na API do servidor
Na APIClient existem 3 métodos de login na API do servidor, e cada um deles armazena o valor sid(session-id), que é utilizado automaticamente em cada chamada subsequente da API no cabeçalho (o nome no cabeçalho deste parâmetro — X-chkp-sid), então não é necessário processar esse parâmetro adicionalmente.
Método login
Opção usando login e senha (no exemplo, o nome de usuário admin e a senha 1q2w3e foram passados como argumentos posicionais):
login = client.login('admin', '1q2w3e') No método login, também estão disponíveis parâmetros opcionais adicionais, aqui estão seus nomes e valores padrão:
continue_last_session=False, domain=None, read_only=False, payload=NoneMétodo login_with_api_key
Opção usando a 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 API key):
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 login.
O método login_as_root
Uma variante de login na máquina local com o servidor API:
login = client.login_as_root()Para este método, apenas dois parâmetros opcionais estão disponíveis:
domain=None, payload=NoneE finalmente os próprios chamadas API
Temos duas opções para fazer chamadas API através dos métodos api_call e api_query. Vamos entender qual é a diferença entre elas.
api_call
Este método é aplicável a qualquer chamada. Precisamos passar a última parte para a chamada API e o payload no corpo da solicitação, se necessário. Se o payload estiver vazio, não precisa ser passado:
api_versions = client.api_call('show-api-versions') Saída para esta solicitação abaixo:
Em [23]: api_versions
Saída[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:
Em [25]: show_host
Out[25]:
APIResponse({
"data": {
"color": "preto",
"comments": "",
"domain": {
"domain-type": "domínio",
"name": "Usuário SMC",
"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": "desbloqueado",
"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": "preto",
"comments": "",
"domain": {
"domain-type": "domínio",
"name": "Usuário SMC",
"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": "desbloqueado",
"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
})
api_query
Deixe-me esclarecer que este método é aplicável apenas para chamadas cujo retorno pressupõe offset (deslocamento). Esse retorno ocorre quando ele contém ou pode conter uma grande quantidade de informações. Por exemplo, isso pode ser uma solicitação de lista de todos os objetos do tipo host criados no servidor de gerenciamento. Para tais solicitações, a API retorna uma lista de 50 objetos por padrão (o limite pode ser aumentado para 500 objetos na resposta). E para evitar fazer múltiplas chamadas para obter informações mudando o parâmetro offset na solicitação da API, existe o método api_query, que realiza esse trabalho automaticamente. Exemplos de chamadas onde esse método é necessário: show-sessions, show-hosts, show-networks, show-wildcards, show-groups, show-address-ranges, show-simple-gateways, show-simple-clusters, show-access-roles, show-trusted-clients, show-packages. Na verdade, no nome dessas chamadas da API vemos palavras no plural, então essas chamadas serão mais fáceis de serem processadas através de api_query
show_hosts = client.api_query('show-hosts') Saída para esta solicitação abaixo:
Em [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
})
Processamento de resultados de chamadas de API
Após isso, é possível utilizar variáveis e métodos da classe APIResponse(tanto dentro do gerenciador de contexto quanto fora dele). A classe APIResponse possui 4 métodos e 5 variáveis predefinidas, nos concentraremos nas mais importantes.

success
Para começar, seria bom garantir que a chamada da API foi bem-sucedida e retornou um resultado. Para isso, existe o método success:
Em [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 foi bem-sucedida (qualquer outro código de resposta). É conveniente usar logo após a chamada da 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) statuscode
Retorna o código de resposta após a execução da chamada da API.
Em [62]: api_versions.status_code
Out[62]: 400
Códigos de resposta possíveis: 200,400,401,403,404,409,500,501.
set_success_status
No entanto, pode ser necessário alterar o valor do status success. Tecnicamente, pode-se colocar qualquer coisa lá, até mesmo uma string comum. Mas um exemplo real pode ser redefinir esse parâmetro para False sob certas condições associadas. Abaixo, observe o exemplo em que existem tarefas sendo executadas no servidor de gerenciamento, mas consideraremos essa solicitação como falhada (definiremos a variável success em False, embora a chamada da API tenha sido bem-sucedida e 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)
breakresponse()
O método response permite ver um 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']}}
data
Permite ver apenas o corpo da resposta (body) sem informações excessivas.
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']}
error_message
Essas informações estão disponíveis apenas quando ocorre um erro ao processar a 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_nmessage: Unrecognized parameter [1]n'
Exemplos úteis
Abaixo estão exemplos que utilizam chamadas de API que foram adicionadas na versão Management API 1.6.
Para começar, vamos examinar o funcionamento das chamadas add-host e add-address-range. Suponha que precisamos criar como objetos do tipo host todos os endereços IP da sub-rede 192.168.0.0/24, cujo último octeto seja 5, enquanto todos os outros endereços IP devem ser registrados como objetos do tipo intervalo de endereços. Além disso, o endereço da sub-rede e o endereço de broadcast devem ser excluídos.
Assim, abaixo está um script que resolve essa tarefa e cria 50 objetos do tipo host e 51 objetos do tipo intervalo de endereços. Para resolver a tarefa, são necessárias 101 chamadas de API (sem contar a chamada final de publicação). Além disso, com o módulo timeit, calculamos o tempo de execução do script até o momento da publicação das alterações.
Script utilizando 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, a execução deste script leva de 30 a 50 segundos, dependendo da carga no servidor de gerenciamento.
Agora vamos ver como resolver essa mesma tarefa usando uma chamada de API add-objects-batch, cujo suporte foi adicionado na versão da API 1.6. Essa chamada permite criar muitos objetos de uma só vez com uma única solicitação API. Além disso, esses podem ser objetos de tipos diferentes (como hosts, sub-redes e intervalos de endereços). Assim, nossa tarefa pode ser resolvida em uma única chamada 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')
A execução deste 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, a chamada de API do tipo batch para 101 objetos é 10 vezes mais rápida. Com um maior número de objetos, a diferença será ainda mais impressionante.
Agora vamos ver como trabalhar com set-objects-batch. Com essa chamada de API, podemos alterar em massa qualquer parâmetro. Vamos definir a cor sienna para a primeira metade dos endereços do exemplo anterior (até .124 do host, incluindo os intervalos) e a cor khaki para a segunda metade dos endereços.
Alteração da 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")
É possível remover vários objetos em uma única chamada de API usando delete-objects-batch. Agora, vamos ver um exemplo de código que remove todos os hosts criados anteriormente através de add-objects-batch.
Removendo 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 funcionalidades que aparecem nas novas versões do software Check Point ganham imediatamente chamadas de API. Assim, no R80.40 surgiram recursos como Revert to revision e Smart Task, e para eles foram prontamente preparadas as chamadas de API correspondentes. Além disso, toda a funcionalidade ao migrar do modo Legacy para o modo Unified Policy também passa a ter suporte da API. Por exemplo, uma atualização esperada na versão de software R80.40 foi a migração da política de Inspeção HTTPS do modo Legacy para o modo Unified Policy, e essa funcionalidade imediatamente obteve chamadas de API. Aqui está um exemplo de código que adiciona, na posição mais alta, uma regra na política de Inspeção HTTPS que exclui da inspeção 3 categorias (Saúde, Finanças, Serviços Públicos), que são proibidas de serem inspecionadas de acordo com a legislação em vários países.
Adicionar regra à política de Inspeção HTTPS
from cpapi import APIClient, APIClientArgs
client_args = APIClientArgs(server="192.168.47.240")
data = {
"layer" : "Camada Padrão",
"position" : "top",
"name" : "Requisitos Legais",
"action": "bypass",
"site-category": ["Saúde", "Governo / Militar", "Serviços Financeiros"]
}
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")
Execução de scripts Python no servidor de gerenciamento Check Point
Tudo na mesma contém informações sobre como executar scripts em Python diretamente do servidor de gerenciamento. Isso pode ser conveniente quando você não tem a capacidade de se conectar ao servidor da API de outra máquina. Eu gravei um vídeo de seis minutos no qual examino a instalação do módulo cpapi e as particularidades da execução de scripts Python no servidor de gerenciamento. Como exemplo, estou executando um script que automatiza a configuração de um novo gateway para uma tarefa como auditoria de rede. Security CheckUp. Entre as particularidades que enfrentei: na versão Python 2.7 ainda não existe a função input, portanto, para processar as informações inseridas pelo usuário, usa-se a função raw_input. No restante, o código é o mesmo que para execução em outras máquinas, apenas é mais conveniente usar a função login_as_root, para não precisar inserir 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("Não foi possível obter a impressão digital do servidor - Verifique a conectividade com o servidor.")
# exit(1)
login_res = client.login_as_root()
if login_res.success is False:
print("Falha no login:n{}".format(login_res.error_message))
exit(1)
gw_name = raw_input("Digite o nome do gateway:")
gw_ip = raw_input("Digite o endereço IP do gateway:")
if sys.stdin.isatty():
sic = getpass.getpass("Digite a senha temporária para o gateway (SIC): ")
else:
print("Atenção! Sua senha será exibida na tela!")
sic = raw_input("Digite a senha temporária para o gateway (SIC): ")
version = raw_input("Digite a versão do gateway (como 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("A conexão segura com o gateway não foi estabelecida!")
exit(1)
elif add_gw.success:
print("O gateway foi adicionado com sucesso.")
gw_uid = add_gw.data['uid']
gw_name = add_gw.data['name']
else:
print("Falha ao adicionar o gateway - {}".format(add_gw.error_message))
exit(1)
change_policy = client.api_call("set-access-layer", {"name" : "Rede", "applications-and-url-filtering": "true", "content-awareness": "true"})
if change_policy.success:
print("A política foi alterada com sucesso")
else:
print("Falha ao alterar a política - {}".format(change_policy.error_message))
change_rule = client.api_call("set-access-rule", {"name" : "Regra de Limpeza", "layer" : "Rede", "action": "Accept", "track": {"type": "Registro Detalhado", "accounting": "true"}})
if change_rule.success:
print("A regra de limpeza foi alterada com sucesso")
else:
print("Falha ao alterar a regra de limpeza - {}".format(change_rule.error_message))
# publicar o resultado
publish_res = client.api_call("publish", {})
if publish_res.success:
print("As alterações foram publicadas com sucesso.")
else:
print("Falha ao publicar as alterações - {}".format(install_tp_policy.error_message))
install_access_policy = client.api_call("install-policy", {"policy-package" : "Padrão", "access" : 'true', "threat-prevention" : 'false', "targets" : gw_uid})
if install_access_policy.success:
print("A política de acesso foi instalada")
else:
print("Falha ao instalar a política de acesso - {}".format(install_tp_policy.error_message))
install_tp_policy = client.api_call("install-policy", {"policy-package" : "Padrão", "access" : 'false', "threat-prevention" : 'true', "targets" : gw_uid})
if install_tp_policy.success:
print("A política de prevenção de ameaças foi instalada")
else:
print("Falha ao instalar a política de prevenção de ameaças - {}".format(install_tp_policy.error_message))
# adicionar senhas e frases-senha ao dicionário
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" : "Adicionar senhas e frases-senha", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
if add_password_dictionary.success:
print("A linha do dicionário de senhas {} foi adicionada com sucesso".format(line_num))
else:
print("Falha ao adicionar o dicionário - {}".format(add_password_dictionary.error_message))
main() Exemplo de arquivo com o dicionário de senhas additional_pass.conf
{
"passwords" : ["malware","malicioso","infectado","Infectado"],
"phrases" : ["senha","Senha","Pass","pass","codigo","chave","pwd","senha","Senha","Chave","chave","código","Códigos"]
}
Conclusão
Este artigo considera apenas as principais funcionalidades de trabalho Python SDK e do módulo cpapi(como você pode supor, são essencialmente sinônimos), e estudando o código deste módulo, você descobrirá ainda mais possibilidades na sua utilização. É possível que você tenha o desejo de complementá-lo com suas próprias classes, funções, métodos e variáveis. Você sempre pode compartilhar seus trabalhos e revisar outros scripts para Check Point na seção na comunidade , que reúne tanto desenvolvedores de produtos quanto usuários.
Feliz codificação e obrigado por ler até o final!
Fonte: habr.com
