Thjeshtojmë punën me Check Point API me ndihmën e Python SDK

ThjeshtojmĂ« punĂ«n me Check Point API me ndihmĂ«n e Python SDKE gjithĂ« fuqia e ndĂ«rveprimit me API zbullohet kur pĂ«rdoret nĂ« bashkĂ«punim me kodin programues, kur krijohen mundĂ«si pĂ«r tĂ« formuar dinamikisht kĂ«rkesat API dhe mjete pĂ«r analizimin e pĂ«rgjigjeve API. MegjithatĂ«, ende mbetet pak e dukshme Python Software Development Kit (mĂ« pas — Python SDK) pĂ«r Check Point Management API, pĂ«r tĂ« cilin Ă«shtĂ« mĂ«kat. Ai e thjeshton ndjeshĂ«m jetĂ«n e zhvilluesve dhe entuziastĂ«ve tĂ« automatizimit. Python ka fituar popullaritet tĂ« madh kohĂ«t e fundit dhe vendosa tĂ« heq njĂ« boshllĂ«k dhe tĂ« bĂ«j njĂ« pĂ«rmbledhje tĂ« mundĂ«sive kryesore Check Point API Python Development Kit. Ky artikull shĂ«rben si njĂ« shtesĂ« e shkĂ«lqyer pĂ«r njĂ« artikull tjetĂ«r nĂ« HabrĂ« Check Point R80.10 API. Menaxhimi pĂ«rmes CLI, skripteve dhe jo vetĂ«m. Ne do tĂ« shqyrtojmĂ« se si tĂ« shkruajmĂ« skriptet duke pĂ«rdorur Python SDK dhe do tĂ« ndalemi mĂ« nĂ« detaje nĂ« funksionalitetin e ri tĂ« Management API nĂ« versionin 1.6 (tĂ« mbĂ«shtetur qĂ« nga R80.40). PĂ«r tĂ« kuptuar artikullin, nevojiten njohuri bazike mbi punĂ«n me API dhe Python.

Check Point aktivisht zhvillon API dhe deri më tani janë nxjerrë në pah:

Python SDK deri më tani mbështet vetëm ndërveprimin me Management API dhe Gaia API. Ne do të shqyrtojmë klasat, metodat dhe variablat më të rëndësishme në këtë modul.

Thjeshtojmë punën me Check Point API me ndihmën e Python SDK

Instalimi i modulit

Moduli cpapi instalohet shpejt dhe lehtësisht nga repozytori zyrtar i Check Point në github nëpërmjet pip. Udhëzime të detajizuara për instalimin gjenden në README.md. Ky modul është i optimizuar për të punuar me versionet Python 2.7 dhe 3.7. Në këtë artikull, shembujt do të jepen duke përdorur Python 3.7. Megjithatë, Python SDK mund të ekzekutohet drejtpërdrejt nga serveri i menaxhimit të Check Point (Smart Management), por atje mbështetet vetëm versioni Python 2.7, prandaj në seksionin e fundit do të jepet kodi për versionin 2.7. Menjëherë pas instalimit të modulit, rekomandoj të shikoni shembujt në direktorët examples_python2 dhe examples_python3.

Fillimi i punës

Për që të kemi mundësinë të punojmë me komponentët e modulit cpapi, është e nevojshme të importojmë nga moduli cpapi të paktën dy klasa të nevojshme:

APIClient dhe APIClientArgs

nga cpapi importo APIClient, APIClientArgs

Klasa APIClientArgs përcakton parametrat e lidhjes me serverin API, ndërsa klasa APIClient përcakton ndërveprimin me API-në.

Definojmë parametrat e lidhjes

Për të përcaktuar parametrat e ndryshëm të lidhjes me API-në, duhet të krijoni një instancë të klasës APIClientArgs. Në parim, parametrat e saj janë të paracaktuar dhe gjatë ekzekutimit të skriptit në serverin e menaxhimit, nuk është e nevojshme t'i especificoni.

client_args = APIClientArgs()

Por gjatë ekzekutimit në një host të jashtëm, duhet të specifikoni të paktën adresën IP ose emrin e hostit të serverit API (i njohur gjithashtu si serveri i menaxhimit). Në shembullin më poshtë përcaktojmë parametrin e lidhjes server dhe i japim atij si një string adresën IP të serverit të menaxhimit.

client_args = APIClientArgs(server='192.168.47.241')

Le të shikojmë të gjitha parametrat dhe vlerat e tyre të paracaktuara që mund të përdoren gjatë lidhjes me serverin API:

Argumentet e metodës __init__ të klasës APIClientArgs

klasa APIClientArgs:
    """
    Kjo klasë ofron argumente për konfigurimin e APIClient.
    Të gjitha argumentet janë të konfiguruara me vlerat e tyre të paracaktuar.
    """

    # porti është vendosur në None si parazgjedhje, por do të zëvendësohet me 443 nëse nuk especificohet
    # vlerat e mundshme të kontekstit - web_api (parazgjedhja) ose 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
        # fingerprint i serverit të menaxhimit
        self.fingerprint = fingerprint
        # session-id.
        self.sid = sid
        # emri ose adresa IP e serverit të menaxhimit
        self.server = server
        # niveli i debug
        self.http_debug_level = http_debug_level
        # një array me të gjitha thirrjet API (për qëllime debug)
        self.api_calls = api_calls if api_calls else []
        # emri i skedarit të debug. Nëse lëshohet bosh, të dhënat e debug nuk do të ruhen në disk.
        self.debug_file = debug_file
        # adresa e serverit proxy HTTP (pa "http://")
        self.proxy_host = proxy_host
        # porti i serverit proxy HTTP
        self.proxy_port = proxy_port
        # versioni API i serverit të menaxhimit
        self.api_version = api_version
        # Tregon se klienti nuk duhet të kontrollojë certifikatën e serverit
        self.unsafe = unsafe
        # Tregon se klienti duhet automatikisht ta pranojë dhe ta ruajë certifikatën e serverit
        self.unsafe_auto_accept = unsafe_auto_accept
        # Konteksti i përdorimit të klientit - parazgjedhja është web_api
        self.context = context

Mendoj se argumentet që mund të përdoren në instancat e klasës APIClientArgs janë intuitivisht të qarta për administratorët e Check Point dhe nuk kanë nevojë për komente shtesë.

Lidhja përmes APIClient dhe menaxherit të kontekstit

Klasa APIClient është më e lehtë të përdoret përmes menaxherit të kontekstit. Gjithçka që duhet të kaloni në instancën e klasës APIClient janë parametrat e lidhjes që u përmendën në hapat e mëparshëm.

me APIClient(client_args) si klient:

Menaxheri i kontekstit nuk do të kryejë automatikisht thirrjen login në serverin API, megjithatë ai do të kryejë thirrjen logout kur dalim prej tij. Nëse për ndonjë shkak logout pas përfundimit të punës me thirrjet API nuk është i nevojshëm, duhet të filloni punën pa përdorur menaxherin e kontekstit:

client = APIClient(clieng_args)

Kontrolli i lidhjes

TĂ« kontrolloni nĂ«se lidhja kalon sipas parametrave tĂ« caktuar Ă«shtĂ« mĂ« e lehtĂ« me metodĂ«n check_fingerprint. NĂ«se kontrolli i hash-it sha1 pĂ«r certifikatin fingerprint tĂ« serverit API nuk ka kaluar (metoda ktheu False), zakonisht kjo shkaktohet nga probleme me lidhjen dhe mund tĂ« ndalojmĂ« ekzekutimin e programit (ose t’i japim pĂ«rdoruesit mundĂ«sinĂ« tĂ« korrigjojĂ« tĂ« dhĂ«nat pĂ«r lidhjen):

    if client.check_fingerprint() is False:
        print("Nuk arritëm të merrnim fingerprint-in e serverit - Kontrolloni lidhjen me serverin.")
        exit(1)

Kujdes, se klasa APIClient do tĂ« kontrollojĂ« me çdo thirrje API (metodat api_call dhe api_query, pĂ«r to do flasim pak mĂ« vonĂ«) sha1 fingerprint-in e certifikatĂ«s nĂ« serverin API. NĂ«se gjatĂ« kontrollit sha1 fingerprint-it tĂ« certifikatĂ«s nĂ« serverin API identifikohet njĂ« gabim (certifikata Ă«shtĂ« e panjohur ose Ă«shtĂ« ndryshuar), metoda check_fingerprint do tĂ« ofrojĂ« mundĂ«sinĂ« pĂ«r tĂ« shtuar/ndryshuar informacionin rreth tij nĂ« makinĂ«n lokale nĂ« mĂ«nyrĂ« automatike. Ky kontroll mund tĂ« çaktivizohet krejtĂ«sisht (por njĂ« gjĂ« e tillĂ« rekomandohet vetĂ«m nĂ« rastin e ekzekutimit tĂ« skenarĂ«ve nĂ« serverin API vetĂ«, duke u lidhur me 127.0.0.1), duke pĂ«rdorur argumentin APIClientArgs — unsafe_auto_accept (shih mĂ« shumĂ« rreth APIClientArgs mĂ« herĂ«t nĂ« ‘PĂ«rcaktimi i parametrave tĂ« lidhjes’).

client_args = APIClientArgs(unsafe_auto_accept=True)

Login në serverin API

Me APIClient ka tre metoda tĂ« ndryshme login-i nĂ« serverin API, dhe secila prej tyre mban vlerĂ«n sid(session-id), e cila pĂ«rdoret automatikisht nĂ« çdo thirrje tĂ« mĂ«passhme API nĂ« kokĂ« (emri nĂ« kokĂ« pĂ«r kĂ«tĂ« parametĂ«r — X-chkp-sid), kĂ«shtu qĂ« nuk ka nevojĂ« ta trajtoni pĂ«rsĂ«ri kĂ«tĂ« parametr.

Metoda login

Varianti me përdorimin e emrit dhe fjalëkalimit (në shembull emri i përdoruesit admin dhe fjalëkalimi 1q2w3e janë dërguar si argumente pozitive):

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

Në metodën login gjithashtu janë të disponueshme parametra opcionalë shtesë, po i përmend emrat dhe vlerat e tyre gjithashtu siç janë për parazgjedhje:

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

Metoda login_with_api_key

Varianti me pĂ«rdorimin e çelĂ«sit API (mbĂ«shtetet qĂ« prej versionit tĂ« menaxhimit R80.40/Management API v1.6, ‘3TsbPJ8ZKjaJGvFyoFqHFA==’ ky Ă«shtĂ« vlera e çelĂ«sit API pĂ«r njĂ« nga pĂ«rdoruesit nĂ« serverin e menaxhimit me metodĂ«n e autorizimit API key:

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

Në metodën login_with_api_key janë të disponibles po aq opsione si dhe në metodën Hyrje.

Metoda login_as_root

Një variant login për makinën lokale me serverin API:

     login = client.login_as_root()

Për këtë metodë janë në dispozicion vetëm dy parametra opsionalë:

domain=None, payload=None

Dhe në fund vetë thirrjet API

Kemi dy mundësi për të bërë thirrje API përmes metodave api_call dhe api_query. Le të shqyrtojmë se çfarë ndodhi mes tyre.

api_call

Kjo metodë është e aplikueshme për çdo thirrje. Na nevojitet të kalojmë pjesën e fundit për thirrjen api dhe payload në trupin e kërkesës kur është e nevojshme. Nëse payload është bosh, atëherë nuk mund të kalojë fare:

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

Dalja për këtë kërkesë është nën kat:

In [23]: api_versions                                                           
Out[23]: 
APIResponse({
    "data": {
        "current-version": "1.6",
        "supported-versions": [
            "1",
            "1.1",
            "1.2",
            "1.3",
            "1.4",
            "1.5",
            "1.6"
        ]
    },
    "res_obj": {
        "data": {
            "current-version": "1.6",
            "supported-versions": [
                "1",
                "1.1",
                "1.2",
                "1.3",
                "1.4",
                "1.5",
                "1.6"
            ]
        },
        "status_code": 200
    },
    "status_code": 200,
    "success": true
})
show_host = client.api_call('show-host', {'name' : 'h_8.8.8.8'})

Dalja për këtë kërkesë është nën kat:

NĂ« [25]: show_host
Out[25]:
APIResponse({
    "data": {
        "color": "e zezë",
        "comments": "",
        "domain": {
            "domain-type": "domain",
            "name": "Përdorues SMC",
            "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": "e zezë",
            "comments": "",
            "domain": {
                "domain-type": "domain",
                "name": "Përdorues SMC",
                "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

Së pari, dua të theksoj se kjo metodë është e aplikueshme vetëm për thirrjet ku rezultati parashikon offset (shkallëzim). Ky rezultat ndodh kur ka ose mund të ketë një numër të madh informacioni. Për shembull, kjo mund të jetë një kërkesë për listën e të gjitha objekteve të krijuara të tipit host në serverin e menaxhimit. Për këto kërkesa, API kthen një listë prej 50 objekteve si standard (mund të rritet kufiri në 500 objekte në përgjigje). Dhe për të mos kërkuar informacionin disa herë, duke ndryshuar parametrin offset në kërkesën API, ekziston metoda api_query, e cila kryen këtë punë automatikisht. Shembuj thirrjesh ku nevojitet kjo metodë: 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. Në fakt, në emrat e këtyre thirrjeve API ne shohim fjalë në shumës, kështu që këto thirrje do të jenë më të lehta për t'u trajtuar përmes api_query

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

Dalja për këtë kërkesë është nën kat:

In [21]: show_hosts                                                             
Out[21]: 
APIResponse({
    "data": [
        {
            "domain": {
                "domain-type": "domain",
                "name": "SMC User",
                "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
            },
            "ipv4-address": "192.168.47.1",
            "name": "h_192.168.47.1",
            "type": "host",
            "uid": "5d7d7086-d70b-4995-971a-0583b15a2bfc"
        },
        {
            "domain": {
                "domain-type": "domain",
                "name": "SMC User",
                "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
            },
            "ipv4-address": "8.8.8.8",
            "name": "h_8.8.8.8",
            "type": "host",
            "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
        }
    ],
    "res_obj": {
        "data": {
            "from": 1,
            "objects": [
                {
                    "domain": {
                        "domain-type": "domain",
                        "name": "SMC User",
                        "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
                    },
                    "ipv4-address": "192.168.47.1",
                    "name": "h_192.168.47.1",
                    "type": "host",
                    "uid": "5d7d7086-d70b-4995-971a-0583b15a2bfc"
                },
                {
                    "domain": {
                        "domain-type": "domain",
                        "name": "SMC User",
                        "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
                    },
                    "ipv4-address": "8.8.8.8",
                    "name": "h_8.8.8.8",
                    "type": "host",
                    "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
                }
            ],
            "to": 2,
            "total": 2
        },
        "status_code": 200
    },
    "status_code": 200,
    "success": true
})

Trajtimi i rezultateve të thirrjeve API

Pasi kjo, është e mundur të përdoren variablat dhe metodat e klasës APIResponse(si brenda menaxherit të kontekstit ashtu edhe jashtë tij). Klasës i janë paracaktuar 4 metoda dhe 5 variabla, mbi më të rëndësishmit do të ndalojmë më hollësisht. APIResponse success

Thjeshtojmë punën me Check Point API me ndihmën e Python SDK

Për të filluar, do të ishte mirë të sigurohemi se thirrja API ka kaluar me sukses dhe ka kthyer rezultat. Për këtë ka metodën

In [49]: api_versions.success Out[49]: True Për të filluar, do të ishte mirë të sigurohemi se thirrja API ka kaluar me sukses dhe ka kthyer rezultat. Për këtë ka metodën:

Kthen True nĂ«se thirrja API ka kaluar me sukses (Kodi i pĂ«rgjigjes — 200) dhe False nĂ«se jo (cdo kod tjetĂ«r pĂ«rgjigjeje). ËshtĂ« e dobishme ta pĂ«rdorĂ«sh menjĂ«herĂ« pas thirrjes API, pĂ«r tĂ« treguar informacion tĂ« ndryshĂ«m nĂ« varĂ«si tĂ« kodit tĂ« pĂ«rgjigjes.

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

statuscode 

Kthen kodin e përgjigjes pas ekzekutimit të thirrjes API.

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

Kodi të mundshëm të përgjigjeve:

set_success_status 200,400,401,403,404,409,500,501.

set_success_status

Megjithatë, mund të jetë e nevojshme të ndryshoni vlerën e statusit success. Teknikisht, aty mund të vendosni gjithçka, madje edhe një varg të thjeshtë. Por një shembull real mund të jetë rimbushja e këtij parametri në False në kushte të caktuara. Më poshtë, kushtojini vëmendje një shembulli, kur ka detyra që kryhen në serverin e menaxhimit, por do të ndajmë këtë kërkesë si të dështuar (do ta vendosim variablin success në False, megjithëse thirrja e API-së ishte e suksesshme dhe ktheu kodin 200).

for task in task_result.data["tasks"]:
    if task["status"] == "dështuar" or task["status"] == "arritur pjesërisht":
        task_result.set_success_status(False)
        break

response()

Metoda response lejon që të shihni një fjalor me kodin e përgjigjes (status_code) dhe me trupin e përgjigjes (body).

In [94]: api_versions.response()                                                
Out[94]: 
{'status_code': 200,
 'data': {'current-version': '1.6',
  'supported-versions': ['1', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6']}}

data

Lejon të shihni vetëm trupin e përgjigjes (body) pa informacion të tepërt.

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

Kjo informacion është e disponueshme, vetëm kur gjatë përpunimit të kërkesës API ka ndodhur një gabim (Kodi i përgjigjes jo 200). Shembulli i daljes

In [107]: api_versions.error_message                                            
Out[107]: 'kod: generic_err_invalid_parameter_nmessage: Parametri [1] nuk njihet n'

Shembuj të dobishëm

Më poshtë janë listuar shembujt, në të cilat janë përdorur thirrjet API, të cilat janë shtuar në versionin Management API 1.6.

Për të filluar, le të shqyrtojmë funksionimin e thirrjeve add-host dhe add-address-range. Le të supozojmë se na nevojitet të krijojmë si objekte të tipit host të gjitha adresat IP të subnet-it 192.168.0.0/24, okteti i fundit i të cilave është 5, ndërsa të gjitha adresat IP të tjera të regjistrohen si objekte të tipit interval adresash. Në të njëjtën kohë, adresën e subnet-it dhe adresën e broadcast-it duhet t'i përjashtojmë.

Pra, më poshtë është treguar një skenar në të cilin zgjidhet kjo detyrë dhe krijohen 50 objekte të tipit host dhe 51 objekt i tipit interval adresash. Zgjidhja e problemit kërkon 101 thirrje API (pa përfshirë thirrjen përfundimtare të publikimit). Gjithashtu, me ndihmën e modulit timeit llogarisim kohën për ekzekutimin e skenarit deri në momentin e publikimit të ndryshimeve.

Skenari me përdorimin e add-host dhe add-address-range

import timeit
from cpapi import APIClient, APIClientArgs

start = timeit.default_timer()

first_ip = 1
last_ip = 4

client_args = APIClientArgs(server="192.168.47.240")

with APIClient(client_args) as client: 
     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
     for ip in range(5,255,5):
         add_host = client.api_call("add-host", {"name" : f"h_192.168.0.{ip}", "ip-address": f'192.168.0.{ip}'})
     while last_ip < 255:
         add_range = client.api_call("add-address-range", {"name": f"r_192.168.0.{first_ip}-{last_ip}", "ip-address-first": f"192.168.0.{first_ip}", "ip-address-last": f"192.168.0.{last_ip}"})
         first_ip+=5
         last_ip+=5
     stop = timeit.default_timer() 
     publish = client.api_call("publish")
     
print(f'Time to execute batch request: {stop - start} seconds')

Në mjedisin tim laboratorik, ekzekutimi i këtij skripti zgjat nga 30 deri në 50 sekonda në varësi të ngarkesës së serverit të menaxhimit.

Tani le të shohim si ta zgjidhim të njëjtën detyrë me thirrjen API add-objects-batch, mbështetje e së cilës është shtuar në versionin e API 1.6. Kjo thirrje lejon që me një kërkesë API të krijohet një sërë objektesh menjëherë. Dhe këto mund të jenë objekte të llojeve të ndryshme (për shembull, hoste, nënrrjeta dhe diapazone adresash). Kështu, detyra jonë mund të zgjidhet brenda një thirrjeje API.

Skripti me përdorimin e 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')

Dhe për ekzekutimin e këtij skripti në mjedisin tim laboratorik zgjat nga 3 deri në 7 sekonda në varësi të ngarkesës së serverit të menaxhimit. Kështu, mesatarisht, në 101 objekte thirrja API e tipit batch funksionon 10 herë më shpejt. Për një numër më të madh objektesh, ndryshimi do të jetë edhe më impresionues.

Tani le të shohim si të punojmë me set-objects-batch. Me këtë thirrje API ne mund të ndryshojmë masivisht çdo parametër. Le të caktojmë përgjysmë të parë të adresave nga shembulli i kaluar (deri në .124 të hostit, por gjithashtu edhe për diapazone) ngjyrën sienna, ndërsa përgjysmë të dytë të adresave do t'i caktojmë ngjyrën khaki.

Ndryshimi i ngjyrës së objekteve të krijuara në shembullin e mëparshëm

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ë fshihni shumë objekte në një thirrje API, mund të përdorni delete-objects-batch. Tani le të shohim një shembull kodi, i cili fshin të gjithë hostet, të krijuar më parë përmes add-objects-batch.

Fshirja e objekteve duke përdorur 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)

Të gjitha funksionet që shfaqen në versionet e reja të softuerit Check Point, menjëherë fitojnë gjithashtu thirrje API. Kështu, në R80.40 u prezantuan disa "veçori" si Revert to revision dhe Smart Task, dhe për to u përgatitën menjëherë thirrje përkatëse API. Për më tepër, të gjitha funksionalitetet kur kalojmë nga konsolat Legacy në modalitetin Unified Policy gjithashtu fitojnë mbështetje për API. Për shembull, një përmirësim shumë të pritur në versionin R80.40 ishte kalimi i politikës së HTTPS Inspection nga moda Legacy në modalitetin Unified Policy, dhe ky funksionalitet menjëherë mori thirrje API. Këtu është një shembull kodi që shton në pozita më të larta politika e HTTPS Inspection një rregull që përjashton nga inspektimi 3 kategori (Shëndeti, Financa, Shërbimet Qeveritare), të cilat ndalohen sipas legjislacionit në disa vende.

Shto një rregull në politikën e HTTPS Inspection

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

data = {
  "layer": "Default Layer",
  "position": "top",
  "name": "Kërkesat Ligjore",
  "action": "bypass",
  "site-category": ["Shëndetësia", "Qeveria / Ushtarak", "Shërbimet Financiare"]
}

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

Ekzekutimi i skripteve Python në serverin e menaxhimit Check Point

E njëjta gjë README.md përmban informacion se si të ekzekutoni skripte në Python direkt nga serveri i menaxhimit. Kjo mund të jetë e përshtatshme kur nuk keni mundësi të lidheni me serverin API nga një makinë tjetër. Unë kam regjistruar një video gjashtë minutëshe në të cilën shqyrtoj instalimin e modulit cpapi dhe veçoritë e ekzekutimit të skripteve Python në serverin e menaxhimit. Si shembull, ekzekutohet një skript që automatizon konfigurimin e një gateway të ri për një detyrë si auditi i rrjetit Kontrolli i Sigurisë. Nga veçoritë me të cilat u përballa: në versionin Python 2.7, nuk pati ende funksionin input, prandaj për përpunimin e informacionit që përdoruesi fut, përdoret funksioni raw_input. Të gjitha të tjerat, kodi është i njëjtë si për ekzekutimin nga makineta të tjera, por është më e lehtë të përdorë funksionin login_as_root, për të mos bërë të nevojshme përsëritjen e emrit të përdoruesit, fjalëkalimit dhe adresës IP të serverit të menaxhimit.

Luaj videon

Skripti për konfigurim të shpejtë të Kontrollit të Sigurisë

nga __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:
       # nëse client.check_fingerprint() është False:
       #     print("Nuk arriti të merrni gjurmën e serverit - Kontrolloni lidhjen me serverin.")
       #     exit(1)
        login_res = client.login_as_root()

        if login_res.success është False:
            print("Dëshira për të hyrë dështoi:n{}".format(login_res.error_message))
            exit(1)

        gw_name = raw_input("Shkruani emrin e gateway-it:")
        gw_ip = raw_input("Shkruani adresën IP të gateway-it:")
        if sys.stdin.isatty():
            sic = getpass.getpass("Shkruani fjalëkalimin një herë për gateway-in (SIC): ")
        else:
            print("Kujdes! Fjalëkalimi juaj do të shfaqet në ekran!")
            sic = raw_input("Shkruani fjalëkalimin një herë për gateway-in (SIC): ")
        version = raw_input("Shkruani versionin e gateway-it (si 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("Lidhja e sigurt me gateway-in nuk është krijuar!")
            exit(1)
        elif add_gw.success:
            print("Gateway-i u shtua me sukses.")
            gw_uid = add_gw.data['uid']
            gw_name = add_gw.data['name']
        else:
            print("Dështoi të shtoni gateway-in - {}".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("Politika është ndryshuar me sukses")
        else:
            print("Dështoi të ndryshoni politikën- {}".format(change_policy.error_message))
        change_rule = client.api_call("set-access-rule", {"name" : "Rregulli i pastrimit", "layer" : "Network", "action": "Accept", "track": {"type": "Detailed Log", "accounting": "true"}})
        if change_rule.success:
            print("Rregulli i pastrimit është ndryshuar me sukses")
        else:
            print("Dështoi të ndryshoni rregullin e pastrimit- {}".format(change_rule.error_message))

        # publikoni rezultatin
        publish_res = client.api_call("publish", {})
        if publish_res.success:
            print("Ndryshimet u publikuan me sukses.")
        else:
                print("Dështoi të publikoni ndërrimet - {}".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("Politika e aksesit është instaluar")
        else:
                print("Dështoi të instaloni politikën e aksesit - {}".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("Politika e parandaluar e kërcënimeve është instaluar")
        else:
            print("Dështoi të instaloni politikën e parandaluar të kërcënimeve - {}".format(install_tp_policy.error_message))
        
        # shtoni fjalëkalimet dhe frazat në fjalorin
        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" : "Shto fjalëkalimet dhe frazat", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
                if add_password_dictionary.success:
                    print("Linja e fjalëkalimit në fjalor u shtua me sukses {}".format(line_num))
                else:
                    print("Dështoi të shtoni fjalorin - {}".format(add_password_dictionary.error_message))

main()

Shembulli i skedarit me fjalorin e fjalëkalimeve additional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","password","Password","Key","key","cipher","Cipher"]
}

Përfundim

Ky artikull shqyrton vetëm mundësitë kryesore të punës Python SDK dhe moduli cpapi(siç mund të mendoni, këto janë faktikisht sinonime), dhe duke studiuar kodin në këtë modul do të hapni më shumë mundësi për ta përdorur atë. Nuk përjashtohet që të keni dëshirë ta plotësoni atë me klasat, funksionet, metodat dhe variablat tuaja. Gjithmonë mund të ndani arritjet tuaja dhe të shikoni skriptet e tjera për Check Point në seksionin CodeHub në komunitet CheckMates, i cili bashkon zhvilluesit e produkteve dhe përdoruesit.

Gëzuar kodimin dhe faleminderit që e lexuat deri në fund!

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster