Tutta la potenza dell'interazione con l'API si svela quando viene utilizzata in combinazione con il codice sorgente, quando si creano possibilità di formare dinamicamente richieste API e strumenti per analizzare le risposte API. Tuttavia, continua a rimanere poco visibile Python Software Development Kit (di seguito - Python SDK) per Check Point Management API, e a ragione. Rende notevolmente più semplice la vita agli sviluppatori e agli appassionati di automazione. Python ha guadagnato un'enorme popolarità di recente e ho deciso di colmare il divario e fare una panoramica delle principali funzionalità . Questo articolo costituisce un'ottima aggiunta a un altro articolo su Habr . Noi esamineremo come scrivere script utilizzando Python SDK e ci soffermeremo maggiormente sulle nuove funzionalità dell'API di gestione nella versione 1.6 (supportata a partire da R80.40). Per comprendere questo articolo sono necessarie conoscenze di base sul lavoro con API e Python.
Check Point sta attivamente sviluppando API e attualmente sono stati rilasciati:
- — interazione con il server di gestione tramite API (e possibilità di eseguire script sui gateway controllati dal server di gestione)
- — interazione con i gateway di sicurezza
- — interazione con la sandbox nel cloud di Check Point
- — interazione con il blade di Identity Awareness sui gateway
- — interazione con il portale di gestione dei gateway SMB ()
- — interazione con i controller IoT
- — interazione con (soluzione di sicurezza SD-WAN)
- — interazione con
Python SDK attualmente supporta l'interazione solo con Management API e Gaia API.Esamineremo le classi, i metodi e le variabili più importanti in questo modulo.

L'installazione del modulo
Modulo cpapi avviene rapidamente e facilmente dal utilizzando pip. Le istruzioni dettagliate per l'installazione sono disponibili in . Questo modulo è stato adattato per funzionare con versioni Python 2.7 e 3.7. In questo articolo, gli esempi saranno forniti utilizzando Python 3.7. Tuttavia, Python SDK può essere eseguito direttamente dal server di gestione di Check Point (Smart Management), ma su questi è supportata solo la versione Python 2.7, quindi nell'ultima sezione verrà fornito il codice per la versione 2.7. Subito dopo l'installazione del modulo, consiglio di guardare gli esempi nelle directory examples_python2 e examples_python3.
Inizio del lavoro
Per avere la possibilità di 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, e la classe APIClient gestisce l'interazione con l'API.
Definiamo i parametri di connessione
Per definire i diversi parametri di connessione all'API, è necessario creare un'istanza della classe APIClientArgs. In generale, i suoi parametri sono predefiniti e non è necessario specificarli al momento dell'esecuzione dello script sul server di gestione.
client_args = APIClientArgs()Ma 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 lo assegniamo come stringa all'indirizzo IP del server di gestione.
client_args = APIClientArgs(server='192.168.47.241')Diamo un'occhiata a tutti i parametri e i 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 di default, ma viene sostituita da 443 se non specificata
# I possibili valori del contesto - web_api (default) 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 lasciato 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 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 e salvare automaticamente il certificato del server
self.unsafe_auto_accept = unsafe_auto_accept
# Il contesto di utilizzo del client - di default è web_api
self.context = contextCredo che gli argomenti che possono essere utilizzati nelle istanze della classe APIClientArgs siano intuitivamente comprensibili per gli amministratori di Check Point e non necessitino di ulteriori commenti.
Colleghiamoci tramite APIClient e il gestore di contesto
Classe APIClient è più comodo utilizzare il gestore di contesto. Tutto ciò che è necessario trasmettere all'istanza della classe APIClient sono i parametri di connessione definiti nel passaggio precedente.
with APIClient(client_args) as client:
Il gestore di contesto non eseguirà automaticamente la chiamata di login al server API, ma eseguirà la chiamata di logout quando si esce da esso. Se per qualche motivo la chiamata di logout al termine dell'uso delle API non è necessaria, è possibile iniziare il lavoro senza utilizzare il gestore di contesto:
client = APIClient(client_args)Verifica connessione
Verificare se la connessione funziona con i parametri forniti è più semplice utilizzando il metodo check_fingerprint. Se il controllo dell'hash sha1 per il fingerprint del certificato del server API non è andato a buon fine (il metodo ha restituito False), 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):
if client.check_fingerprint() is False:
print("Non è stato possibile ottenere il fingerprint del server - Controlla la connettività con il server.")
exit(1)
Tieni presente che in seguito la classe APIClient verificherà ad ogni chiamata API (i metodi api_call e api_query, di cui parleremo più avanti) l'hash sha1 del fingerprint del certificato sul server API. Se durante il controllo dell'hash sha1 del fingerprint del certificato del server API viene rilevato un errore (certificato sconosciuto o modificato), il metodo check_fingerprint offrirà la possibilità di aggiungere/modificare le informazioni su di esso sulla macchina locale in modo automatico. Questa verifica può essere disabilitata completamente (ma si raccomanda solo in caso di esecuzione degli script sul server API stesso, con connessione a 127.0.0.1), utilizzando l'argomento APIClientArgs — unsafe_auto_accept (vedi maggiori dettagli su APIClientArgs in precedenza in "Definiamo i parametri di connessione").
client_args = APIClientArgs(unsafe_auto_accept=True)Login al server API
A APIClient ci sono ben 3 metodi di login sul 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 dell'intestazione per questo parametro è X-chkp-sid), quindi non è necessario elaborare ulteriormente questo parametro.
Metodo login
Opzione con utilizzo di username 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 ulteriori parametri opzionali, riporto qui 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 (supportato a partire dalla versione 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.
Il metodo login_as_root
Opzione di login per una 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 stesse
Abbiamo due opzioni per effettuare chiamate API tramite metodi api_call e api_query. Vediamo quale sia la differenza tra di loro.
api_call
Questo metodo è applicabile a 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 passarlo affatto:
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]: mostrar_host
Out[25]:
APIResponse({
"data": {
"color": "nero",
"comments": "",
"domain": {
"domain-type": "dominio",
"name": "Utente SMC",
"uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
},
"groups": [],
"icon": "Oggetti/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": "Oggetti/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 subito chiarire che questo metodo è applicabile solo per le chiamate il cui output prevede un offset. Questo output avviene quando contiene o potrebbe contenere un grande quantitativo di informazioni. Ad esempio, potrebbe trattarsi di una richiesta per un elenco di 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 il metodo api_query, che svolge automaticamente questo lavoro. Esempi di chiamate in cui è 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. Infatti, 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]: show_hosts
Out[21]:
APIResponse({
"data": [
{
"domain": {
"domain-type": "domain",
"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": "domain",
"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": "domain",
"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": "domain",
"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 questo, è 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 predefiniti, su quelli più importanti ci soffermeremo di più.

successo
Per iniziare, sarebbe utile assicurarsi che la chiamata API sia andata a buon fine e abbia restituito un risultato. A tal fine, esiste un metodo successo:
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 (qualunque altro codice di risposta). È utile utilizzarlo subito dopo la chiamata API, per visualizzare informazioni diverse in base al 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
Possibili codici di risposta: 200,400,401,403,404,409,500,501.
set_success_status
In questo caso, potrebbe essere necessario modificare il valore dello stato success. Tecnicamente, si può includere qualunque cosa, persino una semplice stringa. Ma un esempio reale potrebbe essere il ripristino di questo parametro a False in determinate condizioni concomitanti. Di seguito, fai attenzione all'esempio in cui ci sono compiti eseguiti sul server di gestione, ma considereremo questa richiesta come non riuscita (impostiamo la variabile success in False, nonostante la chiamata API sia stata efficace 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 consente di visualizzare il dizionario con il codice di risposta (status_code) e 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 elencati esempi in cui si utilizzano chiamate API che sono state aggiunte 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 subnet 192.168.0.0/24, il cui ultimo ottetto è 5, mentre tutti gli altri indirizzi IP devono essere registrati come oggetti di tipo intervallo di indirizzi. In questo caso, l'indirizzo della subnet e l'indirizzo di broadcast devono essere esclusi.
Quindi, di seguito è presentato uno script che risolve questo compito e crea 50 oggetti di tipo host e 51 oggetti di tipo intervallo di indirizzi. Per risolvere il compito, sono necessarie 101 chiamate API (escludendo la chiamata finale publish). Utilizzando il modulo timeit, calcoliamo anche 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'Tempo di esecuzione della richiesta batch: {stop - start} secondi')
Nel mio ambiente di laboratorio, l'esecuzione di questo script richiede da 30 a 50 secondi a seconda del carico sul server di gestione.
E ora vediamo come risolvere lo stesso problema utilizzando la chiamata API add-objects-batch, supportato dalla versione API 1.6. Questa chiamata consente di creare molti oggetti con una sola richiesta API. 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')
E l'esecuzione di questo script nel mio ambiente di laboratorio richiede da 3 a 7 secondi a seconda del carico sul server di gestione. Cioè, in media, su 101 oggetti, la chiamata API di tipo batch funziona 10 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 del precedente esempio (fino al .124 dell'host, compresi anche i range) sul colore sienna, mentre alla seconda metà degli indirizzi assegneremo il colore khaki.
Modifica del colore degli oggetti creati nell'esempio precedente
da cpapi importare 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 sola chiamata API utilizzando delete-objects-batch. Ora vediamo un esempio di codice che elimina tutti gli host creati in precedenza tramite add-objects-batch.
Eliminazione di oggetti utilizzando delete-objects-batch
da cpapi importare 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à che appaiono nelle nuove versioni del software Check Point acquisiscono immediatamente anche chiamate API. Ad esempio, nella versione R80.40 sono state introdotte funzionalità come Revert to revision e Smart Task, per le quali sono state preparate le corrispondenti chiamate API. Inoltre, l'intera funzionalità durante la transizione dalle console Legacy alla modalità Unified Policy viene arricchita con il supporto API. Ad esempio, il tanto atteso aggiornamento nella versione del software R80.40 è stata la migrazione della politica HTTPS Inspection dalla modalità Legacy alla modalità Unified Policy, e questa funzionalità ha immediatamente ricevuto chiamate API. Ecco un esempio di codice che aggiunge in cima alla policy HTTPS Inspection una regola che esclude dall'ispezione 3 categorie (Salute, Finanze, Servizi pubblici), che sono vietate da ispezionare in conformità con la legislazione in diversi paesi.
Aggiungi regola alla politica 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": ["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")
Esecuzione di script Python sul server di gestione Check Point
Rimane invariato contiene informazioni su come eseguire script Python direttamente dal server di gestione. Questo può essere utile quando non hai la possibilità di collegarti al server API da un'altra macchina. Ho registrato un video di sei minuti in cui esamino l'installazione del modulo cpapi e le caratteristiche dell'esecuzione di script Python sul server di gestione. Come esempio, viene eseguito uno script che automatizza la configurazione di un nuovo gateway per un compito come l'audit della rete Security CheckUp. Tra le caratteristiche con cui ho dovuto confrontarmi: nella versione Python 2.7 non è ancora comparsa la funzione input, quindi per elaborare le informazioni fornite dall'utente viene utilizzata la funzione raw_input. Altrimenti, il codice è lo stesso utilizzato per l'esecuzione da altre macchine, solo che è più comodo usare la funzione login_as_root, in modo da non dover specificare nuovamente il proprio username, password e indirizzo IP del server di gestione.

Script per la rapida configurazione di Security CheckUp
da __future__ importare print_function
import getpass
import sys, os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
dalla cpapi import APIClient, APIClientArgs
def main():
con APIClient() come client:
# se client.check_fingerprint() è False:
# print("Impossibile ottenere l'impronta 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 sarà mostrata sullo schermo!")
sic = raw_input("Inserisci la password monouso per il gateway (SIC): ")
version = raw_input("Inserisci la versione del gateway (es. 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" : "Regola di Cleanup", "layer" : "Network", "action": "Accept", "track": {"type": "Detailed Log", "accounting": "true"}})
if change_rule.success:
print("La regola di cleanup è stata cambiata con successo")
else:
print("Impossibile cambiare la regola di cleanup - {}".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 frasi segrete 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" : "Aggiungi password e frasi segrete", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
if add_password_dictionary.success:
print("La riga di dizionario delle 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","maligno","infettato","Infettato"],
"phrases" : ["password","Password","Pass","pass","codigo","chiave","pwd","пароль","Пароль","Chiave","chiave","cifratura","Cifratura"]
}
Conclusione
Questo articolo esamina solo le principali funzionalità del lavoro Python SDK e del modulo cpapi(come potreste aver intuito, sono praticamente sinonimi), e studiando il codice in questo modulo scoprirete molte più opportunità nel lavorarci. Non è da escludere che possiate desiderare 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 unisce sviluppatori di prodotti e utenti.
Buon coding e grazie per aver letto fino in fondo!
Fonte: habr.com
