Vereinfachung der Check Point API mit dem Python SDK

Vereinfachung der Check Point API mit dem Python SDKDie volle Leistungsfähigkeit der Interaktion mit APIs entfaltet sich bei der Verwendung zusammen mit Programmcode, wenn es möglich wird, API-Anfragen und Tools zur Analyse von API-Antworten dynamisch zu generieren. Allerdings bleibt es immer noch unbemerkt Python-Softwareentwicklungskit (im Folgenden als Python SDK bezeichnet) für Check Point Management API, aber vergeblich. Es vereinfacht das Leben von Entwicklern und Automatisierungsbegeisterten erheblich. Python hat in letzter Zeit enorm an Popularität gewonnen und ich habe beschlossen, die Lücke zu schließen und die Hauptfunktionen zu überprüfen. Check Point API Python-Entwicklungskit. Dieser Artikel dient als hervorragende Ergänzung zu einem anderen Artikel über Habré Check Point R80.10 API. Verwaltung über CLI, Skripte und mehr. Wir werden uns ansehen, wie man Skripte mit dem Python SDK schreibt, und werfen einen genaueren Blick auf die neue Management-API-Funktionalität in Version 1.6 (unterstützt ab R80.40). Um den Artikel zu verstehen, benötigen Sie Grundkenntnisse im Umgang mit APIs und Python.

Check Point entwickelt die API aktiv weiter und hat derzeit Folgendes veröffentlicht:

Das Python SDK unterstützt derzeit nur die Interaktion mit der Management API und Gaia-API. Wir werden uns in diesem Modul mit den wichtigsten Klassen, Methoden und Variablen befassen.

Vereinfachung der Check Point API mit dem Python SDK

Modul installieren

Modul cpapi lässt sich schnell und einfach installieren offizielles Check Point-Repository auf Github über Pip. Detaillierte Installationsanweisungen finden Sie in README.md. Dieses Modul ist für die Arbeit mit den Python-Versionen 2.7 und 3.7 angepasst. In diesem Artikel werden Beispiele mit Python 3.7 gegeben. Das Python SDK kann jedoch direkt vom Check Point Management Server (Smart Management) ausgeführt werden, unterstützt jedoch nur Python 2.7, sodass im letzten Abschnitt Code für Version 2.7 bereitgestellt wird. Direkt nach der Installation des Moduls empfehle ich einen Blick auf die Beispiele in den Verzeichnissen Beispiele_python2 и Beispiele_python3.

Erste Schritte

Damit wir mit den Komponenten des cpapi-Moduls arbeiten können, müssen wir aus dem Modul importieren cpapi mindestens zwei erforderliche Kurse:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Klasse APIClientArgs ist verantwortlich für Verbindungsparameter zum API-Server und der Klasse APIClient ist für die Interaktion mit der API verantwortlich.

Verbindungsparameter ermitteln

Um verschiedene Parameter für die Verbindung zur API zu definieren, müssen Sie eine Instanz der Klasse erstellen APIClientArgs. Seine Parameter sind grundsätzlich vordefiniert und müssen beim Ausführen des Skripts auf dem Steuerungsserver nicht angegeben werden.

client_args = APIClientArgs()

Bei der Ausführung auf einem Drittanbieter-Host müssen Sie jedoch mindestens die IP-Adresse oder den Hostnamen des API-Servers (auch als Verwaltungsserver bezeichnet) angeben. Im folgenden Beispiel definieren wir den Serververbindungsparameter und weisen ihm die IP-Adresse des Verwaltungsservers als Zeichenfolge zu.

client_args = APIClientArgs(server='192.168.47.241')

Schauen wir uns alle Parameter und ihre Standardwerte an, die beim Herstellen einer Verbindung zum API-Server verwendet werden können:

Argumente der __init__-Methode der APIClientArgs-Klasse

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

Ich glaube, dass die Argumente, die in Instanzen der APIClientArgs-Klasse verwendet werden können, für Check Point-Administratoren intuitiv sind und keine zusätzlichen Kommentare erfordern.

Verbindung über APIClient und Kontextmanager

Klasse APIClient Am bequemsten nutzen Sie es über den Kontextmanager. An eine Instanz der APIClient-Klasse müssen lediglich die Verbindungsparameter übergeben werden, die im vorherigen Schritt definiert wurden.

with APIClient(client_args) as client:

Der Kontextmanager führt nicht automatisch einen Anmeldeaufruf beim API-Server durch, sondern einen Abmeldeaufruf, wenn er sich abmeldet. Wenn nach Abschluss der Arbeit mit API-Aufrufen aus irgendeinem Grund keine Abmeldung erforderlich ist, müssen Sie mit der Arbeit beginnen, ohne den Kontextmanager zu verwenden:

client = APIClient(clieng_args)

Verbindungstest

Ob die Verbindung die angegebenen Parameter erfüllt, lässt sich am einfachsten mit der Methode überprüfen check_fingerprint. Wenn die Überprüfung der SHA1-Hash-Summe für den Fingerabdruck des Server-API-Zertifikats fehlschlägt (die Methode gibt Folgendes zurück). falsch), dann liegt dies in der Regel an Verbindungsproblemen und wir können die Ausführung des Programms stoppen (oder dem Benutzer die Möglichkeit geben, die Verbindungsdaten zu korrigieren):

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

Bitte beachten Sie, dass in Zukunft die Klasse APIClient prüft jeden API-Aufruf (Methoden). api_call и api_query, wir werden etwas später darüber sprechen) sha1-Fingerabdruckzertifikat auf dem API-Server. Wenn jedoch bei der Überprüfung des sha1-Fingerabdrucks des API-Server-Zertifikats ein Fehler festgestellt wird (das Zertifikat ist unbekannt oder wurde geändert), wird die Methode check_fingerprint bietet die Möglichkeit, Informationen darüber auf dem lokalen Computer automatisch hinzuzufügen/zu ändern. Diese Prüfung kann mithilfe des Arguments APIClientArgs vollständig deaktiviert werden (dies kann jedoch nur empfohlen werden, wenn Skripte auf dem API-Server selbst ausgeführt werden, wenn eine Verbindung zu 127.0.0.1 hergestellt wird). unsicher_auto_accept (Weitere Informationen zu APIClientArgs finden Sie weiter oben unter „Verbindungsparameter definieren“).

client_args = APIClientArgs(unsafe_auto_accept=True)

Melden Sie sich beim API-Server an

У APIClient Es gibt bis zu drei Methoden zum Anmelden beim API-Server, und jede davon versteht die Bedeutung sid(Sitzungs-ID), die automatisch bei jedem nachfolgenden API-Aufruf im Header verwendet wird (der Name im Header dieses Parameters lautet X-chkp-sid), sodass dieser Parameter nicht weiter verarbeitet werden muss.

Anmeldemethode

Option mit Login und Passwort (im Beispiel werden der Benutzername admin und das Passwort 1q2w3e als Positionsargumente übergeben):

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

In der Anmeldemethode sind auch zusätzliche optionale Parameter verfügbar; hier sind ihre Namen und Standardwerte:

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

Login_with_api_key-Methode

Option mit einem API-Schlüssel (unterstützt ab Management-Version R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" Dies ist der API-Schlüsselwert für einen der Benutzer auf dem Verwaltungsserver mit der API-Schlüssel-Autorisierungsmethode):

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

In der Methode login_with_api_key Es stehen die gleichen optionalen Parameter zur Verfügung wie in der Methode login.

login_as_root-Methode

Option zum Anmelden an einem lokalen Computer mit einem API-Server:

     login = client.login_as_root()

Für diese Methode stehen nur zwei optionale Parameter zur Verfügung:

domain=None, payload=None

Und schließlich ruft sich die API selbst auf

Wir haben zwei Möglichkeiten, API-Aufrufe über Methoden durchzuführen api_call и api_query. Lassen Sie uns herausfinden, was der Unterschied zwischen ihnen ist.

api_call

Diese Methode ist für alle Anrufe anwendbar. Bei Bedarf müssen wir den letzten Teil für den API-Aufruf und die Nutzlast im Anfragetext übergeben. Wenn die Nutzlast leer ist, kann sie überhaupt nicht übertragen werden:

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

Ausgabe für diese Anfrage unterhalb des Schnitts:

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'})

Ausgabe für diese Anfrage unterhalb des Schnitts:

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
})

api_query

Lassen Sie mich gleich einen Vorbehalt anbringen, dass diese Methode nur für Aufrufe anwendbar ist, deren Ausgabe einen Offset beinhaltet. Eine solche Schlussfolgerung liegt vor, wenn sie eine große Menge an Informationen enthält oder enthalten kann. Dies könnte beispielsweise eine Anforderung einer Liste aller erstellten Hostobjekte auf dem Verwaltungsserver sein. Für solche Anfragen gibt die API standardmäßig eine Liste mit 50 Objekten zurück (Sie können die Grenze auf 500 Objekte in der Antwort erhöhen). Und um Informationen nicht mehrmals durch Ändern des Offset-Parameters in der API-Anfrage abzurufen, gibt es eine api_query-Methode, die diese Arbeit automatisch erledigt. Beispiele für Aufrufe, bei denen diese Methode benötigt wird: Show-Sessions, Show-Hosts, Show-Netzwerke, Show-Wildcards, Show-Gruppen, Show-Adressbereiche, Show-Simple-Gateways, Show-Simple-Cluster, Show-Zugriffsrollen, Show-Trusted-Clients, Show-Pakete. Tatsächlich sehen wir mehrere Wörter im Namen dieser API-Aufrufe, sodass diese Aufrufe einfacher zu verarbeiten sind api_query

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

Ausgabe für diese Anfrage unterhalb des Schnitts:

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
})

Verarbeiten der Ergebnisse von API-Aufrufen

Danach können Sie die Variablen und Methoden der Klasse verwenden APIResponse(sowohl innerhalb des Kontextmanagers als auch außerhalb). Im Unterricht APIResponse Es sind 4 Methoden und 5 Variablen vordefiniert, auf die wichtigsten gehen wir näher ein.

Vereinfachung der Check Point API mit dem Python SDK

Erfolg

Zunächst wäre es eine gute Idee, sicherzustellen, dass der API-Aufruf erfolgreich war und ein Ergebnis zurückgegeben hat. Dafür gibt es eine Methode Erfolg:

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

Gibt True zurück, wenn der API-Aufruf erfolgreich war (Antwortcode - 200) und False, wenn nicht erfolgreich (jeder andere Antwortcode). Es ist praktisch, unmittelbar nach einem API-Aufruf zu verwenden, um je nach Antwortcode unterschiedliche Informationen anzuzeigen.

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

Statuscode

Gibt den Antwortcode zurück, nachdem ein API-Aufruf durchgeführt wurde.

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

Mögliche Antwortcodes: 200,400,401,403,404,409,500,501.

set_success_status

In diesem Fall kann es erforderlich sein, den Wert des Erfolgsstatus zu ändern. Technisch gesehen kann man dort alles unterbringen, sogar eine normale Saite. Ein reales Beispiel wäre jedoch das Zurücksetzen dieses Parameters auf False unter bestimmten Begleitbedingungen. Achten Sie unten auf das Beispiel, bei dem Aufgaben auf dem Verwaltungsserver ausgeführt werden, wir diese Anfrage jedoch als erfolglos betrachten (wir werden die Erfolgsvariable auf setzen). falsch, obwohl der API-Aufruf erfolgreich war und Code 200 zurückgegeben hat.

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

Antwort()

Mit der Antwortmethode können Sie das Wörterbuch mit dem Antwortcode (status_code) und dem Antworttext (body) anzeigen.

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']}}

technische Daten

Ermöglicht Ihnen, nur den Hauptteil der Antwort (Body) ohne unnötige Informationen anzuzeigen.

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']}

Fehlermeldung

Diese Informationen sind nur verfügbar, wenn bei der Verarbeitung der API-Anfrage (Antwortcode) ein Fehler aufgetreten ist nicht 200). Beispielausgabe

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

Nützliche Beispiele

Im Folgenden finden Sie Beispiele, die die API-Aufrufe verwenden, die in Management API 1.6 hinzugefügt wurden.

Schauen wir uns zunächst an, wie Anrufe funktionieren Host hinzufügen и Adressbereich hinzufügen. Nehmen wir an, wir müssen alle IP-Adressen des Subnetzes 192.168.0.0/24, dessen letztes Oktett 5 ist, als Objekte vom Typ Host erstellen und alle anderen IP-Adressen als Objekte vom Typ Adressbereich schreiben. Schließen Sie in diesem Fall die Subnetzadresse und die Broadcast-Adresse aus.

Nachfolgend finden Sie ein Skript, das dieses Problem löst und 50 Objekte vom Typ „Host“ und 51 Objekte vom Typ „Adressbereich“ erstellt. Um das Problem zu lösen, sind 101 API-Aufrufe erforderlich (den letzten Veröffentlichungsaufruf nicht mitgerechnet). Außerdem berechnen wir mithilfe des Moduls timeit die Zeit, die von der Ausführung des Skripts bis zur Veröffentlichung der Änderungen benötigt wird.

Skript mit „Add-Host“ und „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')

In meiner Laborumgebung dauert die Ausführung dieses Skripts je nach Auslastung des Verwaltungsservers zwischen 30 und 50 Sekunden.

Sehen wir uns nun an, wie Sie dasselbe Problem mithilfe eines API-Aufrufs lösen können Add-Objects-Batch, deren Unterstützung in API-Version 1.6 hinzugefügt wurde. Mit diesem Aufruf können Sie in einer API-Anfrage viele Objekte gleichzeitig erstellen. Darüber hinaus kann es sich um Objekte unterschiedlichen Typs handeln (z. B. Hosts, Subnetze und Adressbereiche). Somit kann unsere Aufgabe im Rahmen eines API-Aufrufs gelöst werden.

Skript mit 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')

Und die Ausführung dieses Skripts in meiner Laborumgebung dauert je nach Auslastung des Verwaltungsservers zwischen 3 und 7 Sekunden. Das bedeutet, dass ein Batch-Aufruf bei 101 API-Objekten im Durchschnitt zehnmal schneller ausgeführt wird. Bei einer größeren Anzahl von Objekten wird der Unterschied noch beeindruckender sein.

Sehen wir uns nun an, wie man damit arbeitet set-objects-batch. Mit diesem API-Aufruf können wir jeden Parameter in großen Mengen ändern. Stellen wir die erste Hälfte der Adressen aus dem vorherigen Beispiel (bis zu .124 Hosts und auch Bereiche) auf die Farbe Sienna ein und weisen wir der zweiten Hälfte der Adressen die Farbe Khaki zu.

Ändern der Farbe der im vorherigen Beispiel erstellten Objekte

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")

Sie können mehrere Objekte in einem API-Aufruf löschen mit Objekte-Batch löschen. Schauen wir uns nun ein Codebeispiel an, das alle zuvor über erstellten Hosts löscht Add-Objects-Batch.

Objekte mit delete-objects-batch löschen

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)

Alle Funktionen, die in neuen Versionen der Check Point-Software erscheinen, erhalten sofort API-Aufrufe. So erschienen in R80.40 „Funktionen“ wie „Auf Revision zurücksetzen“ und „Smart Task“, und entsprechende API-Aufrufe wurden sofort für sie vorbereitet. Darüber hinaus erhalten alle Funktionen beim Wechsel von Legacy-Konsolen zum Unified Policy-Modus auch API-Unterstützung. Das lang erwartete Update in der Softwareversion R80.40 war beispielsweise die Verschiebung der HTTPS-Inspektionsrichtlinie vom Legacy-Modus in den Unified Policy-Modus, und diese Funktionalität erhielt sofort API-Aufrufe. Hier ist ein Beispielcode, der an der obersten Position der HTTPS-Inspektionsrichtlinie eine Regel hinzufügt, die drei Kategorien von der Inspektion ausschließt (Gesundheit, Finanzen, Regierungsdienste), deren Inspektion gemäß dem Gesetz in einer Reihe von Ländern verboten ist.

Fügen Sie der HTTPS-Inspektionsrichtlinie eine Regel hinzu

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")

Ausführen von Python-Skripten auf dem Check Point-Verwaltungsserver

Alles ist das selbe README.md enthält Informationen zum Ausführen von Python-Skripten direkt vom Steuerungsserver. Dies kann praktisch sein, wenn Sie von einem anderen Computer aus keine Verbindung zum API-Server herstellen können. Ich habe ein sechsminütiges Video aufgenommen, in dem ich mir die Installation des Moduls anschaue cpapi und Funktionen zum Ausführen von Python-Skripten auf dem Steuerungsserver. Beispielsweise wird ein Skript ausgeführt, das die Konfiguration eines neuen Gateways für eine Aufgabe wie die Netzwerküberwachung automatisiert Sicherheitscheck. Zu den Features, mit denen ich mich befassen musste: Die Funktion ist in Python 2.7 noch nicht enthalten Varianten des Eingangssignals:Um die vom Benutzer eingegebenen Informationen zu verarbeiten, wird eine Funktion verwendet raw_input. Ansonsten ist der Code derselbe wie beim Starten von anderen Maschinen, nur ist die Nutzung der Funktion komfortabler login_as_root, um Ihren eigenen Benutzernamen, Ihr Passwort und Ihre IP-Adresse des Verwaltungsservers nicht erneut anzugeben.

Skript zur schnellen Einrichtung von 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()

Eine Beispieldatei mit einem Passwortwörterbuch „additional_pass.conf“.
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Abschluss

In diesem Artikel werden nur die grundlegenden Möglichkeiten der Arbeit untersucht Python-SDK und Modul cpapi(Wie Sie vielleicht schon vermutet haben, handelt es sich hierbei tatsächlich um Synonyme), und wenn Sie den Code in diesem Modul studieren, werden Sie noch mehr Möglichkeiten entdecken, damit zu arbeiten. Möglicherweise möchten Sie es durch eigene Klassen, Funktionen, Methoden und Variablen ergänzen. Sie können Ihre Arbeit jederzeit teilen und andere Skripte für Check Point im Abschnitt ansehen CodeHub in der Gemeinschaft CheckMates, die sowohl Produktentwickler als auch Anwender zusammenbringt.

Viel Spaß beim Codieren und vielen Dank fürs Lesen bis zum Ende!

Source: habr.com

Kommentar hinzufügen