Facilităm lucrul cu Check Point API folosind Python SDK

Facilităm lucrul cu Check Point API folosind Python SDKToată puterea interacțiunii cu API-ul se descoperă prin utilizarea împreună cu codul de programare, când apar oportunități de a genera dinamic cereri API și instrumente pentru analiza răspunsurilor API. Cu toate acestea, rămâne, deocamdată, puțin observată Kitul de Dezvoltare Software Python (mai departe – Python SDK) pentru API-ul de Management Check Point, și pe bună dreptate. Acesta simplifică semnificativ viața dezvoltatorilor și a pasionaților de automatizare. Python a câștigat popularitate enormă în ultima vreme și am decis să umplu golul și să fac o prezentare generală a principalelor sale posibilități Kitul de Dezvoltare API Python Check Point. Acest articol este un supliment excelent la un alt articol de pe Habr Check Point R80.10 API. Gestionare prin CLI, scripturi și nu numai. Vom analiza cum să scriem scripturi folosind Python SDK și ne vom concentra mai în detaliu asupra noului funcțional din API-ul de Management în versiunea 1.6 (susținută începând cu R80.40). Pentru a înțelege articolul, sunt necesare cunoștințe de bază despre cum funcționează API-urile și Python.

Check Point dezvoltă activ API-urile, iar până în prezent au apărut:

Python SDK în prezent suportă interacțiunea doar cu Management API și Gaia API. Vom analiza cele mai importante clase, metode și variabile din acest modul.

Facilităm lucrul cu Check Point API folosind Python SDK

Instalarea modulului

Modulul cpapi se face rapid și simplu din repozitoriul oficial Check Point de pe github folosind pip. Instrucțiunile detaliate de instalare sunt disponibile în README.md. Acest modul este adaptat pentru a funcționa cu versiunile Python 2.7 și 3.7. În acest articol, exemplele vor fi prezentate folosind Python 3.7. Cu toate acestea, Python SDK poate fi rulat direct de pe serverul de management Check Point (Smart Management), dar acolo se suportă doar versiunea Python 2.7, așa că în ultima secțiune va fi prezentat codul pentru versiunea 2.7. Imediat după instalarea modulului, recomand să verificați exemplele din directoarele examples_python2 și examples_python3.

Începerea utilizării

Pentru a avea posibilitatea de a lucra cu componentele modulului cpapi, este necesar să importăm din modul cpapi cel puțin două clase necesare:

APIClient și APIClientArgs

from cpapi import APIClient, APIClientArgs

Clasă APIClientArgs se ocupă cu parametrii de conectare la serverul API, iar clasa APIClient se ocupă cu interacțiunea cu API-ul.

Definim parametrii de conectare

Pentru a defini diferiți parametri de conectare la API, trebuie să creăm o instanță a clasei APIClientArgs. Practic, parametrii săi sunt predeterminați și la rularea scriptului pe serverul de management, nu este nevoie să îi specificăm.

client_args = APIClientArgs()

Dar la rularea pe un gazduitor terț, trebuie să specificăm cel puțin adresa IP sau numele gazduitorului serverului API (la fel cu serverul de management). În exemplul de mai jos, definim parametrul de conectare server și îi atribuim ca șir de caractere adresa IP a serverului de management.

client_args = APIClientArgs(server='192.168.47.241')

Să ne uităm la toți parametrii și valorile lor implicite care pot fi utilizate la conectarea la serverul API:

Argumentele metodei __init__ a clasei APIClientArgs

class APIClientArgs:
    """
    Această clasă oferă argumente pentru configurarea APIClient.
    Toate argumentele sunt configurate cu valorile lor implicite.
    """

    # portul este setat la None din start, dar este înlocuit cu 443 dacă nu este specificat
    # valorile posibile pentru context - web_api (implicit) sau 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-ul serverului de management
        self.fingerprint = fingerprint
        # id-ul sesiunii.
        self.sid = sid
        # numele serverului de management sau adresa IP
        self.server = server
        # nivelul de debug
        self.http_debug_level = http_debug_level
        # un array cu toate apelurile API (pentru scopuri de debug)
        self.api_calls = api_calls if api_calls else []
        # numele fișierului de debug. Dacă este lăsat gol, datele de debug nu vor fi salvate pe disk.
        self.debug_file = debug_file
        # adresa serverului proxy HTTP (fără "http://")
        self.proxy_host = proxy_host
        # portul serverului proxy HTTP
        self.proxy_port = proxy_port
        # versiunea API a serverului de management
        self.api_version = api_version
        # Indică faptul că clientul nu ar trebui să verifice certificatul serverului
        self.unsafe = unsafe
        # Indică faptul că clientul ar trebui să accepte și să salveze automat certificatul serverului
        self.unsafe_auto_accept = unsafe_auto_accept
        # Contextul utilizării clientului - implicit web_api
        self.context = context

Consider că argumentele care pot fi utilizate în instanțele clasei APIClientArgs sunt intuitive pentru toți administratorii Check Point și nu necesită comentarii suplimentare.

Ne conectăm prin APIClient și managerul de context

Clasă APIClient cel mai convenabil este să folosiți prin managerul de context. Tot ce trebuie să transmitem instanței clasei APIClient sunt parametrii de conectare definiți în pasul precedent.

with APIClient(client_args) as client:

Managerul de context nu va efectua automat apelul de login la serverul API, dar va efectua apelul de logout la ieșirea din acesta. Dacă din diverse motive apelul de logout la finalizarea lucrului cu apelurile API nu este necesar, trebuie să începeți lucrul fără utilizarea managerului de context:

client = APIClient(clieng_args)

Verificarea conexiunii

Cea mai simplă modalitate de a verifica dacă conexiunea se face conform parametrelor specificate este prin metoda check_fingerprint. Dacă verificarea hash-ului sha1 pentru fingerprint-ul certificatului serverului API nu a trecut (metoda a returnat False), de obicei aceasta este cauzată de probleme cu conexiunea și putem opri executarea programului (sau oferi utilizatorului posibilitatea de a corecta datele de conectare):

    if client.check_fingerprint() is False:
        print("Nu s-a putut obține fingerprint-ul serverului - Verificați conectivitatea cu serverul.")
        exit(1)

Rețineți că, în continuare, clasa APIClient va verifica la fiecare apel API (metodele api_call și api_query, despre care vom discuta mai târziu) fingerprint-ul sha1 al certificatului pe serverul API. Dacă în timpul verificării fingerprint-ului sha1 al certificatului serverului API este identificată o eroare (certificatul este necunoscut sau a fost modificat), metoda check_fingerprint va oferi posibilitatea de a adăuga/modifica informațiile despre acesta pe mașina locală în mod automat. Această verificare poate fi dezactivată complet (dar se recomandă doar în cazul în care se rulează scripturi pe serverul API în sine, la conectarea la 127.0.0.1), folosind argumentul APIClientArgs — unsafe_auto_accept (vezi mai multe detalii despre APIClientArgs mai devreme în „Definirea parametrilor de conectare”).

client_args = APIClientArgs(unsafe_auto_accept=True)

Login la serverul API

În APIClient există trei metode de autentificare la serverul API, iar fiecare dintre ele reține valoarea sid(session-id), care este utilizată automat în fiecare apel API ulterior în antet (numele din antet pentru acest parametru — X-chkp-sid), astfel încât nu trebuie să procesați suplimentar acest parametru.

Metoda login

O variantă folosind un nume de utilizator și o parolă (în exemplu, numele utilizatorului admin și parola 1q2w3e sunt transmise ca argumente poziționale):

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

În metoda login sunt disponibile și parametri opționali suplimentari, iată numele lor și valorile implicite:

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

Metoda login_with_api_key

O variantă folosind cheia API (suportată începând cu versiunea de management R80.40/Management API v1.6, „3TsbPJ8ZKjaJGvFyoFqHFA==“ aceasta este valoarea cheii API pentru unul dintre utilizatorii de pe serverul de management cu metoda de autorizare API key):

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

În metoda login_with_api_key sunt disponibile aceleași parametri opționali ca și în metoda login.

Metoda login_as_root

Opțiunea de login pentru mașina locală cu serverul API:

     login = client.login_as_root()

Pentru această metodă, sunt disponibile doar două parametrii opționali:

domain=None, payload=None

Și în final, apelurile API

Avem două opțiuni de a face apeluri API prin metode api_call și api_query. Să vedem care este diferența dintre ele.

api_call

Această metodă se aplică pentru orice apeluri. Trebuie să transmitem ultima parte pentru apelul api și payload-ul în corpul cererii, dacă este necesar. Dacă payload-ul este gol, nu trebuie transmis deloc:

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

Rezultatul pentru această cerere mai jos:

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

Rezultatul pentru această cerere mai jos:

În [25]: show_host                                                              
Out[25]: 
APIResponse({
    "data": {
        "color": "negru",
        "comments": "",
        "domain": {
            "domain-type": "domeniu",
            "name": "Utilizator 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": "deblocat",
            "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": "negru",
            "comments": "",
            "domain": {
                "domain-type": "domeniu",
                "name": "Utilizator 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": "deblocat",
                "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

Aș dori să menționez de la bun început că această metodă este aplicabilă doar pentru apeluri al căror rezultat presupune un offset. Acest rezultat apare atunci când conține sau este posibil să conțină o cantitate mare de informații. De exemplu, aceasta poate fi o solicitare pentru lista tuturor obiectelor de tip gazdă create pe serverul de gestionare. Pentru astfel de solicitări, API-ul returnează implicit o listă de 50 de obiecte (limită care poate fi crescută la 500 de obiecte în răspuns). Și pentru a nu solicita informațiile de mai multe ori, modificând parametrul offset în solicitarea API, există metoda api_query care efectuează această muncă automat. Exemple de apeluri unde se necesită această 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. De fapt, în numele acestor apeluri API vedem cuvinte la plural, astfel încât aceste apeluri vor fi mai ușor de procesat prin api_query

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

Rezultatul pentru această cerere mai jos:

În [21]: show_hosts                                                             
Out[21]: 
APIResponse({
    "data": [
        {
            "domain": {
                "domain-type": "domain",
                "name": "Utilizator SMC",
                "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": "Utilizator SMC",
                "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": "Utilizator SMC",
                        "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": "Utilizator SMC",
                        "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
})

Prelucrarea rezultatelor apelurilor API

După aceasta, se pot utiliza variabilele și metodele clasei APIResponse(atât în interiorul managerului de context, cât și în afară). Clasa APIResponse definește 4 metode și 5 variabile, la cele mai importante ne vom opri mai în detaliu.

Facilităm lucrul cu Check Point API folosind Python SDK

success

Pentru început, ar fi bine să ne asigurăm că apelul API a fost efectuat cu succes și a returnat rezultatul. Pentru aceasta există metoda success:

În [49]: api_versions.success                                                   
Out[49]: True

Returnează True dacă apelul API a avut succes (Codul răspunsului — 200) și False dacă nu a avut succes (orice alt cod de răspuns). Este convenabil să fie folosit imediat după apelul API, pentru a afișa informații diferite în funcție de codul răspunsului.

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

statuscode

Returnează codul răspunsului după executarea apelului API.

În [62]: api_versions.status_code                                               
Out[62]: 400

Coduri de răspuns posibile: 200,400,401,403,404,409,500,501.

set_success_status

Este poate necesita modificarea valorii statusului success. Tehnic, acolo se poate plasa orice, chiar și un simplu string. Un exemplu real ar putea fi resetarea acestei variabile la False sub anumite condiții. În continuare, observați exemplul când există sarcini executate pe serverul de management, dar vom considera această solicitare ca fiind eșuată (vom seta variabila success la False, chiar dacă apelul API a fost de succes și a returnat codul 200).

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

response()

Metoda response permite vizualizarea unui dicționar cu codul de răspuns (status_code) și cu corpul răspunsului (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

Permite vizualizarea doar a corpului răspunsului (body) fără informații suplimentare.

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

Această informație este disponibilă doar atunci când a apărut o eroare la procesarea cererii API (codu răspunsului nu 200). Exemplu de ieșire

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

Exemple utile

Mai jos sunt enumerate exemple în care sunt utilizate apelurile API care au fost adăugate în versiunea Management API 1.6.

Pentru început, să analizăm funcționarea apelurilor add-host și add-address-range. Să presupunem că trebuie să creăm ca obiecte de tip host toate adresele IP din subrețeaua 192.168.0.0/24, ultimul octet al cărora este 5, iar toate celelalte adrese IP să fie scrise ca obiecte de tip interval de adrese. De asemenea, să excludem adresa de subrețea și adresa de difuzare.

Așadar, mai jos este prezentat un script în care se rezolvă această sarcină și se creează 50 de obiecte de tip host și 51 de obiecte de tip interval de adrese. Soluționarea sarcinii necesită 101 apeluri API (fără a conta apelul final de publicare). De asemenea, cu ajutorul modulului timeit, măsurăm timpul de execuție al scriptului până la momentul publicării modificărilor.

Script cu utilizarea add-host și 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 mediu meu de laborator, execuția acestui script durează între 30 și 50 de secunde, în funcție de încărcarea serverului de management.

Acum să vedem cum putem rezolva aceeași problemă folosind apeluri API add-objects-batch, suport adăugat în versiunea API 1.6. Acest apel permite crearea a numeroase obiecte cu o singură cerere API. De asemenea, acestea pot fi obiecte de tipuri diferite (de exemplu, gazde, subrețele și intervale de adrese). Astfel, sarcina noastră poate fi rezolvată în cadrul unei singure ape API.

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

Și execuția acestui script în mediu meu de laborator durează între 3 și 7 secunde, în funcție de încărcarea serverului de management. Așadar, în medie, pentru 101 obiecte, apelul API de tip batch rulează de 10 ori mai repede. La un număr mai mare de obiecte, diferența va fi și mai impresionantă.

Acum să vedem cum lucrăm cu set-objects-batch. Cu acest apel API putem modifica în masă orice parametru. Să configurăm prima jumătate din adresele din exemplul anterior (până la .124 gazdă, inclusiv intervalele) la culoarea sienna, iar celelalte jumătate le vom asigna culoarea khaki.

Modificarea culorii obiectelor create în exemplul anterior

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

Se pot elimina multiple obiecte într-o singură apelare API folosind delete-objects-batch. Acum să ne uităm la un exemplu de cod care elimină toate gazdele create anterior prin add-objects-batch.

Eliminarea obiectelor folosind 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)

Toate funcțiile care apar în noile versiuni ale software-ului Check Point obțin imediat și apeluri API. Astfel, în R80.40 au apărut „funcții” precum Revert to revision și Smart Task, iar pentru acestea s-au pregătit imediat apeluri API corespunzătoare. Mai mult decât atât, întreaga funcționalitate în tranziția din consolele Legacy în modul Unified Policy este, de asemenea, îmbogățită cu suport API. De exemplu, o actualizare mult așteptată în versiunea R80.40 a fost mutarea politicii HTTPS Inspection din modul Legacy în modul Unified Policy, iar această funcționalitate a primit imediat apeluri API. Iată un exemplu de cod care adaugă în partea de sus a politicii HTTPS Inspection o regulă care exclude din inspecție 3 categorii (Sănătate, Finanțe, Servicii Guvernamentale), care nu pot fi inspectate conform legislației din anumite țări.

Adăugați o regulă în politica HTTPS Inspection

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

data = {
  "layer" : "Default Layer",
  "position" : "top",
  "name" : "Cerințe Legale",
  "action": "bypass",
  "site-category": ["Sănătate", "Guvern / Militar", "Servicii 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")

Rularea scripturilor Python pe serverul de gestionare Check Point

Tot în același README.md conține informații despre cum să rulați scripturi Python direct de pe serverul de gestionare. Acest lucru poate fi convenabil atunci când nu aveți posibilitatea de a vă conecta la serverul API de pe o altă mașină. Am înregistrat un videoclip de șase minute în care discut despre instalarea modulului cpapi și particularitățile rulării scripturilor Python pe serverul de gestionare. Ca exemplu, se rulează un script care automatizează configurarea unei noi porți pentru o sarcină precum auditul rețelei Security CheckUp. Printre particularitățile întâmpinate: în versiunea Python 2.7 nu a apărut încă funcția input, prin urmare, pentru a gestiona informațiile introduse de utilizator, se folosește funcția raw_input. În rest, codul este la fel ca și pentru rularea de pe alte mașini, doar că este mai convenabil să utilizați funcția login_as_root, pentru a nu fi nevoie să specificați din nou propriul nume de utilizator, parolă și IP-ul serverului de gestionare.

Redați video

Script pentru configurarea rapidă a Security CheckUp

from __future__ import print_function
import getpass
import sys, os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from cpapi import APIClient, APIClientArgs

def main():
    with APIClient() as client:
       # if client.check_fingerprint() is False:
       #     print("Nu s-a putut obține amprenta serverului - Verificați conectivitatea cu serverul.")
       #     exit(1)
        login_res = client.login_as_root()

        if login_res.success is False:
            print("Autentificare eșuată:n{}".format(login_res.error_message))
            exit(1)

        gw_name = raw_input("Introduceți numele gateway-ului:")
        gw_ip = raw_input("Introduceți adresa IP a gateway-ului:")
        if sys.stdin.isatty():
            sic = getpass.getpass("Introduceți o parolă unică pentru gateway (SIC): ")
        else:
            print("Atenție! Parola dvs. va fi afișată pe ecran!")
            sic = raw_input("Introduceți o parolă unică pentru gateway (SIC): ")
        version = raw_input("Introduceți versiunea gateway-ului (de exemplu, 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("Conexiunea securizată cu gateway-ul nu a fost stabilită!")
            exit(1)
        elif add_gw.success:
            print("Gateway-ul a fost adăugat cu succes.")
            gw_uid = add_gw.data['uid']
            gw_name = add_gw.data['name']
        else:
            print("Eșec la adăugarea gateway-ului - {}".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("Politica a fost schimbată cu succes")
        else:
            print("Eșec la schimbarea politicii - {}".format(change_policy.error_message))
        change_rule = client.api_call("set-access-rule", {"name" : "Regula de curățare", "layer" : "Network", "action": "Accept", "track": {"type": "Detailed Log", "accounting": "true"}})
        if change_rule.success:
            print("Regula de curățare a fost schimbată cu succes")
        else:
            print("Eșec la schimbarea regulii de curățare - {}".format(change_rule.error_message))

        # publică rezultatul
        publish_res = client.api_call("publish", {})
        if publish_res.success:
            print("Modificările au fost publicate cu succes.")
        else:
                print("Eșec la publicarea modificărilor - {}".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("Politica de acces a fost instalată")
        else:
                print("Eșec la instalarea politicii de acces - {}".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("Politica de prevenire a amenințărilor a fost instalată")
        else:
            print("Eșec la instalarea politicii de prevenire a amenințărilor - {}".format(install_tp_policy.error_message))
        
        # adaugă parolele și frazele de acces în dicționar
        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" : "Adăugați parole și fraze de acces", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
                if add_password_dictionary.success:
                    print("Linia {} din dicționarul de parole a fost adăugată cu succes".format(line_num))
                else:
                    print("Eșec la adăugarea dicționarului - {}".format(add_password_dictionary.error_message))

main()

Exemplu de fișier cu un dicționar de parole additional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infectat"],
"phrases" : ["parola","Parola","Pass","pass","codigo","cheie","pwd","пароль","Пароль","Ключ","clavă","шифр","Şifru"]
}

Concluzie

Această articole abordează doar principalele funcționalități de lucru Python SDK și modulul cpapi(după cum te-ai putut gândi, acestea sunt de fapt sinonime), iar studiind codul din acest modul vei descoperi și mai multe posibilități de a lucra cu el. Nu este exclus să simți nevoia să-l completezi cu propriile tale clase, funcții, metode și variabile. Poți să împărtășești întotdeauna realizările tale și să vizualizezi alte scripturi pentru Check Point în secțiunea CodeHub din comunitate CheckMates, care reunește atât dezvoltatori de produse, cât și utilizatori.

Bucură-te de codare și mulțumim că ai citit până la final!

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster