A Check Point API egyszerűsítése a Python SDK segítségével

A Check Point API egyszerűsítése a Python SDK segítségévelAz API-kkal való interakció teljes ereje akkor derül ki, ha programkóddal együtt használják, amikor lehetővé válik az API-kérések dinamikus generálása és az API-válaszok elemzésére szolgáló eszközök. Azonban továbbra is észrevehetetlen marad Python szoftverfejlesztő készlet (a továbbiakban Python SDK) számára Check Point Management API, de hiába. Jelentősen leegyszerűsíti a fejlesztők és az automatizálás iránt érdeklődők életét. A Python az utóbbi időben óriási népszerűségre tett szert, és úgy döntöttem, hogy pótlom a hiányt, és áttekintem a főbb funkciókat. Check Point API Python Development Kit. Ez a cikk kiváló kiegészítésként szolgál egy másik, Habréval kapcsolatos cikkhez Check Point R80.10 API. Kezelés CLI-n, szkripteken és egyebeken keresztül. Megvizsgáljuk, hogyan lehet szkripteket írni a Python SDK használatával, és közelebbről megvizsgáljuk az új Management API funkciót az 1.6-os verzióban (R80.40-től kezdve támogatott). A cikk megértéséhez alapvető ismeretekre lesz szüksége az API-kkal és a Pythonnal való munkavégzésről.

A Check Point aktívan fejleszti az API-t, és jelenleg a következők jelentek meg:

A Python SDK jelenleg csak a Management API-val és az interakciót támogatja Gaia API. Ebben a modulban megvizsgáljuk a legfontosabb osztályokat, metódusokat és változókat.

A Check Point API egyszerűsítése a Python SDK segítségével

A modul telepítése

Modul cpapi gyorsan és egyszerűen telepíthető innen hivatalos Check Point adattár a githubon keresztül gyümölcsmag. A részletes szerelési utasítások itt találhatók README.md. Ez a modul a Python 2.7-es és 3.7-es verzióival való együttműködésre készült. Ebben a cikkben példákat adunk a Python 3.7 használatával. A Python SDK azonban közvetlenül is futtatható a Check Point Management Server (Smart Management) kiszolgálóról, de csak a Python 2.7-et támogatják, így az utolsó rész a 2.7-es verzió kódját tartalmazza. Közvetlenül a modul telepítése után javaslom, hogy nézze meg a példákat a könyvtárakban examples_python2 и examples_python3.

Az első lépések

Ahhoz, hogy a cpapi modul komponenseivel dolgozhassunk, importálni kell a modulból cpapi legalább két kötelező osztály:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Osztály APIClientArgs felelős az API szerverhez és az osztályhoz való kapcsolódási paraméterekért APIClient felelős az API-val való interakcióért.

Csatlakozási paraméterek meghatározása

Az API-hoz való csatlakozáshoz szükséges különféle paraméterek meghatározásához létre kell hoznia az osztály példányát APIClientArgs. A paraméterei elvileg előre definiáltak, és amikor a parancsfájlt a vezérlőszerveren futtatjuk, ezeket nem kell megadni.

client_args = APIClientArgs()

Ha azonban harmadik féltől származó gazdagépen fut, meg kell adnia legalább az API-kiszolgáló (más néven felügyeleti kiszolgáló) IP-címét vagy gazdagépnevét. Az alábbi példában definiáljuk a szerverkapcsolati paramétert, és karakterláncként hozzárendeljük a felügyeleti kiszolgáló 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ékét, amelyek az API-kiszolgálóhoz való csatlakozáskor használhatók:

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

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

Úgy gondolom, hogy az APIClientArgs osztály példányaiban használható argumentumok intuitívak a Check Point rendszergazdák számára, és nem igényelnek további megjegyzéseket.

Csatlakozás APIClienten és környezetkezelőn keresztül

Osztály APIClient Használatának legkényelmesebb módja a környezetkezelő. Csak az előző lépésben meghatározott kapcsolati paramétereket kell átadni az APIClient osztály egy példányának.

with APIClient(client_args) as client:

A környezetkezelő nem indít automatikusan bejelentkezési hívást az API-kiszolgálónak, de kijelentkezéskor egy kijelentkezési hívást indít. Ha valamilyen oknál fogva nincs szükség kijelentkezésre az API-hívásokkal végzett munka befejezése után, akkor a környezetkezelő használata nélkül kell elkezdenie a munkát:

client = APIClient(clieng_args)

A kapcsolat ellenőrzése

A módszerrel a legegyszerűbben ellenőrizheti, hogy a kapcsolat megfelel-e a megadott paramétereknek check_ujjlenyomat. Ha a szerver API-tanúsítvány ujjlenyomatának sha1 hash összegének ellenőrzése sikertelen (a metódus visszaadott Hamis), akkor ezt általában csatlakozási problémák okozzák, és leállíthatjuk a program végrehajtását (vagy lehetőséget adunk a felhasználónak a csatlakozási adatok javítására):

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

Felhívjuk figyelmét, hogy a jövőben az osztály APIClient minden API-hívást ellenőriz (metódusok api_call и api_query, kicsit tovább fogunk róluk beszélni) sha1 ujjlenyomat-tanúsítvány az API szerveren. De ha az API szerver tanúsítvány sha1 ujjlenyomatának ellenőrzésekor hibát észlel (a tanúsítvány ismeretlen vagy megváltozott), a módszer check_ujjlenyomat lehetőséget biztosít az információk automatikus hozzáadására/módosítására a helyi gépen. Ez az ellenőrzés teljesen letiltható (de ez csak akkor javasolt, ha a szkriptek magán az API-kiszolgálón futnak, amikor 127.0.0.1-hez csatlakozik), az APIClientArgs argumentum használatával - unsafe_auto_accept (További információ az APIClientArgs-ról korábban a „Kapcsolatparaméterek meghatározása” részben).

client_args = APIClientArgs(unsafe_auto_accept=True)

Jelentkezzen be az API szerverre

У APIClient 3 módszer létezik az API szerverre való bejelentkezéshez, és mindegyik megérti a jelentését sid(session-id), amely automatikusan használatos minden következő API-hívásnál a fejlécben (a paraméter fejlécében lévő név X-chkp-sid), így nincs szükség a paraméter további feldolgozására.

bejelentkezési mód

Lehetőség bejelentkezés és jelszó használatával (a példában az admin felhasználónév és a 1q2w3e jelszó pozíciós argumentumként kerül átadásra):

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

További opcionális paraméterek is elérhetők a bejelentkezési módban, ezek nevei és alapértelmezett értékei:

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

Módszer: login_with_api_key

Lehetőség API-kulcs használatával (az R80.40/Management API v1.6 kezelési verziótól kezdve támogatott, "3TsbPJ8ZKjaJGvFyoFqHFA==" ez az API-kulcs értéke a felügyeleti kiszolgáló egyik felhasználójának API-kulcs engedélyezési módszerrel):

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

A módszerben login_with_api_key ugyanazok az opcionális paraméterek állnak rendelkezésre, mint a módszerben Belépés.

login_as_root metódus

Lehetőség bejelentkezni egy helyi gépre API-kiszolgálóval:

     login = client.login_as_root()

Ehhez a módszerhez csak két választható paraméter áll rendelkezésre:

domain=None, payload=None

És végül az API hívja magát

Két lehetőségünk van API-hívások végrehajtására metódusokon keresztül api_call и api_query. Nézzük meg, mi a különbség köztük.

api_call

Ez a módszer minden hívásra alkalmazható. Szükség esetén át kell adnunk az api hívás és a hasznos terhelés utolsó részét a kérés törzsében. Ha a rakomány üres, akkor egyáltalán nem vihető át:

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

Kimenet ehhez a kéréshez a vágás alatt:

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

Kimenet ehhez a kéréshez a vágás alatt:

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

Azonnal le kell szögeznem, hogy ez a módszer csak olyan hívásokra alkalmazható, amelyek kimenete eltolást tartalmaz. Ilyen következtetésre akkor kerül sor, ha nagy mennyiségű információt tartalmaz vagy tartalmazhat. Ez lehet például egy kérés a felügyeleti kiszolgálón létrehozott összes gazdagép objektum listájára. Az ilyen kérések esetén az API alapértelmezés szerint 50 objektumot tartalmazó listát ad vissza (a válaszban a korlátot 500 objektumra növelheti). És annak érdekében, hogy ne húzza le többször az információt, megváltoztatva az eltolási paramétert az API-kérésben, van egy api_query metódus, amely ezt automatikusan elvégzi. Példák azokra a hívásokra, ahol szükség van erre a módszerre: show-sessions, show-hosts, show-networks, show-wildcards, show-groups, show-dress-ranges, show-simple-gateways, show-simple-clusters, show-access-rolles, show-trusted-kliens, show-csomagok. Valójában többes számú szavakat látunk ezen API-hívások nevében, így ezek a hívások könnyebben kezelhetők api_query

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

Kimenet ehhez a kéréshez a vágás alatt:

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

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

Ezt követően használhatja az osztály változóit és metódusait APIResponse(a környezetkezelőn belül és azon kívül is). Az osztályban APIResponse 4 módszer és 5 változó van előre definiálva, a legfontosabbakon még részletesebben kitérünk.

A Check Point API egyszerűsítése a Python SDK segítségével

siker

Kezdetben jó ötlet lenne megbizonyosodni arról, hogy az API-hívás sikeres volt, és eredményt adott-e. Erre van egy módszer siker:

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

Igazat ad vissza, ha az API hívás sikeres volt (válaszkód - 200), és False értéket, ha nem volt sikeres (bármilyen más válaszkód). Kényelmes közvetlenül egy API-hívás után használni, hogy a válaszkódtól függően különböző információkat jelenítsen meg.

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

állapotkód

API-hívás után adja vissza a válaszkódot.

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

Ebben az esetben szükség lehet a sikeres állapot értékének módosítására. Technikailag bármit beletehetsz, még egy rendes karakterláncot is. De valós példa erre a paraméter visszaállítása False értékre bizonyos kísérő feltételek mellett. Az alábbiakban figyeljen a példára, amikor a felügyeleti kiszolgálón futnak feladatok, de ezt a kérést sikertelennek fogjuk tekinteni (a sikerváltozót a következőre állítjuk Hamis, annak ellenére, hogy az API-hívás sikeres volt, és a 200-as kódot adta vissza).

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

válasz()

A válaszmódszer lehetővé teszi a szótár megtekintését a válaszkóddal (status_code) és a válasz törzsével (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']}}

dátum

Lehetővé teszi, hogy csak a válasz törzsét (test) lássa, szükségtelen 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']}

hiba üzenet

Ez az információ csak akkor érhető el, ha hiba történt az API-kérés feldolgozása során (válaszkód nincs 200). Példa kimenet

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

Hasznos példák

A következő példák a Management API 1.6-ban hozzáadott API-hívásokat használják.

Először is nézzük meg, hogyan működnek a hívások add-host и add-címtartomány. Tegyük fel, hogy a 192.168.0.0/24 alhálózat összes IP-címét, amelynek utolsó oktettje 5, létre kell hoznunk a gazdagép típusú objektumként, és az összes többi IP-címet a címtartomány típusú objektumként kell megírnunk. Ebben az esetben hagyja ki az alhálózati címet és a szórási címet.

Tehát az alábbiakban egy szkriptet találunk, amely megoldja ezt a problémát, és 50 gazdagép típusú és 51 címtartomány típusú objektumot hoz létre. A probléma megoldásához 101 API-hívás szükséges (a végső közzétételi hívást nem számítva). Ezenkívül a timeit modul segítségével kiszámítjuk a szkript végrehajtásához szükséges időt a módosítások közzétételéig.

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

Az én laborkörnyezetemben ennek a szkriptnek a végrehajtása 30–50 másodpercet vesz igénybe, a felügyeleti kiszolgáló terhelésétől függően.

Most nézzük meg, hogyan lehet ugyanazt a problémát API-hívással megoldani add-objects-batch, amelynek támogatása az API 1.6-os verziójában került hozzáadásra. Ez a hívás lehetővé teszi egyszerre több objektum létrehozását egy API-kérésben. Ezenkívül ezek különböző típusú objektumok lehetnek (például gazdagépek, alhálózatok és címtartományok). Így a feladatunk egy API hívás keretein belül megoldható.

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

Ennek a szkriptnek a futtatása a laborkörnyezetemben 3-7 másodpercet vesz igénybe, a felügyeleti kiszolgáló terhelésétől függően. Ez azt jelenti, hogy átlagosan 101 API objektumon egy kötegelt típusú hívás 10-szer gyorsabban fut. Nagyobb számú objektum esetén a különbség még lenyűgözőbb lesz.

Most pedig lássuk, hogyan kell vele dolgozni set-objects-batch. Ezzel az API-hívással bármilyen paramétert tömegesen módosíthatunk. Állítsuk be az előző példa címeinek első felét (legfeljebb .124 gazdagépig és tartományokig) a sienna színre, a címek második feléhez pedig rendeljük a khaki színt.

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

Egy API-hívásban több objektumot is törölhet a használatával delete-objects-batch. Most nézzünk meg egy kódpéldát, amely törli az összes korábban a keresztül létrehozott gazdagépet add-objects-batch.

Objektumok törlése a delete-objects-batch használatával

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)

A Check Point szoftver új kiadásaiban megjelenő összes funkció azonnal API-hívásokat kap. Így az R80.40-ben megjelentek az olyan „szolgáltatások”, mint a Revert to revision és a Smart Task, amelyekhez azonnal elkészültek a megfelelő API-hívások. Ezen túlmenően a régi konzolokról az egyesített házirend módba való áttéréskor minden funkció API-támogatást is kap. Például az R80.40-es szoftververzió régóta várt frissítése a HTTPS-ellenőrzési házirend áthelyezése volt a Legacy módból az Egységes házirend módba, és ez a funkció azonnal API-hívásokat kapott. Íme egy példa arra a kódra, amely egy olyan szabályt ad a HTTPS-ellenőrzési szabályzat legfelső pozíciójához, amely kizár 3 kategóriát az ellenőrzésből (egészségügy, pénzügy, kormányzati szolgáltatások), amelyek ellenőrzése számos országban a törvények értelmében tilos.

Adjon hozzá egy szabályt a HTTPS-ellenőrzési szabályzathoz

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-szkriptek futtatása a Check Point felügyeleti kiszolgálón

Minden ugyanaz README.md információkat tartalmaz a Python-szkriptek közvetlenül a vezérlőkiszolgálóról történő futtatásáról. Ez akkor lehet kényelmes, ha nem tud egy másik gépről csatlakozni az API-kiszolgálóhoz. Rögzítettem egy hatperces videót, amelyben a modul telepítését nézem cpapi és Python-szkriptek futtatásának jellemzői a vezérlőkiszolgálón. Például egy szkript fut, amely automatizálja egy új átjáró konfigurálását egy olyan feladathoz, mint például a hálózati auditálás. Biztonsági ellenőrzés. A funkciók közül, amelyekkel meg kellett küzdenem: a funkció még nem jelent meg a Python 2.7-ben bemenet, tehát a felhasználó által beírt információk feldolgozásához egy függvényt használnak nyers_bemenet. Egyébként a kód ugyanaz, mint a többi gépről való indításnál, csak kényelmesebb a funkció használata login_as_root, hogy ne adja meg újra saját felhasználónevét, jelszavát és a felügyeleti szerver IP-címét.

Szkript a Biztonsági ellenőrzés gyors beállításához

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

Példafájl egy jelszószótárral, további_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Következtetés

Ez a cikk csak az alapvető munkalehetőségeket vizsgálja Python SDK és modul cpapi(ahogyan azt sejteni lehetett, ezek valójában szinonimák), és a modul kódjának tanulmányozásával még több lehetőséget fedezhet fel a vele való munka során. Lehetséges, hogy ki szeretné egészíteni saját osztályaival, függvényeivel, metódusaival és változóival. A szakaszban bármikor megoszthatja munkáját, és megtekintheti a Check Point egyéb szkriptjeit CodeHub a közösségben CheckMates, amely a termékfejlesztőket és a felhasználókat egyaránt összefogja.

Jó kódolást és köszönöm, hogy a végéig elolvastad!

Forrás: will.com

Hozzászólás