Tutta la potenza dell'interazione con le API si svela quando viene utilizzata insieme al codice sorgente, permettendo di creare dinamicamente richieste API e strumenti per analizzare le risposte delle API. Tuttavia, continua a passare inosservato Python Software Development Kit (di seguito "Python SDK") per Check Point Management API, e sarebbe un peccato. Rende la vita degli sviluppatori e degli appassionati di automazione notevolmente più semplice. Python ha guadagnato una enorme popolarità recentemente, e ho deciso di colmare questa lacuna e fornire una panoramica delle principali funzionalità . Questo articolo è un ottimo complemento a un altro articolo su Habr . Esamineremo come scrivere script utilizzando il Python SDK e ci concentreremo sulle nuove funzionalità dell'API Management nella versione 1.6 (supportata a partire da R80.40). Per comprendere appieno l'articolo, sono necessarie conoscenze di base sull'uso delle API e su Python.
Check Point sta attivamente sviluppando le API e ad oggi sono state rilasciate:
- — interazione con il server di gestione tramite API (inclusa la possibilità di eseguire script sui gateway gestiti dal server di gestione)
- — interazione con i gateway di sicurezza
- — gestione della sandbox nel cloud di Check Point
- — gestione della blade di Consapevolezza dell'Identità sui gateway
- — gestione del portale SMB dei gateway ()
- — interazione con i controller IoT
- — gestione di (soluzione di sicurezza SD-WAN)
- — gestione di
Il SDK Python attualmente supporta solo l'interazione con Management API e API Gaia. Esamineremo le classi, i metodi e le variabili più importanti in questo modulo.

Installazione del modulo
Modulo cpapi si installa rapidamente e facilmente da utilizzando pip. È disponibile una guida dettagliata all'installazione in . Questo modulo è adattato per funzionare con le versioni Python 2.7 e 3.7. In questo articolo, gli esempi saranno forniti utilizzando Python 3.7. Tuttavia, il SDK Python può essere eseguito direttamente dal server di gestione di Check Point (Smart Management), ma su di esso è supportata solo la versione Python 2.7, quindi nell'ultimo paragrafo verrà fornito il codice per la versione 2.7. Subito dopo l'installazione del modulo, consiglio di dare un'occhiata agli esempi nelle directory examples_python2 e examples_python3.
Inizio
Per poter lavorare con i componenti del modulo cpapi, è necessario importare dal modulo cpapi almeno due classi necessarie:
APIClient e APIClientArgs
from cpapi import APIClient, APIClientArgs
Classe APIClientArgs gestisce i parametri di connessione al server API, mentre la classe APIClient gestisce l'interazione con l'API.
Definiamo i parametri di connessione
Per definire vari parametri di connessione all'API, è necessario creare un'istanza della classe APIClientArgs. In linea di principio, i suoi parametri sono predefiniti e durante l'esecuzione dello script sul server di gestione non è necessario specificarli.
client_args = APIClientArgs()Tuttavia, quando viene eseguito su un host esterno, è necessario specificare almeno l'indirizzo IP o il nome host del server API (che è anche il server di gestione). Nell'esempio seguente, definiamo il parametro di connessione server e gli assegniamo come stringa l'indirizzo IP del server di gestione.
client_args = APIClientArgs(server='192.168.47.241')Diamo un'occhiata a tutti i parametri e ai loro valori predefiniti che possono essere utilizzati per connettersi al server API:
Argomenti del metodo __init__ della classe APIClientArgs
class APIClientArgs:
"""
Questa classe fornisce argomenti per la configurazione di APIClient.
Tutti gli argomenti sono configurati con i loro valori predefiniti.
"""
# la porta è impostata su None per default, ma viene sostituita con 443 se non specificata
# valori possibili per il contesto - web_api (predefinito) o 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
# fingerprint del server di gestione
self.fingerprint = fingerprint
# session-id.
self.sid = sid
# nome o indirizzo IP del server di gestione
self.server = server
# livello di debug
self.http_debug_level = http_debug_level
# un array con tutte le chiamate api (per scopi di debug)
self.api_calls = api_calls if api_calls else []
# nome del file di debug. Se rimane vuoto, i dati di debug non verranno salvati su disco.
self.debug_file = debug_file
# indirizzo del server proxy HTTP (senza "http://")
self.proxy_host = proxy_host
# porta del proxy HTTP
self.proxy_port = proxy_port
# versione dell'API del server di gestione
self.api_version = api_version
# Indica che il client non dovrebbe controllare il certificato del server
self.unsafe = unsafe
# Indica che il client dovrebbe accettare automaticamente e salvare il certificato del server
self.unsafe_auto_accept = unsafe_auto_accept
# Il contesto di utilizzo del client - predefinito a web_api
self.context = contextRitengo che gli argomenti utilizzabili nelle istanze della classe APIClientArgs siano intuitivi per gli amministratori di Check Point e non necessitino di ulteriori commenti.
Ci connettendo tramite APIClient e il gestore di contesto
Classe APIClient è più conveniente utilizzare attraverso il gestore di contesto. L'unica cosa da passare all'istanza della classe APIClient sono i parametri di connessione definiti nel passo precedente.
with APIClient(client_args) as client:
Il gestore di contesto non eseguirà automaticamente la chiamata login al server API, ma eseguirà la chiamata logout quando se ne esce. Se per qualche motivo non è richiesta la chiamata logout al termine del lavoro con le chiamate API, è necessario iniziare a lavorare senza utilizzare il gestore di contesto:
client = APIClient(client_args)Verifica della connessione
Controllare se la connessione è valida con i parametri specificati è più semplice utilizzando il metodo check_fingerprint. Se il controllo dell'hash sha1 per il fingerprint del certificato del server API non ha avuto successo (il metodo ha restituito Falso), di solito ciò è causato da problemi di connessione e possiamo interrompere l'esecuzione del programma (o dare all'utente la possibilità di correggere i dati di connessione):
se client.check_fingerprint() è False:
print("Impossibile ottenere l'impronta digitale del server - Controlla la connettività con il server.")
exit(1)
Si prega di notare che in futuro la classe APIClient verificherà ad ogni chiamata API (metodi api_call e api_query, di cui si parlerà più avanti) l'impronta digitale sha1 del certificato sul server API. Se durante il controllo dell'impronta digitale sha1 del certificato del server API si riscontra un errore (certificato sconosciuto o modificato), il metodo check_fingerprint fornirà la possibilità di aggiungere/modificare le informazioni su di esso nella macchina locale in modo automatico. Questa verifica può essere completamente disabilitata (ma ciò è raccomandato solo nel caso di esecuzione di script sul server API stesso, quando ci si connette a 127.0.0.1), utilizzando l'argomento APIClientArgs — unsafe_auto_accept (vedi maggiori dettagli su APIClientArgs precedentemente in «Definizione dei parametri di connessione»).
client_args = APIClientArgs(unsafe_auto_accept=True)Accesso al server API
A APIClient ci sono ben 3 metodi per accedere al server API, e ognuno di essi memorizza il valore sid(session-id), che viene utilizzato automaticamente in ogni successiva chiamata API nell'intestazione (il nome di questo parametro nell'intestazione è X-chkp-sid), quindi non è necessario gestire ulteriormente questo parametro.
Il metodo di accesso
Opzione con utilizzo di login e password (nell'esempio il nome utente è admin e la password 1q2w3e sono passati come argomenti posizionali):
login = client.login('admin', '1q2w3e') Nel metodo login sono disponibili anche parametri opzionali aggiuntivi, ecco i loro nomi e valori predefiniti:
continue_last_session=False, domain=None, read_only=False, payload=NoneMetodo login_with_api_key
Opzione con utilizzo della chiave API (supportata a partire dalla versione di gestione R80.40 / Management API v1.6, «3TsbPJ8ZKjaJGvFyoFqHFA==» questo è il valore della chiave API per uno degli utenti sul server di gestione con il metodo di autorizzazione API key):
login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==') Nel metodo login_with_api_key sono disponibili gli stessi parametri opzionali come nel metodo login.
Metodo login_as_root
Opzione di login sulla macchina locale con server API:
login = client.login_as_root()Per questo metodo sono disponibili solo due parametri opzionali:
domain=None, payload=NoneE infine le chiamate API
Abbiamo due opzioni per effettuare chiamate API tramite i metodi api_call e api_query. Scopriamo qual è la differenza tra di loro.
api_call
Questo metodo è applicabile per qualsiasi chiamata. Dobbiamo passare l'ultima parte per la chiamata API e il payload nel corpo della richiesta se necessario. Se il payload è vuoto, non è necessario passarne nemmeno uno:
api_versions = client.api_call('show-api-versions') Output per questa richiesta sotto il tag:
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'})Output per questa richiesta sotto il tag:
In [25]: show_host
Out[25]:
APIResponse({
"data": {
"color": "nero",
"comments": "",
"domain": {
"domain-type": "dominio",
"name": "Utente 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": "sbloccato",
"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": "nero",
"comments": "",
"domain": {
"domain-type": "dominio",
"name": "Utente 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": "sbloccato",
"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
Voglio sottolineare che questo metodo è applicabile solo per le chiamate il cui output prevede l'offset. Questo output si verifica quando contiene o può contenere una grande quantità di informazioni. Ad esempio, potrebbe trattarsi di una richiesta per elencare tutti gli oggetti di tipo host creati nel server di gestione. Per tali richieste, l'API restituisce un elenco di 50 oggetti per impostazione predefinita (il limite può essere aumentato a 500 oggetti nella risposta). E per evitare di richiamare le informazioni più volte, cambiando il parametro offset nella richiesta API, esiste un metodo api_query che gestisce automaticamente questo lavoro. Esempi di chiamate dove è necessario questo metodo: 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. Di fatto, nel nome di queste chiamate API vediamo parole al plurale, quindi queste chiamate saranno più facili da gestire tramite api_query
show_hosts = client.api_query('show-hosts') Output per questa richiesta sotto il tag:
In [21]: mostra_host
Out[21]:
APIResponse({
"data": [
{
"domain": {
"domain-type": "dominio",
"name": "Utente SMC",
"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": "dominio",
"name": "Utente SMC",
"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": "dominio",
"name": "Utente SMC",
"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": "dominio",
"name": "Utente SMC",
"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
})
Elaborazione dei risultati delle chiamate API
Dopo di che, è possibile utilizzare le variabili e i metodi della classe APIResponse(sia all'interno del gestore di contesto che all'esterno). La classe APIResponse ha 4 metodi e 5 variabili predefinite, su quelle più importanti ci soffermeremo di più.

success
Per iniziare, sarebbe utile assicurarsi che la chiamata API sia andata a buon fine e abbia restituito un risultato. A questo scopo, esiste un metodo success:
In [49]: api_versions.success
Out[49]: True
Restituisce True se la chiamata API è andata a buon fine (Codice di risposta — 200) e False se non è andata a buon fine (qualsiasi altro codice di risposta). È comodo usarlo subito dopo la chiamata API per visualizzare informazioni diverse a seconda del codice di risposta.
if api_ver.success:
print(api_versions.data)
else:
print(api_versions.err_message) statuscode
Restituisce il codice di risposta dopo l'esecuzione della chiamata API.
In [62]: api_versions.status_code
Out[62]: 400
Codici di risposta possibili: 200,400,401,403,404,409,500,501.
set_success_status
In questo caso potrebbe essere necessario modificare il valore dello stato di success. Tecnicamente, è possibile inserire qualsiasi cosa, persino una semplice stringa. Ma un esempio reale può essere il ripristino di questo parametro su False in determinate condizioni concomitanti. Di seguito, si noti un esempio in cui ci sono attività eseguite sul server di gestione, ma considereremo questa richiesta come non riuscita (imposteremo la variabile success su Falso, nonostante la chiamata API sia stata riuscita e abbia restituito il codice 200).
for task in task_result.data["tasks"]:
if task["status"] == "failed" or task["status"] == "partially succeeded":
task_result.set_success_status(False)
breakresponse()
Il metodo response permette di visualizzare un dizionario con il codice di risposta (status_code) e con il corpo della risposta (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
Permette di vedere solo il corpo della risposta (body) senza informazioni superflue.
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
Queste informazioni sono disponibili solo quando si è verificato un errore durante l'elaborazione della richiesta API (codice di risposta non 200). Esempio di output
In [107]: api_versions.error_message
Out[107]: 'code: generic_err_invalid_parameter_namenmessage: Unrecognized parameter [1]n'
Esempi utili
Di seguito sono riportati esempi che utilizzano chiamate API incluse nella versione Management API 1.6.
Iniziamo esaminando il funzionamento delle chiamate add-host e add-address-range. Supponiamo di dover creare come oggetti di tipo host tutti gli indirizzi IP della rete 192.168.0.0/24, il cui ottetto finale è uguale a 5, mentre tutti gli altri indirizzi IP devono essere registrati come oggetti di tipo intervallo di indirizzi. Nel farlo, escludere l'indirizzo di rete e l'indirizzo di broadcast.
Quindi, di seguito è riportato uno script che risolve questo compito e crea 50 oggetti di tipo host e 51 oggetti di tipo intervallo di indirizzi. Per completare questo compito sono necessarie 101 chiamate API (escludendo la chiamata finale publish). Inoltre, con il modulo timeit, calcoliamo il tempo di esecuzione dello script fino al momento della pubblicazione delle modifiche.
Script con utilizzo di 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')
Nel mio ambiente di laboratorio, l'esecuzione di questo script richiede tra 30 e 50 secondi a seconda del carico sul server di gestione.
Adesso vediamo come risolvere la stessa questione usando la chiamata API add-objects-batch, supportata dalla versione API 1.6. Questa chiamata consente di creare numerosi oggetti in un'unica richiesta API. Inoltre, questi possono essere oggetti di diversi tipi (ad esempio, host, subnet e range di indirizzi). In questo modo, il nostro compito può essere risolto in un'unica chiamata API.
Script con utilizzo di 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'Tempo di esecuzione della richiesta batch: {stop - start} secondi')
Nella mia ambiente di laboratorio, l'esecuzione di questo script richiede da 3 a 7 secondi, a seconda del carico sul server di gestione. Quindi, in media, su 101 oggetti, la chiamata API di tipo batch viene completata dieci volte più velocemente. Con un numero maggiore di oggetti, la differenza sarà ancora più impressionante.
Ora diamo un'occhiata a come lavorare con set-objects-batch. Con questa chiamata API possiamo modificare in massa qualsiasi parametro. Impostiamo la prima metà degli indirizzi dell'esempio precedente (fino al .124 dell'host, compresi anche i range) di colore sienna, mentre alla seconda metà degli indirizzi assegnamo il colore khaki.
Modifica del colore degli oggetti creati nell'esempio precedente
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")
È possibile eliminare un insieme di oggetti in una singola chiamata API utilizzando delete-objects-batch. Ora diamo un'occhiata a un esempio di codice che elimina tutti gli host creati in precedenza tramite add-objects-batch.
Eliminazione di oggetti utilizzando 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)
Tutte le funzionalità introdotte nelle nuove versioni del software Check Point ricevono immediatamente anche le chiamate API. Ad esempio, nella R80.40 sono state introdotte caratteristiche come Revert to revision e Smart Task, per le quali sono state subito preparate le chiamate API corrispondenti. Inoltre, tutta la funzionalità quando si passa dalle console Legacy alla modalità Unified Policy ottiene anche supporto API. Un aggiornamento molto atteso nella versione R80.40 è stato il trasferimento della politica HTTPS Inspection dalla modalità Legacy alla modalità Unified Policy, e questa funzionalità ha ricevuto immediatamente le chiamate API. Ecco un esempio di codice che aggiunge in cima alla politica di HTTPS Inspection una regola che esclude dall'ispezione 3 categorie (Salute, Finanza, Servizi Pubblici), che non possono essere ispezionate in conformità con la legislazione di diversi paesi.
Aggiungere una regola alla politica di HTTPS Inspection
from cpapi import APIClient, APIClientArgs
client_args = APIClientArgs(server="192.168.47.240")
data = {
"layer" : "Default Layer",
"position" : "top",
"name" : "Requisiti Legali",
"action": "bypass",
"site-category": ["Salute", "Governo / Militare", "Servizi Finanziari"]
}
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")
Esecuzione di script Python sul server di gestione Check Point
Tutto rimane lo stesso qui contiene informazioni su come eseguire script Python direttamente dal server di gestione. Questo può essere utile quando non si ha la possibilità di connettersi all'API del server da un'altra macchina. Ho registrato un video di sei minuti in cui esamino l'installazione del modulo cpapi e le caratteristiche di esecuzione degli script Python sul server di gestione. Come esempio, viene eseguito uno script che automatizza la configurazione di un nuovo gateway per compiti come l'audit della rete Security CheckUp. Tra le peculiarità affrontate: nella versione Python 2.7 non era ancora presente la funzione input, quindi per elaborare le informazioni immesse dall'utente si utilizza la funzione raw_input. Per il resto, il codice è lo stesso di quello per l'esecuzione da altre macchine, solo che è più comodo usare la funzione login_as_root, per non dover reinserire il proprio nome utente, password e indirizzo IP del server di gestione.

Script per una configurazione rapida di 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("Impossibile ottenere la firma del server - Controlla la connettività con il server.")
# exit(1)
login_res = client.login_as_root()
if login_res.success is False:
print("Accesso fallito:n{}".format(login_res.error_message))
exit(1)
gw_name = raw_input("Inserisci il nome del gateway:")
gw_ip = raw_input("Inserisci l'indirizzo IP del gateway:")
if sys.stdin.isatty():
sic = getpass.getpass("Inserisci la password monouso per il gateway(SIC): ")
else:
print("Attenzione! La tua password verrà visualizzata sullo schermo!")
sic = raw_input("Inserisci la password monouso per il gateway(SIC): ")
version = raw_input("Inserisci la versione del gateway(come 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("La connessione sicura con il gateway non è stata stabilita!")
exit(1)
elif add_gw.success:
print("Il gateway è stato aggiunto con successo.")
gw_uid = add_gw.data['uid']
gw_name = add_gw.data['name']
else:
print("Impossibile aggiungere il 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("La politica è stata cambiata con successo")
else:
print("Impossibile cambiare la politica - {}".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("La regola di pulizia è stata cambiata con successo")
else:
print("Impossibile cambiare la regola di pulizia - {}".format(change_rule.error_message))
# pubblica il risultato
publish_res = client.api_call("publish", {})
if publish_res.success:
print("Le modifiche sono state pubblicate con successo.")
else:
print("Impossibile pubblicare le modifiche - {}".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("La politica di accesso è stata installata")
else:
print("Impossibile installare la politica di accesso - {}".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("La politica di prevenzione delle minacce è stata installata")
else:
print("Impossibile installare la politica di prevenzione delle minacce - {}".format(install_tp_policy.error_message))
# aggiungi password e passphrase al dizionario
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("La linea del dizionario della password {} è stata aggiunta con successo".format(line_num))
else:
print("Impossibile aggiungere il dizionario - {}".format(add_password_dictionary.error_message))
main() Esempio di file con il dizionario delle password additional_pass.conf
{
"passwords" : ["malware","malicioso","infettato","Infettato"],
"phrases" : ["password","Password","Pass","pass","codice","chiave","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"]
}
Conclusione
Questo articolo tratta solo delle funzionalità di base del lavoro Python SDK e del modulo cpapi(come avrete intuito, questi sono praticamente sinonimi), e studiando il codice di questo modulo scoprirete ulteriori possibilità nel suo utilizzo. Non è escluso che possiate avere voglia di arricchirlo con le vostre classi, funzioni, metodi e variabili. Potete sempre condividere i vostri lavori e visionare altri script per Check Point nella sezione della comunità , che riunisce sia sviluppatori di prodotti che utenti.
Buon coding e grazie per aver letto fino alla fine!
Fonte: habr.com
