Vereenvoudigen van het werk met de Check Point API met behulp van de Python SDK

Vereenvoudigen van het werk met de Check Point API met behulp van de Python SDKDe volledige kracht van interactie met de API komt tot uiting wanneer deze in combinatie met programmatuur wordt gebruikt, waardoor de mogelijkheid ontstaat om API-aanvragen dynamisch te vormen en hulpmiddelen voor het analyseren van API-antwoorden te creƫren. Tot nu toe blijft echter nog te veel onopgemerkt Python Software Development Kit (02) Python SDK voor Check Point Management API, wat jammer is. Het vereenvoudigt het leven van ontwikkelaars en liefhebbers van automatisering aanzienlijk. Python heeft de laatste tijd enorme populariteit verworven en ik besloot de leemte op te vullen en een overzicht van de belangrijkste mogelijkheden te geven Check Point API Python Development Kit. Dit artikel dient als een uitstekende aanvulling op een ander artikel op Habr Check Point R80.10 API. Beheer via CLI, scripts en meer.. We zullen bekijken hoe we scripts kunnen schrijven met behulp van de Python SDK en meer in detail ingaan op de nieuwe functionaliteit van de Management API in versie 1.6 (ondersteund vanaf R80.40). Voor het begrijpen van het artikel zijn basiskennis van API-werking en Python vereist.

Check Point ontwikkelt de API actief en op dit moment zijn er verschenen:

De Python SDK ondersteunt momenteel alleen interactie met de Management API en Gaia API. We zullen de belangrijkste klassen, methoden en variabelen in deze module bekijken.

Vereenvoudigen van het werk met de Check Point API met behulp van de Python SDK

Installatie van de module

Module cpapi wordt snel en eenvoudig geïnstalleerd vanuit de officiële repository van Check Point op github met behulp van pip. Een gedetailleerde instructie voor de installatie is te vinden in README.md. Deze module is aangepast voor gebruik met Python-versies 2.7 en 3.7. In dit artikel worden voorbeelden gegeven met Python 3.7. De Python SDK kan echter direct vanaf de Check Point-managementserver (Smart Management) worden uitgevoerd, maar daar wordt alleen versie 2.7 ondersteund, daarom worden in het laatste deel voorbeelden voor versie 2.7 gegeven. Direct na de installatie van de module raad ik aan om de voorbeelden in de mappen te bekijken examples_python2 en examples_python3.

Aan de slag

Om met de componenten van de module cpapi te kunnen werken, moet er geĆÆmporteerd worden uit de module cpapi minstens twee noodzakelijke klassen:

APIClient en APIClientArgs

from cpapi import APIClient, APIClientArgs

Klasse APIClientArgs verantwoordelijk voor de verbindingsparameters naar de API-server, terwijl de klasse APIClient verantwoordelijk is voor de interactie met de API.

Definiƫren van de verbindingsparameters

Om verschillende verbindingsparameters naar de API te definiƫren, moet een instantie van de klasse APIClientArgsworden gemaakt. In principe zijn de parameters vooraf gedefinieerd en hoeven ze bij het uitvoeren van het script op de beheerserver niet opgegeven te worden.

client_args = APIClientArgs()

Maar bij uitvoering op een externe host moeten minstens het IP-adres of de hostnaam van de API-server (de beheerserver) opgegeven worden. In het onderstaande voorbeeld definiƫren we de verbindingsparameter server en wijzen we deze een string toe van het IP-adres van de beheerserver.

client_args = APIClientArgs(server='192.168.47.241')

Laten we kijken naar alle parameters en hun standaardwaarden die gebruikt kunnen worden bij de verbinding met de API-server:

Argumenten van de __init__ methode van de klasse APIClientArgs

class APIClientArgs:
    """
    Deze klasse biedt argumenten voor de configuratie van APIClient.
    Alle argumenten zijn geconfigureerd met hun standaardwaarden.
    """

    # poort is standaard op None ingesteld, maar wordt vervangen door 443 als deze niet is gespecificeerd
    # context mogelijke waarden - web_api (standaard) of 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
        # vingerafdruk van de beheerserver
        self.fingerprint = fingerprint
        # sessie-id.
        self.sid = sid
        # naam of IP-adres van de beheerserver
        self.server = server
        # debugniveau
        self.http_debug_level = http_debug_level
        # een array met alle API-aanroepen (voor debugdoeleinden)
        self.api_calls = api_calls if api_calls else []
        # naam van het debugbestand. Als leeg gelaten, worden debuggegevens niet op schijf opgeslagen.
        self.debug_file = debug_file
        # adres van de HTTP-proxyserver (zonder "http://")
        self.proxy_host = proxy_host
        # poort van de HTTP-proxy
        self.proxy_port = proxy_port
        # API-versie van de beheerserver
        self.api_version = api_version
        # Geeft aan dat de client het certificaat van de server niet moet controleren
        self.unsafe = unsafe
        # Geeft aan dat de client het certificaat van de server automatisch moet accepteren en opslaan
        self.unsafe_auto_accept = unsafe_auto_accept
        # De context van het gebruik van de client - standaard op web_api
        self.context = context

Ik neem aan dat de argumenten die in instanties van de klasse APIClientArgs gebruikt kunnen worden, intuĆÆtief zijn voor Check Point-beheerders en geen verdere toelichting nodig hebben.

Verbinding maken via APIClient en de contextmanager

Klasse APIClient Het is het gemakkelijkst om met een contextmanager te werken. Alles wat aan de APIClient-klasse moet worden doorgegeven, zijn de verbindingsparameters die in de vorige stap zijn gedefinieerd.

with APIClient(client_args) as client:

De contextmanager zal automatisch geen login-aanroep naar de API-server uitvoeren, maar het zal wel de logout-aanroep uitvoeren wanneer je eruit gaat. Als om de een of andere reden de logout na het werken met API-aanroepen niet nodig is, moet je beginnen zonder gebruik te maken van de contextmanager:

client = APIClient(client_args)

Verbinding controleren

Het is het eenvoudigst om te controleren of de verbinding met de opgegeven parameters werkt met de methode check_fingerprint. Als de SHA1-hashcontrole voor de fingerprint van het API-servercertificaat mislukt (de methode retourneert False), dan wordt dit meestal veroorzaakt door verbindingsproblemen en kunnen we de uitvoering van het programma stoppen (of de gebruiker de mogelijkheid geven om de verbindingsgegevens te corrigeren):

    if client.check_fingerprint() is False:
        print("Kon de fingerprint van de server niet verkrijgen - Controleer de connectiviteit met de server.")
        exit(1)

Houd er rekening mee dat de klasse APIClient bij elke API-aanroep (methoden api_call en api_query, waar we het zo meteen over zullen hebben) de SHA1-fingerprint van het certificaat op de API-server zal controleren. En als bij de controle van de SHA1-fingerprint van het certificaat van de API-server een fout wordt ontdekt (certificaat onbekend of gewijzigd), zal de methode check_fingerprint de mogelijkheid bieden om informatie erover op de lokale machine automatisch toe te voegen of te wijzigen. Deze controle kan helemaal worden uitgeschakeld (maar dit kan alleen worden aanbevolen wanneer het script op de API-server zelf draait, bij verbinding met 127.0.0.1), door de APIClientArgs-parameter te gebruiken — unsafe_auto_accept (zie meer over APIClientArgs eerder in "De verbindingsparameters definiĆ«ren").

client_args = APIClientArgs(unsafe_auto_accept=True)

Inloggen op de API-server

Er APIClient zijn in totaal 3 methoden voor inloggen op de API-server, en elke methode onthoudt de waarde sid(sessie-id), die automatisch in elke volgende API-aanroep in de header wordt gebruikt (de naam in de header van deze parameter is X-chkp-sid), dus je hoeft deze parameter niet extra te verwerken.

Login-methode

Een variant met gebruikersnaam en wachtwoord (in het voorbeeld zijn de gebruikersnaam admin en het wachtwoord 1q2w3e als positionele argumenten doorgegeven):

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

In de login-methode zijn ook aanvullende optionele parameters beschikbaar, hier zijn hun namen en standaardwaarden:

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

login_with_api_key methode

Optie met gebruik van de API-sleutel (ondersteund vanaf versie R80.40/Management API v1.6, «3TsbPJ8ZKjaJGvFyoFqHFA==» dit is de waarde van de API-sleutel voor een van de gebruikers op de beheerserver met de autorisatiemethode API-sleutel):

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

In de methode login_with_api_key zijn dezelfde optionele parameters beschikbaar als in de methode login.

login_as_root methode

Optie voor inloggen op de lokale machine met de API-server:

     login = client.login_as_root()

Voor deze methode zijn er in totaal slechts twee optionele parameters beschikbaar:

domain=None, payload=None

En tot slot de API-aanroepen

We hebben twee opties om API-aanroepen te doen via methoden api_call en api_query. Laten we de verschillen tussen hen bekijken.

api_call

Deze methode is toepasbaar voor alle aanroepen. We moeten het laatste onderdeel voor de API-aanroep en de payload in de body van het verzoek doorgeven indien nodig. Als de payload leeg is, kan deze volledig worden weggelaten:

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

De uitvoer voor dit verzoek staat onder de kat:

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

De uitvoer voor dit verzoek staat onder de kat:

In [25]: show_host                                                              
Out[25]: 
APIResponse({
    "data": {
        "color": "zwart",
        "comments": "",
        "domain": {
            "domain-type": "domein",
            "name": "SMC Gebruiker",
            "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": "ontgrendeld",
            "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": "zwart",
            "comments": "",
            "domain": {
                "domain-type": "domein",
                "name": "SMC Gebruiker",
                "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": "ontgrendeld",
                "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

Ik moet meteen duidelijk maken dat deze methode alleen van toepassing is voor aanroepen waarvan de uitvoer een offset (verschuiving) vereist. Dergelijke uitvoer komt voor wanneer er een grote hoeveelheid informatie in zit of kan zitten. Bijvoorbeeld, dit kan een aanvraag zijn voor een lijst van alle aangemaakte objecten van het type host op de beheerserver. Voor dit soort verzoeken retourneert de API standaard een lijst van 50 objecten (je kunt de limiet verhogen tot 500 objecten in het antwoord). En om te voorkomen dat je meerdere keren informatie moet ophalen door de offset-parameter in het API-verzoek te wijzigen, is er een methode api_query die dit automatisch voor je doet. Voorbeelden van aanroepen waarbij deze methode nodig is: 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. Feitelijk zien we in de naam van deze API-aanroepen woorden in meervoud, dus deze aanroepen zullen gemakkelijker te verwerken zijn via api_query

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

De uitvoer voor dit verzoek staat onder de kat:

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

Verwerken van API-aanroepresultaten

Daarna kunnen de variabelen en methoden van de klasse worden gebruikt APIResponse(zowel binnen de contextmanager als daarbuiten). De klasse APIResponse heeft 4 gedefinieerde methoden en 5 variabelen, we zullen ons meer richten op de belangrijkste.

Vereenvoudigen van het werk met de Check Point API met behulp van de Python SDK

success

Voorafgaand zou het goed zijn om te controleren of de API-aanroep succesvol was en een resultaat heeft teruggeleverd. Hiervoor is er een methode success:

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

Geeft True terug als de API-aanroep succesvol was (Statuscode — 200) en False als het niet succesvol was (iedere andere statuscode). Handig om meteen na de API-aanroep te gebruiken om op basis van de statuscode verschillende informatie weer te geven.

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

statuscode

Geeft de statuscode terug na het uitvoeren van de API-aanroep.

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

Mogelijke statuscodes: 200,400,401,403,404,409,500,501.

set_success_status

Er kan behoefte zijn om de statuswaarde success te wijzigen. Technisch gezien kan daar alles worden geplaatst, zelfs een gewone string. Maar een echt voorbeeld kan zijn om deze parameter op False te zetten onder bepaalde bijbehorende voorwaarden. Let hieronder op het voorbeeld waarin er taken zijn die op de beheerserver worden uitgevoerd, maar we beschouwen deze aanvraag als mislukt (we zetten de variabele success op False, hoewel de API-aanroep succesvol was en code 200 terugstuurde).

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

response()

De methode response toont een woordenboek met de antwoordcode (status_code) en de antwoordtekst (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

Het toont alleen de antwoordtekst (body) zonder overbodige informatie.

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

Deze informatie is alleen beschikbaar wanneer er een fout is opgetreden tijdens de verwerking van de API-aanroep (antwoordcode niet 200). Voorbeelduitvoer

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

Nuttige voorbeelden

Hieronder staan voorbeelden waarin API-aanroepen worden gebruikt die zijn toegevoegd in versie Management API 1.6.

Laten we beginnen met het bekijken van de aanroepen add-host en add-address-range. Stel dat we alle IP-adressen van het subnet 192.168.0.0/24 moeten creƫren als hostobjecten, waarbij de laatste octet gelijk is aan 5, en alle andere IP-adressen als adresbereikobjecten moeten worden vastgelegd. Daarbij dienen het subnetadres en het broadcastadres uitgesloten te worden.

Dus hieronder staat een script dat deze taak oplost en 50 hostobjecten en 51 bereikobjecten creƫert. Voor het oplossen van de taak zijn 101 API-aanroepen nodig (niet meegerekend de finale aanroep publish). Ook met behulp van de module timeit meten we de tijd die het script nodig heeft tot het moment van publicatie van de wijzigingen.

Script met gebruik van add-host en 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'Tijd om batchaanroep uit te voeren: {stop - start} seconden')

In mijn labomgeving neemt het uitvoeren van dit script tussen de 30 en 50 seconden in beslag, afhankelijk van de belasting op de beheerserver.

Laten we nu eens kijken hoe we dezelfde taak kunnen oplossen met een API-aanroep add-objects-batch, waarvan de ondersteuning is toegevoegd in API versie 1.6. Deze aanroep stelt ons in staat om in ƩƩn API-aanroep meerdere objecten tegelijkertijd aan te maken. Dit kunnen objecten van verschillende typen zijn (bijvoorbeeld hosts, subnetten en adressenreeksen). Hierdoor kan onze taak worden opgelost binnen ƩƩn API-aanroep.

Script met gebruik van 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'Tijd om batchaanroep uit te voeren: {stop - start} seconden')

Voor het uitvoeren van dit script in mijn labomgeving is het nodig om tussen de 3 en 7 seconden, afhankelijk van de belasting op de beheerserver. Dit betekent dat, gemiddeld, bij 101 objecten de API-aanroep van het type batch, 10 keer sneller is. Bij een groter aantal objecten zal het verschil nog indrukwekkender zijn.

Laten we nu eens kijken hoe we kunnen werken met set-objects-batch. Met deze API-aanroep kunnen we massaal elke parameter wijzigen. Laten we de eerste helft van de adressen uit het vorige voorbeeld (tot .124 host, inclusief de bereik) de kleur sienna geven, en de tweede helft van de adressen de kleur khaki toekennen.

Kleurwijziging van objecten, aangemaakt in het vorige voorbeeld.

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

Een groot aantal objecten in ƩƩn API-aanroep kan worden verwijderd met behulp van delete-objects-batch. Laten we nu kijken naar een codevoorbeeld dat alle eerder gemaakte hosts verwijdert via add-objects-batch.

Objecten verwijderen met behulp van 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)

Alle functies die verschijnen in nieuwe releases van Check Point-software krijgen onmiddellijk API-aanroepen. In R80.40 zijn er functies zoals Revert to revision en Smart Task geïntroduceerd, en daarvoor zijn onmiddellijk de bijbehorende API-aanroepen voorbereid. Bovendien krijgt alle functionaliteit bij de overgang van Legacy-consoles naar de Unified Policy-modus ook API-ondersteuning. Een van de meest verwachte updates in de R80.40 softwareversie was de overgang van het HTTPS Inspection-beleid van de Legacy-modus naar de Unified Policy-modus, en deze functionaliteit heeft onmiddellijk API-aanroepen gekregen. Hier is een voorbeeld van de code die een regel toevoegt aan de bovenste positie van het HTTPS Inspection-beleid, die drie categorieën (Gezondheid, Financiën, Overheidsdiensten) uitsluit van inspectie, zoals vereist door de wetgeving in verschillende landen.

Voeg een regel toe aan het HTTPS Inspection-beleid

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

data = {
  "layer" : "Default Layer",
  "position" : "top",
  "name" : "Juridische Vereisten",
  "action": "bypass",
  "site-category": ["Gezondheid", "Overheid / Militaire", "Financiƫle Diensten"]
}

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

Het starten van Python-scripts op de Check Point-beheerserver

En verder README.md bevat informatie over hoe Python-scripts direct vanaf de beheerserver kunnen worden uitgevoerd. Dit kan handig zijn wanneer je niet de mogelijkheid hebt om verbinding te maken met de API-server vanaf een andere machine. Ik heb een zes minuten durende video opgenomen waarin ik de installatie van de module bespreek cpapi en de kenmerken van het starten van Python-scripts op de beheerserver. Als voorbeeld wordt een script uitgevoerd dat de configuratie van een nieuwe gateway automatiseert voor een taak zoals netwerk auditing Security CheckUp. Een van de uitdagingen waarmee ik te maken kreeg: in Python 2.7 is de functie nog niet beschikbaar input, dus voor het verwerken van informatie die de gebruiker invoert, wordt de functie gebruikt raw_input. Verder is de code hetzelfde als voor het uitvoeren vanaf andere machines, alleen is het handiger om de functie login_as_rootte gebruiken, zodat je niet opnieuw je eigen gebruikersnaam, wachtwoord en IP-adres van de beheerserver hoeft op te geven.

Video afspelen

Script voor snelle configuratie van 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("Kon kon het vingerprint van de server niet verkrijgen - Controleer de connectiviteit met de server.")
       #     exit(1)
        login_res = client.login_as_root()

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

        gw_name = raw_input("Voer de naam van de gateway in:")
        gw_ip = raw_input("Voer het IP-adres van de gateway in:")
        if sys.stdin.isatty():
            sic = getpass.getpass("Voer het eenmalige wachtwoord voor de gateway (SIC) in:")
        else:
            print("Let op! Uw wachtwoord zal op het scherm worden weergegeven!")
            sic = raw_input("Voer het eenmalige wachtwoord voor de gateway (SIC) in:")
        version = raw_input("Voer de versie van de gateway in (bijv. 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("Veilige verbinding met de gateway is niet tot stand gebracht!")
            exit(1)
        elif add_gw.success:
            print("De gateway is succesvol toegevoegd.")
            gw_uid = add_gw.data['uid']
            gw_name = add_gw.data['name']
        else:
            print("Toevoegen van de gateway mislukt - {}".format(add_gw.error_message))
            exit(1)

        change_policy = client.api_call("set-access-layer", {"name" : "Netwerk", "applications-and-url-filtering": "true", "content-awareness": "true"})
        if change_policy.success:
            print("Het beleid is succesvol gewijzigd")
        else:
            print("Wijzigen van het beleid mislukt - {}".format(change_policy.error_message))
        change_rule = client.api_call("set-access-rule", {"name" : "Cleanup rule", "layer" : "Netwerk", "action": "Accept", "track": {"type": "Gedetailleerd Logboek", "accounting": "true"}})
        if change_rule.success:
            print("De cleanup rule is succesvol gewijzigd")
        else:
            print("Wijzigen van de cleanup rule mislukt - {}".format(change_rule.error_message))

        # publiceer het resultaat
        publish_res = client.api_call("publish", {})
        if publish_res.success:
            print("De wijzigingen zijn succesvol gepubliceerd.")
        else:
                print("Publiceren van de wijzigingen mislukt - {}".format(install_tp_policy.error_message))

        install_access_policy = client.api_call("install-policy", {"policy-package" : "Standaard", "access" : 'true',  "threat-prevention" : 'false', "targets" : gw_uid})
        if install_access_policy.success:
            print("Het toegangsbeleid is geĆÆnstalleerd")
        else:
                print("Installeren van het toegangsbeleid mislukt - {}".format(install_tp_policy.error_message))

        install_tp_policy = client.api_call("install-policy", {"policy-package" : "Standaard", "access" : 'false',  "threat-prevention" : 'true', "targets" : gw_uid})
        if install_tp_policy.success:
            print("Het dreigingspreventiebeleid is geĆÆnstalleerd")
        else:
            print("Installeren van het dreigingspreventiebeleid mislukt - {}".format(install_tp_policy.error_message))
        
        # voeg wachtwoorden en wachtzinnen toe aan het woordenboek
        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" : "Voeg wachtwoorden en wachtzinnen toe", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
                if add_password_dictionary.success:
                    print("De dictionaryregel {} is succesvol toegevoegd".format(line_num))
                else:
                    print("Toevoegen van de dictionary is mislukt - {}".format(add_password_dictionary.error_message))

main()

Voorbeeld van een bestand met een wachtwoordenwoordenboek additional_pass.conf
{
"passwords" : ["malware","kwaadaardig","geĆÆnfecteerd","GeĆÆnfecteerd"],
"phrases" : ["wachtwoord","Wachtwoord","Pas","pas","codigo","sleutel","pwd","wachtwoord","Wachtwoord","Sleutel","sleutel","versleuteling","Versleuteling"]
}

Conclusie

Dit artikel behandelt alleen de basisfunctionaliteiten Python SDK en module cpapi(zoals je misschien al kon raden, zijn dit eigenlijk synoniemen), en door de code in deze module te bestuderen, ontdek je nog meer mogelijkheden voor het werken ermee. Het kan zijn dat je de wens krijgt om het aan te vullen met je eigen klassen, functies, methoden en variabelen. Je kunt altijd je eigen werk delen en andere scripts voor Check Point bekijken in de sectie CodeHub in de gemeenschap CheckMates, die zowel ontwikkelaars van producten als gebruikers verenigt.

Veel programmeerplezier en bedankt dat je tot het einde hebt gelezen!

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster