Egyszerűsítjük a Check Point API használatát Python SDK-val

Egyszerűsítjük a Check Point API használatát Python SDK-valAz API-val való interakció teljes ereje akkor bontakozik ki, amikor programkóddal együtt használjuk, aminek köszönhetően lehetőség nyílik az API kérések dinamikus formálására és az API válaszok elemzésére. Azonban továbbra is viszonylag észrevétlen marad Python Szoftverfejlesztői Keretrendszer (... a továbbiakban: Python SDK) a Check Point Management API-hoz, ami kár. Érzékelhetően megkönnyíti a fejlesztők és az automatizálás iránt érdeklődők életét. A Python az utóbbi időben hatalmas népszerűségnek örvend, úgy döntöttem, hogy áthidalom a szakadékot, és áttekintem a főbb lehetőségeket. Check Point API Python Fejlesztői Készlet. Ez a cikk remek kiegészítése a Habr keretein belül megjelent másik írásnak. Check Point R80.10 API. Kezelés CLI-n, szkripteken és még sok máson keresztül. Most megnézzük, hogyan írjunk szkripteket a Python SDK használatával, és részletesebben foglalkozunk az új Management API funkcióval az 1.6-os verzióban (amelyet az R80.40-től támogatnak). A cikk megértéséhez alapvető tudás szükséges az API-k és a Python használatáról.

A Check Point aktívan fejleszti az API-t, és jelenleg az alábbi lehetőségek állnak rendelkezésre:

Python SDK jelenleg csak a Management API-val és Gaia API-val támogatott.Megnézzük a legfontosabb osztályokat, módszereket és változókat ebben a modulban.

Egyszerűsítjük a Check Point API használatát Python SDK-val

A modul telepítése

Modul cpapi gyorsan és egyszerűen telepíthető a Check Point hivatalos GitHub-repozitóriumából. segítségével pipRészletes telepítési útmutató található a README.mdoldalon. Ez a modul a Python 2.7 és 3.7 verziókkal való munkára lett optimalizálva. Ebben a cikkben a példák Python 3.7 használatával lesznek bemutatva. Azonban a Python SDK közvetlenül a Check Point vezérlő szerverről (Smart Management) is futtatható, de ezeken csak Python 2.7 verzió támogatott, ezért az utolsó szakaszban a 2.7-es verzióhoz tartozó kódot mutatjuk be. A modul telepítése után javaslom, hogy tekintse meg a példákat a examples_python2 és examples_python3.

Munka kezdetek

Ahhoz, hogy lehetőségünk legyen a cpapi modul összetevőivel dolgozni, importálnunk kell a modulból cpapi legalább két szükséges osztályt:

APIClient és APIClientArgs

a cpapi-ból importálva: APIClient, APIClientArgs

Osztály APIClientArgs az API szerverhez való csatlakozás paramétereiért felelős, míg az osztály APIClient az API-val való interakcióért felelős.

A csatlakozási paraméterek meghatározása

Ahhoz, hogy különböző API-hoz való csatlakozási paramétereket határozzunk meg, létre kell hozni egy példányt az osztályból APIClientArgs. Alapvetően a paraméterei előre meg vannak határozva, és a vezérlő szerveren futó szkript indításakor nem szükséges megadni őket.

client_args = APIClientArgs()

De külső hoszton való indításkor meg kell adni legalább az API szerver IP címét vagy nevét (ami a vezérlő szerver is). Az alábbi példában meghatározzuk a server csatlakozási paramétert, és string formátumban hozzárendeljük a vezérlő szerver IP címét.

client_args = APIClientArgs(server='192.168.47.241')

Nézzük meg az összes paramétert és azok alapértelmezett értékeit, amelyeket felhasználhatunk az API szerverhez való csatlakozáshoz:

Az APIClientArgs osztály __init__ metódusának argumentumai

class APIClientArgs:
    """
    Ez az osztály az APIClient konfigurációjához szükséges argumentumokat biztosítja.
    Minden argumentumot alapértelmezett értékeikkel konfigurálnak.
    """

    # a port alapértelmezés szerint None-ra van állítva, de ha nem adták meg, 443-ra cseréli
    # lehetséges értékek - web_api (alapértelmezett) vagy 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
        # vezérlő szerver ujjlenyomata
        self.fingerprint = fingerprint
        # session-id.
        self.sid = sid
        # vezérlő szerver neve vagy IP-címe
        self.server = server
        # debuggolási szint
        self.http_debug_level = http_debug_level
        # tömb minden API hívással (debug célokra)
        self.api_calls = api_calls if api_calls else []
        # a debug fájl neve. Ha üresen hagyják, a debug adatok nem kerülnek mentésre.
        self.debug_file = debug_file
        # HTTP proxy szerver címe ("http://" nélkül)
        self.proxy_host = proxy_host
        # HTTP proxy port
        self.proxy_port = proxy_port
        # A vezérlő szerver API verziója
        self.api_version = api_version
        # Jelzi, hogy az ügyfélnek nem kell ellenőriznie a szerver tanúsítványát
        self.unsafe = unsafe
        # Jelzi, hogy az ügyfél automatikusan elfogadja és menti a szerver tanúsítványát
        self.unsafe_auto_accept = unsafe_auto_accept
        # Az ügyfél használatának kontextusa - alapértelmezetten web_api
        self.context = context

Úgy vélem, hogy az APIClientArgs osztály példányainál használható argumentumok az adminisztrátorok számára intuitívan érthetők, így a további megjegyzések feleslegesek.

Csatlakozás APIClient-en keresztül és a kontextuskezelő segítségével

Osztály APIClient A legkényelmesebb, ha a context manager-en keresztül használjuk. Minden, amit az APIClient osztály példányának át kell adni, azok a csatlakozási paraméterek, amelyeket az előző lépésben határoztunk meg.

with APIClient(client_args) as client:

A context manager nem fog automatikusan bejelentkezni az API szerverre, de kijelentkezést fog végezni a kilépéskor. Ha valamilyen okból a logout végrehajtására nincs szükség az API hívások befejezése után, el kell kezdeni a munkát context manager használata nélkül:

client = APIClient(client_args)

Kapcsolat ellenőrzése

A kapcsolati paraméterek ellenőrzése legkönnyebben a következő metódussal végezhető: check_fingerprint. Ha a szerver API tanúsítványának fingerprint SHA1 hash ellenőrzése nem sikerül (a metódus visszaadta False), akkor ez általában kapcsolati problémákra utal, és leállíthatjuk a program végrehajtását (vagy lehetőséget adhatunk a felhasználónak a csatlakozási adatok javítására):

    if client.check_fingerprint() is False:
        print("Nem sikerült megkapni a szerver fingerprint-jét - Ellenőrizze a kapcsolatot a szerverrel.")
        exit(1)

Vegye figyelembe, hogy a továbbiakban az osztály APIClient minden egyes API hívás során (a api_call és api_query, melyekről később lesz szó) ellenőrizni fogja a szerver API tanúsítványának SHA1 fingerprint-jét. Ha a szerver API tanúsítványának SHA1 fingerprint-jének ellenőrzésekor hiba lép fel (a tanúsítvány ismeretlen vagy módosított), a metódus check_fingerprint lehetőséget ad arra, hogy automatikusan hozzáadja/változtassa a helyi gépen tárolt információkat. Ezt az ellenőrzést teljesen ki lehet kapcsolni (de ezt csak a skriptek API szerveren való futtatása esetén lehet javasolni, mikor a 127.0.0.1-hez csatlakozik) az APIClientArgs érvet használva — unsafe_auto_accept (további információk az APIClientArgs-ről a „Kapcsolati paraméterek meghatározása” résznél).

client_args = APIClientArgs(unsafe_auto_accept=True)

Bejelentkezés az API szerverre

A APIClient Három teljesen különböző módszer van a bejelentkezésre az API szerverre, és mindegyik megjegyzi a sid(session-id) értékét, amelyet automatikusan felhasznál a következő API hívások során a fejlécben (a paraméter neve a fejlécben — X-chkp-sid), így nincs szükség ennek a paraméternek a külön kezelésére.

Bejelentkezési metódus

A példa felhasználónév admin és jelszó 1q2w3e, amelyeket pozíciós argumentumokként adtunk át:

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

A bejelentkezési metódusban további opcionális paraméterek is elérhetőek, itt van a nevük és az alapértelmezett értékük:

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

login_with_api_key módszer

API kulcs használatával készült változat (támogatott a R80.40/mgmt API v1.6 verziótól kezdve, «3TsbPJ8ZKjaJGvFyoFqHFA==» ez az API kulcs értéke az egyik felhasználó számára a kezelői szerveren az API kulcs hitelesítési módszer használatával):

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

A módszerben login_with_api_key ugyanazok az opcionális paraméterek érhetők el, mint a login.

login_as_root módszer

API szerverhez való lokális bejelentkezés alternatíva:

     login = client.login_as_root()

Ehhez a módszerhez csupán két opcionális paraméter érhető el:

domain=None, payload=None

És végül maguk az API hívások

Két lehetőségünk van az API hívások végrehajtására a módszereken keresztül. api_call és api_queryNézzük meg, miben különbözik a kettő.

api_call

Ez a módszer bármilyen hívásra alkalmazható. Az utolsó részt kell átadni az API híváshoz és a payload-ot a kérés testében, ha szükséges. Ha a payload üres, akkor azt nem szükséges átadni:

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

A kérdés kimenete a következő:

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

A kérdés kimenete a következő:

A [25]: show_host                                                              
Out[25]: 
APIResponse({
    "data": {
        "color": "fekete",
        "comments": "",
        "domain": {
            "domain-type": "domain",
            "name": "SMC Felhasználó",
            "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": "fekete",
            "comments": "",
            "domain": {
                "domain-type": "domain",
                "name": "SMC Felhasználó",
                "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

Előre szeretném jelezni, hogy ez a módszer csak olyan hívásokra alkalmazható, ahol az output offset-re (eltolásra) van szükség. Ilyen output akkor jön létre, ha nagy mennyiségű információt kell megjeleníteni. Például ez lehet egy lekérdezés az összes létrehozott host típusú objektum listájáról a kezelő szerveren. Az ilyen lekérdezésekhez az API alapértelmezés szerint 50 objektumot ad vissza (a válaszként visszakapható objektumok számát 500-ra növelhetjük). Annak érdekében, hogy ne kelljen többször meghívni az információt az API hívás offset paraméterének megváltoztatásával, van egy api_query nevű módszer, amely ezt automatikusan elvégzi. Példák a hívásokra, ahol szükség van erre a módszerre: 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. Valójában ezekben az API hívásokban a neveken láthatóak a többes számú szavak, így ezeket a hívásokat könnyebb lesz kezelni a api_query

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

A kérdés kimenete a következő:

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

Az API hívások eredményeinek feldolgozása

Ezután használhatók a változók és a osztály metódusai APIResponse(akár a kontextus kezelő belsejében, akár kívül). Az osztálynak APIResponse 4 metódusa és 5 változója van, a legfontosabbakkal részletesebben foglalkozunk.

Egyszerűsítjük a Check Point API használatát Python SDK-val

success

Első lépésként jó lenne megbizonyosodni arról, hogy az API hívás sikeresen végrehajtódott és eredményt adott vissza. Erre van a metódus success:

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

True értéket ad vissza, ha az API hívás sikeresen végrehajtódott (válasz kód — 200) és False értéket, ha nem, (bármely más válaszkód). Hasznos az API hívás után azonnal ellenőrizni, hogy a válaszkód alapján különböző információt adhassunk meg.

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

statuscode

Visszaadja a válaszkódot az API hívás végrehajtása után.

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

Lehetséges válaszkódok: 200,400,401,403,404,409,500,501.

set_success_status

Lehetőség van a success státusz értékének megváltoztatására. Technikai szempontból bármit be lehet helyezni, akár egy egyszerű stringet is. De egy valós példa az lehet, amikor ezt a paramétert False-ra állítjuk bizonyos kiegészítő körülmények között. Alább figyeljen arra a példára, amikor feladatokat hajtunk végre a vezérlő szerveren, de ezt a kérelmet sikertelennek tekintjük (a success változót False, annak ellenére, hogy az API hívás sikeres volt, és 200 kódot adott vissza).

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

response()

A response metódus lehetővé teszi a válaszkód szótárának (status_code) és a válasz törzsének (body) megtekintését.

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

Lehetővé teszi a válasz törzsének (body) megtekintését felesleges információk nélkül.

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

Ez az információ csak akkor érhető el, amikor API kérés feldolgozása során hiba lépett fel (válaszkód nem 200). Példa a kimenetre

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

Hasznos példák

Az alábbiakban bemutatott példákban azok az API hívások szerepelnek, amelyeket a Management API 1.6-os verziójába adtak hozzá.

Először nézzük meg a hívások működését add-host és add-address-range. Tegyük fel, hogy a 192.168.0.0/24 alhálózat összes ip címe típusú host objektumként 5-ös utolsó oktettű címként jön létre, míg az összes többi ip cím típusként a cím tartományának objekteként kerül rögzítésre. Ezenkívül az alhálózat címét és a széles sávú címet ki kell zárni.

Így az alábbiakban bemutatott skript megoldja ezt a feladatot, és létrehoz 50 típusú host objektumot és 51 cím tartomány objektumot. A feladat megoldásához összesen 101 API hívás szükséges (a végső publish hívást nem számítva). Emellett a timeit modul segítségével számítjuk ki a script végrehajtására fordított időt a változások közzététele előtt.

A skript az add-host és add-address-range használatával

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

A laboratóriumi környezetemben ennek a szkriptnek a végrehajtása 30 és 50 másodperc között mozog, a vezérlő szerver terhelésétől függően.

Most nézzük meg, hogyan oldhatjuk meg ugyanezt a problémát API hívás segítségével. add-objects-batch, amelynek támogatása az API 1.6 verzióban került bevezetésre. Ez a hívás lehetővé teszi, hogy egy API kérés során több objektumot is létrehozzunk. Ráadásul ezek különböző típusú objektumok lehetnek (például gazdák, alhálózatok és címkörök). Így a feladatunk egy API hívással megoldható.

A script a add-objects-batch használatával

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

A szkript végrehajtásához laboratóriumi környezetemben 3 és 7 másodperc között szükséges, a vezérlő szerver terhelésétől függően. Ez azt jelenti, hogy átlagosan a 101 objektum esetén a batch API hívás 10-szer gyorsabban teljesül. Nagyobb objektumszám esetén a különbség még lenyűgözőbb lesz.

Most nézzük meg, hogyan működhetünk a set-objects-batch. Ezzel az API hívással tömegében módosíthatunk bármely paramétert. Állítsuk be az előző példa első felének címének színét sienna-ra (a .124 hosztig, beleértve a címköröket is), a második felének pedig khaki színt rendelünk.

Az előző példában létrehozott objektumok színének megváltoztatása

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

Több objektum egyszerre történő törlése egy API híváson keresztül lehetséges delete-objects-batch. Most nézzük meg a kód példáját, amely törli az összes korábban létrehozott hosztot add-objects-batch.

Objektumok törlése a delete-objects-batch segítségével

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)

Minden funkció, amely a Check Point új szoftververzióiban megjelenik, azonnal rendelkezik API hívásokkal is. Az R80.40 verzióban olyan „funkciók” jelentek meg, mint a Visszaállítás a korábbi verzióra és az Okos Feladat, és ezekhez azonnal elkészítették a megfelelő API hívásokat. Továbbá, minden funkció, amikor átlépünk a Legacy konzolokból az Unified Policy módba, szintén API támogatást kap. Például a várt frissítés az R80.40 szoftververzióban az HTTPS Inspection politika áthelyezése a Legacy módból az Unified Policy módba volt, és ez a funkció is azonnal API hívásokat kapott. Íme egy példa kódra, amely a legfelső pozícióba helyezi az HTTPS Inspection politikát, amely kivonja az ellenőrzés alól a három kategóriát (Egészségügy, Pénzügy, Kormányzati szolgáltatások), amelyeket tiltanak szakmai nyelven az adott országok jogszabályai szerint.

Szabály hozzáadása az HTTPS Inspection politikához

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

data = {
  "layer" : "Default Layer",
  "position" : "top",
  "name" : "Jogi Követelmények",
  "action": "kivéve",
  "site-category": ["Egészségügy", "Kormány / Katonai", "Pénzügyi Szolgáltatások"]
}

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 szkriptek futtatása a Check Point irányító szerverén

Minden ugyanaz README.md információt tartalmaz arról, hogyan lehet a Python szkripteket közvetlenül az irányító szerverről futtatni. Ez kényelmes lehet, amikor nincs lehetőség csatlakozni az API szerverhez egy másik gépről. Készítettem egy hatperces videót, amelyben nézem a modul telepítését cpapi és a Python szkriptek futtatásának sajátosságait az irányító szerveren. Példaként egy olyan szkriptet indítok, amely automatizálja az új átjáró konfigurálását olyan feladatokhoz, mint a hálózat auditálása Security CheckUp. A problémák közül, amelyekkel szembe kellett néznem: a Python 2.7-es verzióban még nem jelent meg a input, ezért a felhasználó által megadott adatok feldolgozásához a következő funkciót használom: raw_input. Egyébként a kód ugyanaz, mint más gépekről történő futtatás esetén, csak kényelmesebb a login_as_rootfunkciót használni, hogy ne kelljen újra megadni a saját felhasználónevet, jelszót és az irányító szerver IP címét.

Videó lejátszása

Szkript a Security CheckUp gyors beállításához

a __jövő__ importálása 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:
       # ha a client.check_fingerprint() hamis:
       #     print("Nem sikerült megszerezni a szerver ujjlenyomatát - Ellenőrizze a kapcsolatot a szerverrel.")
       #     exit(1)
        login_res = client.login_as_root()

        if login_res.success is False:
            print("A bejelentkezés nem sikerült:n{}".format(login_res.error_message))
            exit(1)

        gw_name = raw_input("Adja meg a kapu nevét:")
        gw_ip = raw_input("Adja meg a kapu IP-címét:")
        if sys.stdin.isatty():
            sic = getpass.getpass("Adja meg a kapuhoz tartozó egyszeri jelszót (SIC): ")
        else:
            print("Figyelem! Az Ön jelszava megjelenik a képernyőn!")
            sic = raw_input("Adja meg a kapuhoz tartozó egyszeri jelszót (SIC): ")
        version = raw_input("Adja meg a kapu verzióját (például 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("A biztonságos kapcsolat a kapuval nem jött létre!")
            exit(1)
        elif add_gw.success:
            print("A kapu sikeresen hozzáadva.")
            gw_uid = add_gw.data['uid']
            gw_name = add_gw.data['name']
        else:
            print("A kapu hozzáadása nem sikerült - {}".format(add_gw.error_message))
            exit(1)

        change_policy = client.api_call("set-access-layer", {"name" : "Hálózat", "applications-and-url-filtering": "true", "content-awareness": "true"})
        if change_policy.success:
            print("A szabályzat sikeresen megváltozott")
        else:
            print("A szabályzat megváltoztatása nem sikerült - {}".format(change_policy.error_message))
        change_rule = client.api_call("set-access-rule", {"name" : "Takarítási szabály", "layer" : "Hálózat", "action": "Accept", "track": {"type": "Részletes napló", "accounting": "true"}})
        if change_rule.success:
            print("A takarítási szabály sikeresen megváltozott")
        else:
            print("A takarítási szabály megváltoztatása nem sikerült - {}".format(change_rule.error_message))

        # a változások közzététele
        publish_res = client.api_call("publish", {})
        if publish_res.success:
            print("A változtatások sikeresen közzétéve.")
        else:
                print("A változtatások közzététele nem sikerült - {}".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("A hozzáférési szabályzat telepítve lett")
        else:
                print("A hozzáférési szabályzat telepítése nem sikerült - {}".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("A fenyegetésmegelőzési szabályzat telepítve lett")
        else:
            print("A fenyegetésmegelőzési szabályzat telepítése nem sikerült - {}".format(install_tp_policy.error_message))
        
        # jelszavak és jelszavak hozzáadása a szótárhoz
        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" : "Jelszavak és jelszavak hozzáadása", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
                if add_password_dictionary.success:
                    print("A jelszó szótár sora {} sikeresen hozzáadva".format(line_num))
                else:
                    print("A szótár hozzáadása nem sikerült - {}".format(add_password_dictionary.error_message))

main()

Példa fájl a jelszó szótárral additional_pass.conf
{
"jelszók" : ["kártevő","rosszindulatú","fertőzött","Fertőzött"],
"kifejezések" : ["jelszó","Jelszó","Átjáró","átjáró","kód","kulcs","pwd","jelszó","Jelszó","Kulcs","kulcs","titkosítás","Titkosítás"]
}

Zárás

Ez a cikk csupán a munka alapvető lehetőségeit tárgyalja Python SDK és modulja cpapi(ahogy azt kitalálhattad, ezek lényegében szinonimák), és ha megvizsgálod ennek a modulnak a kódját, még több lehetőséget fedezhetsz fel a munkához. Elképzelhető, hogy kedved támadna kiegészíteni a saját osztályaiddal, funkcióiddal, metódusaiddal és változóiddal. Mindig megoszthatod a munkáidat, és megtekintheted más Check Point szkripteket a CodeHub közösségben CheckMates, amely összehozza a termékek fejlesztőit és a felhasználókat.

Kellemes kódolást, és köszönöm, hogy végigolvastad ezt!

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster