Vereenvoudiging van de Check Point API met de Python SDK

Vereenvoudiging van de Check Point API met de Python SDKDe volledige kracht van interactie met API's komt tot uiting wanneer het samen met programmacode wordt gebruikt, wanneer het mogelijk wordt om op dynamische wijze API-verzoeken en tools te genereren voor het analyseren van API-reacties. Het blijft echter nog steeds onmerkbaar Python-softwareontwikkelingskit (hierna Python SDK genoemd) voor Check Point Management-API, maar tevergeefs. Het vereenvoudigt het leven van ontwikkelaars en automatiseringsliefhebbers aanzienlijk. Python is de laatste tijd enorm populair geworden en ik besloot het gat op te vullen en de belangrijkste functies te bekijken. Check Point API Python-ontwikkelingskit. Dit artikel vormt een uitstekende aanvulling op een ander artikel over Habré Controleer punt R80.10 API. Beheer via CLI, scripts en meer. We bekijken hoe u scripts schrijft met behulp van de Python SDK en bekijken de nieuwe Management API-functionaliteit in versie 1.6 (ondersteund vanaf R80.40). Om het artikel te begrijpen, heb je basiskennis nodig van het werken met API's en Python.

Check Point is actief bezig met de ontwikkeling van de API en op dit moment zijn de volgende releases uitgebracht:

De Python SDK ondersteunt momenteel alleen interactie met de Management API en Gaia-API. In deze module bekijken we de belangrijkste klassen, methoden en variabelen.

Vereenvoudiging van de Check Point API met de Python SDK

Module-installatie

Module cpapi installeert snel en eenvoudig vanaf officiële Check Point-repository op github via pit. Gedetailleerde installatie-instructies zijn beschikbaar in README.md. Deze module is aangepast om te werken met Python-versies 2.7 en 3.7. In dit artikel worden voorbeelden gegeven van Python 3.7. De Python SDK kan echter rechtstreeks vanaf de Check Point Management Server (Smart Management) worden uitgevoerd, maar deze ondersteunt alleen Python 2.7, dus de laatste sectie bevat code voor versie 2.7. Direct na het installeren van de module raad ik aan om de voorbeelden in de mappen te bekijken voorbeelden_python2 и voorbeelden_python3.

Aan de slag

Om met de componenten van de cpapi-module te kunnen werken, moeten we vanuit de module importeren cpapi minimaal twee verplichte klassen:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Klasse APIClientArgs is verantwoordelijk voor de verbindingsparameters met de API-server en de klasse APIClient is verantwoordelijk voor de interactie met de API.

Verbindingsparameters bepalen

Om verschillende parameters te definiëren voor het verbinden met de API, moet u een exemplaar van de klasse maken APIClientArgs. In principe zijn de parameters ervan vooraf gedefinieerd en wanneer het script op de besturingsserver wordt uitgevoerd, hoeven ze niet te worden gespecificeerd.

client_args = APIClientArgs()

Maar als u op een host van derden draait, moet u minimaal het IP-adres of de hostnaam van de API-server (ook wel de beheerserver genoemd) opgeven. In het onderstaande voorbeeld definiëren we de serververbindingsparameter en wijzen hieraan het IP-adres van de beheerserver toe als een tekenreeks.

client_args = APIClientArgs(server='192.168.47.241')

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

Argumenten van de methode __init__ van de klasse APIClientArgs

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

Ik geloof dat de argumenten die kunnen worden gebruikt in instances van de klasse APIClientArgs intuïtief zijn voor Check Point-beheerders en geen extra commentaar vereisen.

Verbinding maken via APIClient en contextmanager

Klasse APIClient De handigste manier om het te gebruiken is via de contextmanager. Het enige dat moet worden doorgegeven aan een exemplaar van de APIClient-klasse zijn de verbindingsparameters die in de vorige stap zijn gedefinieerd.

with APIClient(client_args) as client:

De contextmanager zal niet automatisch een login-oproep doen naar de API-server, maar zal wel een uitlog-oproep doen wanneer deze wordt afgesloten. Als u om de een of andere reden niet hoeft uit te loggen nadat u klaar bent met het werken met API-aanroepen, moet u beginnen te werken zonder de contextmanager te gebruiken:

client = APIClient(clieng_args)

Verbindingstest

De eenvoudigste manier om te controleren of de verbinding aan de opgegeven parameters voldoet, is met behulp van de methode check_vingerafdruk. Als de verificatie van de sha1-hashsom voor de vingerafdruk van het server-API-certificaat mislukt (de methode retourneert Niet waar), dan wordt dit meestal veroorzaakt door verbindingsproblemen en kunnen we de uitvoering van het programma stopzetten (of de gebruiker de mogelijkheid geven om de verbindingsgegevens te corrigeren):

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

Houd er rekening mee dat in de toekomst de klasse APIClient controleert elke API-aanroep (methods api_call и api_query, we zullen er wat verder over praten) sha1 vingerafdrukcertificaat op de API-server. Maar als er bij het controleren van de sha1-vingerafdruk van het API-servercertificaat een fout wordt ontdekt (het certificaat is onbekend of gewijzigd), kan de methode check_vingerafdruk biedt de mogelijkheid om er automatisch informatie over toe te voegen/wijzigen op de lokale machine. Deze controle kan volledig worden uitgeschakeld (maar dit kan alleen worden aanbevolen als scripts worden uitgevoerd op de API-server zelf, bij verbinding met 127.0.0.1), met behulp van het APIClientArgs-argument - unsafe_auto_accept (zie meer over APIClientArgs eerder in “Verbindingsparameters definiëren”).

client_args = APIClientArgs(unsafe_auto_accept=True)

Log in op de API-server

У APIClient er zijn maar liefst 3 methoden om in te loggen op de API-server, en elk van hen begrijpt de betekenis sid(session-id), die automatisch wordt gebruikt bij elke volgende API-aanroep in de header (de naam in de header van deze parameter is X-chkp-zijde), dus het is niet nodig om deze parameter verder te verwerken.

login methode

Optie met login en wachtwoord (in het voorbeeld worden de gebruikersnaam admin en het wachtwoord 1q2w3e doorgegeven als positionele argumenten):

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

Er zijn ook aanvullende optionele parameters beschikbaar in de inlogmethode; hier zijn hun namen en standaardwaarden:

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

Login_with_api_key-methode

Optie waarbij een API-sleutel wordt gebruikt (ondersteund vanaf beheerversie R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" dit is de API-sleutelwaarde voor een van de gebruikers op de beheerserver met de API-sleutelautorisatiemethode):

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

In methode login_met_api_key dezelfde optionele parameters zijn beschikbaar als in de methode Log in.

login_as_root methode

Optie om in te loggen op een lokale machine met een API-server:

     login = client.login_as_root()

Er zijn slechts twee optionele parameters beschikbaar voor deze methode:

domain=None, payload=None

En ten slotte roept de API zichzelf aan

We hebben twee opties om API-aanroepen te doen via methoden api_call и api_query. Laten we eens kijken wat het verschil tussen hen is.

api_call

Deze methode is van toepassing op alle oproepen. We moeten indien nodig het laatste deel van de API-aanroep en de payload in de aanvraagtekst doorgeven. Als de payload leeg is, kan deze helemaal niet worden verzonden:

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

Uitvoer voor dit verzoek onder de snede:

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

Uitvoer voor dit verzoek onder de snede:

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

Laat ik meteen een voorbehoud maken dat deze methode alleen van toepassing is op oproepen waarvan de uitvoer offset met zich meebrengt. Een dergelijke gevolgtrekking doet zich voor wanneer het een grote hoeveelheid informatie bevat of kan bevatten. Dit kan bijvoorbeeld een verzoek zijn om een ​​lijst met alle gemaakte hostobjecten op de beheerserver. Voor dergelijke verzoeken retourneert de API standaard een lijst met 50 objecten (u kunt de limiet in het antwoord verhogen tot 500 objecten). En om de informatie niet meerdere keren op te halen en de offsetparameter in het API-verzoek te wijzigen, is er een api_query-methode die dit automatisch doet. Voorbeelden van oproepen waarbij deze methode nodig is: show-sessies, show-hosts, show-netwerken, show-wildcards, show-groepen, show-adresbereiken, show-simple-gateways, show-simple-clusters, show-access-rollen, show-trusted-clients, show-pakketten. In feite zien we meervoudige woorden in de naam van deze API-aanroepen, dus deze oproepen zullen gemakkelijker te verwerken zijn api_query

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

Uitvoer voor dit verzoek onder de snede:

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

Het verwerken van de resultaten van API-aanroepen

Hierna kunt u de variabelen en methoden van de klasse gebruiken API-antwoord(zowel binnen de contextmanager als daarbuiten). In de klas API-antwoord Er zijn 4 methoden en 5 variabelen vooraf gedefinieerd; we zullen dieper ingaan op de belangrijkste.

Vereenvoudiging van de Check Point API met de Python SDK

succes

Om te beginnen zou het een goed idee zijn om ervoor te zorgen dat de API-aanroep succesvol was en een resultaat opleverde. Hiervoor bestaat een methode succes:

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

Retourneert True als de API-aanroep succesvol was (reactiecode - 200) en False als deze niet succesvol was (een andere responscode). Het is handig om direct na een API-aanroep verschillende informatie weer te geven, afhankelijk van de responscode.

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

status code

Retourneert de responscode nadat een API-aanroep is gedaan.

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

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

set_success_status

In dit geval kan het nodig zijn om de waarde van de successtatus te wijzigen. Technisch gezien kun je daar alles plaatsen, zelfs een gewone string. Maar een reëel voorbeeld zou het opnieuw instellen van deze parameter op False zijn onder bepaalde begeleidende omstandigheden. Let hieronder op het voorbeeld waarin er taken worden uitgevoerd op de beheerserver, maar we beschouwen dit verzoek als niet succesvol (we zullen de succesvariabele instellen op Niet waar, ondanks het feit dat de API-aanroep succesvol was en code 200 retourneerde).

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

antwoord()

Met de responsmethode kunt u het woordenboek bekijken met de responscode (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']}}

gegevens

Hiermee kunt u alleen de hoofdtekst van het antwoord (body) zien zonder onnodige 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']}

foutbericht

Deze informatie is alleen beschikbaar als er een fout is opgetreden tijdens het verwerken van het API-verzoek (responscode geen 200). Voorbeelduitvoer

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

Nuttige voorbeelden

Hieronder volgen voorbeelden waarin de API-aanroepen worden gebruikt die zijn toegevoegd in Management API 1.6.

Laten we eerst eens kijken hoe oproepen werken add-host и adresbereik toevoegen. Laten we zeggen dat we alle IP-adressen van het subnet 192.168.0.0/24, waarvan het laatste octet 5 is, moeten aanmaken als objecten van het hosttype, en alle andere IP-adressen moeten schrijven als objecten van het adresbereiktype. Sluit in dit geval het subnetadres en het broadcastadres uit.

Hieronder staat dus een script dat dit probleem oplost en 50 objecten van het hosttype en 51 objecten van het adresbereiktype maakt. Om het probleem op te lossen zijn 101 API-aanroepen vereist (de laatste publicatieaanroep niet meegerekend). Ook berekenen we met behulp van de timeit-module de tijd die nodig is om het script uit te voeren totdat de wijzigingen worden gepubliceerd.

Script met 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'Time to execute batch request: {stop - start} seconds')

In mijn labomgeving duurt de uitvoering van dit script tussen de 30 en 50 seconden, afhankelijk van de belasting op de beheerserver.

Laten we nu eens kijken hoe we hetzelfde probleem kunnen oplossen met behulp van een API-aanroep add-objecten-batch, waarvoor ondersteuning is toegevoegd in API-versie 1.6. Met deze aanroep kunt u in één API-verzoek veel objecten tegelijk maken. Bovendien kunnen dit objecten van verschillende typen zijn (bijvoorbeeld hosts, subnetten en adresbereiken). Onze taak kan dus worden opgelost binnen het kader van één API-oproep.

Script met 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')

En het uitvoeren van dit script in mijn labomgeving duurt 3 tot 7 seconden, afhankelijk van de belasting op de beheerserver. Dat wil zeggen dat op 101 API-objecten een batchtype-aanroep gemiddeld 10 keer sneller wordt uitgevoerd. Op een groter aantal objecten zal het verschil nog indrukwekkender zijn.

Laten we nu kijken hoe we ermee kunnen werken set-objecten-batch. Met behulp van deze API-aanroep kunnen we elke parameter in bulk wijzigen. Laten we de eerste helft van de adressen uit het vorige voorbeeld (tot .124 hosts, en ook bereiken) instellen op de kleur sienna, en de kleur kaki toewijzen aan de tweede helft van de adressen.

De kleur wijzigen van de objecten die in het vorige voorbeeld zijn gemaakt

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

U kunt meerdere objecten in één API-aanroep verwijderen met behulp van verwijder-objecten-batch. Laten we nu eens kijken naar een codevoorbeeld dat alle hosts verwijdert die eerder zijn gemaakt via add-objecten-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 in nieuwe releases van Check Point-software verschijnen, krijgen onmiddellijk API-aanroepen. Zo verschenen in R80.40 ‘functies’ als Terug naar revisie en Smart Task, en werden overeenkomstige API-aanroepen onmiddellijk voor hen voorbereid. Bovendien krijgt alle functionaliteit bij het overstappen van Legacy-consoles naar de Unified Policy-modus ook API-ondersteuning. De langverwachte update in softwareversie R80.40 was bijvoorbeeld de verplaatsing van het HTTPS-inspectiebeleid van de Legacy-modus naar de Unified Policy-modus, en deze functionaliteit ontving onmiddellijk API-aanroepen. Hier is een voorbeeld van code die een regel toevoegt aan de toppositie van het HTTPS-inspectiebeleid die 3 categorieën uitsluit van inspectie (gezondheidszorg, financiën, overheidsdiensten), die in een aantal landen volgens de wet verboden zijn voor inspectie.

Voeg een regel toe aan het HTTPS-inspectiebeleid

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

Python-scripts uitvoeren op de Check Point-beheerserver

Alles is hetzelfde README.md bevat informatie over hoe u Python-scripts rechtstreeks vanaf de controleserver kunt uitvoeren. Dit kan handig zijn als u vanaf een andere machine geen verbinding kunt maken met de API-server. Ik heb een video van zes minuten opgenomen waarin ik kijk naar het installeren van de module cpapi en functies voor het uitvoeren van Python-scripts op de controleserver. Er wordt bijvoorbeeld een script uitgevoerd dat de configuratie van een nieuwe gateway automatiseert voor een taak zoals netwerkaudit Beveiligingscontrole. Een van de features waarmee ik te maken kreeg: de functie is nog niet verschenen in Python 2.7 invoer, dus om de informatie die de gebruiker invoert te verwerken, wordt een functie gebruikt ruwe invoer. Anders is de code hetzelfde als voor het starten vanaf andere machines, alleen is het handiger om de functie te gebruiken login_as_root, zodat u niet opnieuw uw eigen gebruikersnaam, wachtwoord en IP-adres van de beheerserver hoeft op te geven.

Script voor snelle installatie 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("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()

Een voorbeeldbestand met een wachtwoordwoordenboek extra_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Conclusie

Dit artikel onderzoekt alleen de basismogelijkheden van werk Python-SDK en moduul cpapi(zoals je misschien al geraden hebt, zijn dit eigenlijk synoniemen), en door de code in deze module te bestuderen zul je nog meer mogelijkheden ontdekken om ermee te werken. Het is mogelijk dat u het wilt aanvullen met uw eigen klassen, functies, methoden en variabelen. U kunt uw werk altijd delen en andere scripts voor Check Point bekijken in de sectie CodeHub in de gemeenschap CheckMates, dat zowel productontwikkelaars als gebruikers samenbrengt.

Veel codeerplezier en bedankt voor het lezen tot het einde!

Bron: www.habr.com

Voeg een reactie