Simpligante la Check Point API kun la Python SDK

Simpligante la Check Point API kun la Python SDKLa plena potenco de interagado kun API-oj estas malkaŝita kiam uzata kune kun programkodo, kiam eblas dinamike generi API-petojn kaj ilojn por analizi API-respondojn. Tamen ĝi ankoraŭ restas nerimarkebla Python Programaro Disvolva Ilaro (ĉi-poste nomata Python SDK) por Check Point Management API, sed vane. Ĝi signife simpligas la vivon de programistoj kaj entuziasmuloj pri aŭtomatigo. Python gajnis grandegan popularecon lastatempe kaj mi decidis plenigi la mankon kaj revizii la ĉefajn funkciojn. Check Point API Python Development Kit. Ĉi tiu artikolo servas kiel bonega aldono al alia artikolo pri Habré Kontrolpunkto R80.10 API. Administrado per CLI, skriptoj kaj pli. Ni rigardos kiel skribi skriptojn uzante la Python SDK kaj pli detale rigardos la novan Administran API-funkcion en versio 1.6 (subtenata ekde R80.40). Por kompreni la artikolon, vi bezonos bazan scion pri labori kun API-oj kaj Python.

Check Point aktive disvolvas la API kaj nuntempe la jenaj estas publikigitaj:

La Python SDK nuntempe nur subtenas interagadon kun la Administrado-API kaj Gaia API. Ni rigardos la plej gravajn klasojn, metodojn kaj variablojn en ĉi tiu modulo.

Simpligante la Check Point API kun la Python SDK

Instalante la modulon

Modulo cpapi instalas rapide kaj facile de oficiala Check Point-deponejo sur github kun helpo de pip. Detalaj instalinstrukcioj estas haveblaj en LEGUMIN.md. Ĉi tiu modulo estas adaptita por labori kun Python-versioj 2.7 kaj 3.7. En ĉi tiu artikolo, ekzemploj estos donitaj uzante Python 3.7. Tamen, la Python SDK povas ruliĝi rekte de la Check Point Management Server (Smart Management), sed ili nur subtenas Python 2.7, do la lasta sekcio provizos kodon por versio 2.7. Tuj post instalo de la modulo, mi rekomendas rigardi la ekzemplojn en la dosierujoj ekzemploj_python2 и ekzemploj_python3.

Kiel ekuzi

Por ke ni povu labori kun la komponantoj de la cpapi-modulo, ni devas importi el la modulo. cpapi almenaŭ du bezonataj klasoj:

APICliento и APIClientArgs

from cpapi import APIClient, APIClientArgs

Класс APIClientArgs respondecas pri konekto-parametroj al la API-servilo, kaj la klaso APICliento respondecas pri interago kun la API.

Determinante konektajn parametrojn

Por difini diversajn parametrojn por konekti al la API, vi devas krei ekzemplon de la klaso APIClientArgs. Principe, ĝiaj parametroj estas antaŭdifinitaj kaj kiam oni rulas la skripton sur la kontrolservilo, ili ne bezonas esti specifitaj.

client_args = APIClientArgs()

Sed kiam vi funkcias sur triaparta gastiganto, vi devas specifi almenaŭ la IP-adreson aŭ gastigantan nomon de la API-servilo (ankaŭ konata kiel la administra servilo). En la malsupra ekzemplo, ni difinas la servilan konekton parametron kaj asignas al ĝi la IP-adreson de la administra servilo kiel ĉeno.

client_args = APIClientArgs(server='192.168.47.241')

Ni rigardu ĉiujn parametrojn kaj iliajn defaŭltajn valorojn, kiuj povas esti uzataj kiam vi konektas al la API-servilo:

Argumentoj de la __init__ metodo de la APIClientArgs klaso

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

Mi kredas, ke la argumentoj uzeblaj en okazoj de la klaso APIClientArgs estas intuiciaj por administrantoj de Check Point kaj ne postulas pliajn komentojn.

Konekti per APIClient kaj kunteksta administranto

Класс APICliento La plej oportuna maniero uzi ĝin estas per la kunteksta administranto. Ĉio, kio devas esti pasita al kazo de la APIClient-klaso, estas la konektoparametroj kiuj estis difinitaj en la antaŭa paŝo.

with APIClient(client_args) as client:

La kunteksta administranto ne aŭtomate faros ensalutan vokon al la API-servilo, sed ĝi faros elsalutvokon kiam ĝi eliros. Se ial elsaluti ne estas bezonata post finlaboro kun API-vokoj, vi devas komenci labori sen uzi la kuntekstan administradon:

client = APIClient(clieng_args)

Kontrolante la konekton

La plej facila maniero por kontroli ĉu la konekto renkontas la specifitajn parametrojn estas uzi la metodon kontroli_fingrospuro. Se la konfirmo de la hash-sumo sha1 por la fingrospuro de la servila API-atestilo malsukcesas (la metodo revenis falsa), tiam ĉi tio estas kutime kaŭzita de konektoproblemoj kaj ni povas ĉesigi la ekzekuton de la programo (aŭ doni al la uzanto la ŝancon korekti la konektajn datumojn):

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

Bonvolu noti, ke estonte la klaso APICliento kontrolos ĉiun API-vokon (metodoj api_call и api_query, ni parolos pri ili iom plu) sha1 fingrospura atestilo en la API-servilo. Sed se, kiam oni kontrolas la fingrospuron sha1 de la API-servila atestilo, eraro estas detektita (la atestilo estas nekonata aŭ estis ŝanĝita), la metodo kontroli_fingrospuro provizos la ŝancon aldoni/ŝanĝi informojn pri ĝi sur la loka maŝino aŭtomate. Ĉi tiu kontrolo povas esti tute malŝaltita (sed ĉi tio povas esti rekomendita nur se skriptoj estas rulitaj sur la API-servilo mem, dum konekto al 127.0.0.1), uzante la argumenton APIClientArgs - nesekura_aŭtomata_akcepto (vidu pli pri APIClientArgs pli frue en "Difini konektajn parametrojn").

client_args = APIClientArgs(unsafe_auto_accept=True)

Ensalutu al API-servilo

У APICliento ekzistas eĉ 3 metodoj por ensaluti en la API-servilo, kaj ĉiu el ili komprenas la signifon sid(session-id), kiu estas uzata aŭtomate en ĉiu posta API-voko en la kaplinio (la nomo en la kaplinio de ĉi tiu parametro estas X-chkp-sid), do ne necesas plu prilabori ĉi tiun parametron.

ensaluta metodo

Opcio uzanta ensaluton kaj pasvorton (en la ekzemplo, la uzantnomo admin kaj pasvorto 1q2w3e estas pasigitaj kiel poziciaj argumentoj):

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

Pliaj laŭvolaj parametroj ankaŭ haveblas en la ensaluta metodo; jen iliaj nomoj kaj defaŭltaj valoroj:

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

Ensalutu_kun_api_key-metodo

Opcio uzanta api-ŝlosilon (subtenata ekde administra versio R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" ĉi tio estas la API-ŝlosila valoro por unu el la uzantoj sur la administra servilo kun la API-ŝlosila rajtigometodo):

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

En metodo ensalutu_per_api_key la samaj laŭvolaj parametroj estas disponeblaj kiel en la metodo Ensaluti.

login_as_root metodo

Opcio por ensaluti al loka maŝino kun API-servilo:

     login = client.login_as_root()

Estas nur du laŭvolaj parametroj disponeblaj por ĉi tiu metodo:

domain=None, payload=None

Kaj finfine la API nomas sin

Ni havas du eblojn por fari API-vokojn per metodoj api_call и api_query. Ni eltrovu, kia estas la diferenco inter ili.

api_call

Ĉi tiu metodo estas aplikebla por iuj alvokoj. Ni devas pasi la lastan parton por la api-voko kaj utila ŝarĝo en la petokorpo se necese. Se utila ŝarĝo estas malplena, tiam ĝi tute ne povas esti transdonita:

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

Eligo por ĉi tiu peto sub la tranĉo:

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

Eligo por ĉi tiu peto sub la tranĉo:

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

Mi tuj rezervu, ke ĉi tiu metodo estas aplikebla nur por vokoj, kies eligo implikas ofseton. Tia inferenco okazas kiam ĝi enhavas aŭ povas enhavi grandan kvanton da informoj. Ekzemple, ĉi tio povus esti peto por listo de ĉiuj kreitaj gastigaj objektoj sur la administrada servilo. Por tiaj petoj, la API resendas liston de 50 objektoj defaŭlte (vi povas pliigi la limon al 500 objektoj en la respondo). Kaj por ne plurfoje tiri informojn ŝanĝante la ofsetan parametron en la API-peto, ekzistas api_query-metodo, kiu faras ĉi tiun laboron aŭtomate. Ekzemploj de vokoj kie ĉi tiu metodo estas bezonata: montri-sesioj, montri-gastigantoj, montri-retoj, montri-komoderoj, montri-grupoj, montri-adresintervaloj, montri-simple-enirejoj, montri-simple-grupoj, montri-aliro-roloj, montri-fidindaj-klientoj, spektaklo-pakaĵoj. Fakte, ni vidas pluralajn vortojn en la nomo de ĉi tiuj API-vokoj, do ĉi tiuj alvokoj estos pli facile manipuleblaj. api_query

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

Eligo por ĉi tiu peto sub la tranĉo:

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

Prilaborado de la rezultoj de API-vokoj

Post tio vi povas uzi la variablojn kaj metodojn de la klaso APIRresponde(kaj ene de la kunteksta administranto kaj ekstere). Ĉe la klaso APIRresponde 4 metodoj kaj 5 variabloj estas antaŭdifinitaj; ni pritraktos la plej gravajn pli detale.

Simpligante la Check Point API kun la Python SDK

sukceso

Komence, estus bona ideo certigi, ke la API-voko estis sukcesa kaj resendis rezulton. Estas metodo por ĉi tio sukceso:

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

Liveras True se la API-voko sukcesis (respondkodo - 200) kaj False se ne sukcesa (iu alia respondkodo). Estas oportune uzi tuj post API-voko por montri malsamajn informojn depende de la respondkodo.

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

statuskodo

Resendas la respondkodon post kiam API-voko estis farita.

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

Eblaj respondkodoj: 200,400,401,403,404,409,500,501.

aro_sukcesa_statuso

En ĉi tiu kazo, eble necesas ŝanĝi la valoron de la sukcesa statuso. Teknike, vi povas meti ion ajn tie, eĉ regulan ŝnuron. Sed reala ekzemplo estus restarigi ĉi tiun parametron al Falsa sub certaj akompanaj kondiĉoj. Malsupre, atentu la ekzemplon kiam estas taskoj kurantaj sur la administra servilo, sed ni konsideros ĉi tiun peton malsukcesa (ni agordos la sukcesan variablon al falsa, malgraŭ la fakto ke la API-voko estis sukcesa kaj resendis kodon 200).

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

respondo()

La respondmetodo permesas vidi la vortaron kun la respondkodo (status_code) kaj la respondkorpo (korpo).

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

datumoj

Permesas al vi vidi nur la korpon de la respondo (korpo) sen nenecesaj informoj.

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

erara_mesaĝo

Ĉi tiu informo haveblas nur kiam eraro okazis dum prilaborado de la API-peto (respondkodo ne 200). Ekzempla eligo

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

Utilaj ekzemploj

La jenaj estas ekzemploj, kiuj uzas la API-vokojn, kiuj estis aldonitaj en Administrado-API 1.6.

Unue, ni rigardu kiel funkcias alvokoj aldoni-gastiganto и aldon-adresa gamo. Ni diru, ke ni devas krei ĉiujn IP-adresojn de la subreto 192.168.0.0/24, kies lasta okteto estas 5, kiel objektoj de la gastiga tipo, kaj skribi ĉiujn aliajn IP-adresojn kiel objektojn de la adresintervalo. En ĉi tiu kazo, ekskludu la subretan adreson kaj elsendan adreson.

Do, malsupre estas skripto, kiu solvas ĉi tiun problemon kaj kreas 50 objektojn de la gastiganta tipo kaj 51 objektojn de la adresintervalo. Por solvi la problemon, 101 API-vokoj estas bezonataj (ne kalkulante la finan publikvokon). Ankaŭ, uzante la timeit-modulon, ni kalkulas la tempon necesan por ekzekuti la skripton ĝis la ŝanĝoj estas publikigitaj.

Skripto uzante add-host kaj add-adress-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')

En mia laboratorio-medio, ĉi tiu skripto daŭras inter 30 kaj 50 sekundoj por ekzekuti, depende de la ŝarĝo sur la administra servilo.

Nun ni vidu kiel solvi la saman problemon per API-voko aldoni-objektoj-batch, subteno por kiu estis aldonita en API-versio 1.6. Ĉi tiu alvoko permesas krei multajn objektojn samtempe en unu API-peto. Krome, ĉi tiuj povas esti objektoj de malsamaj tipoj (ekzemple, gastigantoj, subretoj kaj adresintervaloj). Tiel, nia tasko povas esti solvita kadre de unu API-voko.

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

Kaj ruli ĉi tiun skripton en mia laboratorio-medio daŭras de 3 ĝis 7 sekundoj, depende de la ŝarĝo de la administra servilo. Tio estas, averaĝe, sur 101 API-objektoj, battipa voko funkcias 10 fojojn pli rapide. Sur pli granda nombro da objektoj la diferenco estos eĉ pli impona.

Nun ni vidu kiel labori kun aro-objektoj-aro. Uzante ĉi tiun API-vokon, ni povas amase ŝanĝi ajnan parametron. Ni agordu la unuan duonon de la adresoj de la antaŭa ekzemplo (ĝis .124 gastigantoj, kaj ankaŭ intervaloj) al la kolor sienna, kaj asignu la koloron kaki al la dua duono de la adresoj.

Ŝanĝi la koloron de la objektoj kreitaj en la antaŭa ekzemplo

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

Vi povas forigi plurajn objektojn en unu API-voko uzante delete-objects-batch. Nun ni rigardu kodan ekzemplon, kiu forigas ĉiujn gastigantojn kreitajn antaŭe per aldoni-objektoj-batch.

Forigante objektojn uzante 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)

Ĉiuj funkcioj kiuj aperas en novaj eldonoj de Check Point-programaro tuj akiras API-vokojn. Tiel, en R80.40 tiaj "trajtoj" kiel Reverti al revizio kaj Smart Task aperis, kaj respondaj API-vokoj tuj estis preparitaj por ili. Plie, ĉiuj funkcioj kiam oni transiras de Heredaĵaj konzoloj al Unified Policy-reĝimo ankaŭ akiras API-subtenon. Ekzemple, la longe atendita ĝisdatigo en programara versio R80.40 estis la movo de la HTTPS-Inspekta politiko de Legacy-reĝimo al Unified Policy-reĝimo, kaj ĉi tiu funkcio tuj ricevis API-vokojn. Jen ekzemplo de kodo, kiu aldonas regulon al la supera pozicio de la HTTPS-politiko pri Inspektado, kiu ekskludas 3 kategoriojn de inspektado (Sano, Financo, Registaro-Servoj), kiuj estas malpermesitaj de inspektado laŭ la leĝo en kelkaj landoj.

Aldonu regulon al la HTTPS-Inspekta politiko

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

Kurante Python-skriptojn sur la administradservilo de Check Point

Ĉio estas la sama LEGUMIN.md enhavas informojn pri kiel ruli Python-skriptojn rekte de la kontrolservilo. Ĉi tio povas esti oportuna kiam vi ne povas konekti al la API-servilo de alia maŝino. Mi registris sesminutan videon, en kiu mi rigardas instali la modulon cpapi kaj funkcioj de rulado de Python-skriptoj sur la kontrolservilo. Ekzemple, skripto estas rulita, kiu aŭtomatigas la agordon de nova enirejo por tasko kiel retkontrolado. Sekureca Kontrolo. Inter la funkcioj, kiujn mi devis trakti: la funkcio ankoraŭ ne aperis en Python 2.7 enigo, do por prilabori la informojn, kiujn la uzanto enigas, funkcio estas uzata kruda_enigo. Alie, la kodo estas la sama kiel por lanĉo de aliaj maŝinoj, nur estas pli oportune uzi la funkcion ensalutu_kiel_radiko, por ne specifi viajn proprajn uzantnomon, pasvorton kaj IP-adreson de la administra servilo denove.

Skripto por rapida agordo de Sekureca Kontrolo

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

Ekzempla dosiero kun pasvorta vortaro addition_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

konkludo

Ĉi tiu artikolo ekzamenas nur la bazajn eblecojn de laboro Python SDK kaj modulo cpapi(kiel vi eble divenis, ĉi tiuj fakte estas sinonimoj), kaj studante la kodon en ĉi tiu modulo vi malkovros eĉ pli da ŝancoj por labori kun ĝi. Eblas, ke vi volas kompletigi ĝin per viaj propraj klasoj, funkcioj, metodoj kaj variabloj. Vi ĉiam povas dividi vian laboron kaj vidi aliajn skriptojn por Check Point en la sekcio CodeHub en la komunumo CheckMates, kiu kunigas kaj produktoprogramistojn kaj uzantojn.

Feliĉan kodigon kaj dankon pro legado ĝis la fino!

fonto: www.habr.com

Aldoni komenton