Pojednostavljivanje Check Point API-ja s Python SDK-om

Pojednostavljivanje Check Point API-ja s Python SDK-omPuna snaga interakcije s API-jima otkriva se kada se koristi zajedno s programskim kodom, kada postane moguće dinamički generirati API zahtjeve i alate za analizu API odgovora. Međutim, i dalje ostaje neprimjetno Komplet za razvoj softvera Python (u daljnjem tekstu Python SDK) za Check Point Management API, ali uzalud. Značajno pojednostavljuje život programera i entuzijasta automatizacije. Python je u posljednje vrijeme stekao ogromnu popularnost i odlučio sam popuniti prazninu i pregledati glavne značajke. Check Point API Python Development Kit. Ovaj članak služi kao izvrstan dodatak drugom članku na Habréu Check Point R80.10 API. Upravljanje putem CLI-ja, skripti i više. Pogledat ćemo kako pisati skripte pomoću Python SDK-a i pobliže pogledati novu funkcionalnost API-ja za upravljanje u verziji 1.6 (podržano počevši od R80.40). Za razumijevanje članka trebat će vam osnovno znanje o radu s API-jima i Pythonom.

Check Point aktivno razvija API i trenutno je objavljeno sljedeće:

Python SDK trenutno podržava samo interakciju s API-jem za upravljanje i Gaia API. U ovom modulu ćemo pogledati najvažnije klase, metode i varijable.

Pojednostavljivanje Check Point API-ja s Python SDK-om

Instalacija modula

Modul cpapi instalira se brzo i jednostavno iz službeno spremište Check Pointa na githubu uz pomoć zvjezdica. Detaljne upute za instalaciju dostupne su u PROČITAJ ME.md. Ovaj modul je prilagođen za rad s Python verzijama 2.7 i 3.7. U ovom članku bit će dani primjeri koji koriste Python 3.7. Međutim, Python SDK može se pokrenuti izravno s Check Point Management Servera (Smart Management), ali oni podržavaju samo Python 2.7, tako da će posljednji odjeljak pružiti kod za verziju 2.7. Odmah nakon instaliranja modula, preporučujem da pogledate primjere u imenicima primjeri_python2 и primjeri_python3.

Početak

Da bismo mogli raditi s komponentama cpapi modula, moramo importirati iz modula cpapi najmanje dva obavezna razreda:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Klasa APIClientArgs odgovoran je za parametre povezivanja s API poslužiteljem i klasu APIClient odgovoran je za interakciju s API-jem.

Određivanje parametara veze

Za definiranje različitih parametara za povezivanje s API-jem potrebno je izraditi instancu klase APIClientArgs. U principu, njegovi parametri su unaprijed definirani i prilikom pokretanja skripte na kontrolnom poslužitelju ne moraju se navoditi.

client_args = APIClientArgs()

Ali kada se izvodi na hostu treće strane, trebate navesti barem IP adresu ili naziv hosta API poslužitelja (također poznatog kao poslužitelj za upravljanje). U donjem primjeru definiramo parametar veze s poslužiteljem i dodjeljujemo mu IP adresu poslužitelja za upravljanje kao niz.

client_args = APIClientArgs(server='192.168.47.241')

Pogledajmo sve parametre i njihove zadane vrijednosti koje se mogu koristiti prilikom povezivanja na API poslužitelj:

Argumenti metode __init__ klase APIClientArgs

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

Vjerujem da su argumenti koji se mogu koristiti u instancama klase APIClientArgs intuitivni administratorima Check Pointa i ne zahtijevaju dodatne komentare.

Povezivanje putem APIClient i upravitelja konteksta

Klasa APIClient Najprikladniji način za korištenje je putem upravitelja konteksta. Sve što je potrebno proslijediti instanci klase APIClient su parametri veze koji su definirani u prethodnom koraku.

with APIClient(client_args) as client:

Upravitelj konteksta neće automatski uputiti poziv za prijavu na API poslužitelj, ali će uputiti poziv za odjavu kada iz njega izađe. Ako iz nekog razloga nije potrebna odjava nakon završetka rada s API pozivima, morate početi raditi bez korištenja upravitelja konteksta:

client = APIClient(clieng_args)

Provjera veze

Najlakši način da provjerite zadovoljava li veza navedene parametre je pomoću metode provjera_otiska prsta. Ako provjera hash zbroja sha1 za otisak prsta API certifikata poslužitelja ne uspije (metoda vraćena Lažan), onda je to obično uzrokovano problemima s vezom i možemo zaustaviti izvođenje programa (ili dati korisniku priliku da ispravi podatke o vezi):

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

Napominjemo da će ubuduće klasa APIClient će provjeriti svaki API poziv (metode api_poziv и api_upit, o njima ćemo govoriti malo dalje) sha1 certifikat otiska prsta na API poslužitelju. Ali ako se prilikom provjere sha1 otiska prsta certifikata API poslužitelja otkrije pogreška (certifikat je nepoznat ili je promijenjen), metoda provjera_otiska prsta omogućit će automatsko dodavanje/promjenu informacija o njemu na lokalnom računalu. Ova se provjera može u potpunosti onemogućiti (ali to se može preporučiti samo ako se skripte pokreću na samom API poslužitelju, prilikom povezivanja na 127.0.0.1), koristeći argument APIClientArgs - nesigurno_automatsko_prihvaćanje (pogledajte više o APIClientArgs ranije u “Definiranje parametara veze”).

client_args = APIClientArgs(unsafe_auto_accept=True)

Prijavite se na API poslužitelj

У APIClient postoje čak 3 metode za prijavu na API poslužitelj, a svaka od njih razumije značenje sid(session-id), koji se automatski koristi u svakom sljedećem API pozivu u zaglavlju (ime u zaglavlju ovog parametra je X-chkp-sid), tako da nema potrebe za daljnjom obradom ovog parametra.

način prijave

Opcija koja koristi prijavu i lozinku (u primjeru se korisničko ime admin i lozinka 1q2w3e prosljeđuju kao pozicijski argumenti):

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

Dodatni opcijski parametri također su dostupni u metodi prijave; ovdje su njihovi nazivi i zadane vrijednosti:

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

Login_with_api_key metoda

Opcija koja koristi API ključ (podržano počevši od verzije upravljanja R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" ovo je vrijednost API ključa za jednog od korisnika na poslužitelju za upravljanje s metodom autorizacije API ključa):

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

U metodi prijava_sa_api_ključem dostupni su isti izborni parametri kao u metodi prijava.

login_as_root metoda

Mogućnost prijave na lokalno računalo s API poslužiteljem:

     login = client.login_as_root()

Za ovu metodu dostupna su samo dva izborna parametra:

domain=None, payload=None

I na kraju sami API pozivi

Imamo dvije opcije za upućivanje API poziva putem metoda api_poziv и api_upit. Hajde da shvatimo koja je razlika između njih.

api_poziv

Ova metoda je primjenjiva za sve pozive. Moramo proslijediti zadnji dio za api poziv i korisni sadržaj u tijelu zahtjeva ako je potrebno. Ako je korisni teret prazan, onda se uopće ne može prenijeti:

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

Izlaz za ovaj zahtjev ispod rezanja:

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

Izlaz za ovaj zahtjev ispod rezanja:

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_upit

Dopustite mi da odmah napomenem da je ova metoda primjenjiva samo za pozive čiji izlaz uključuje pomak. Do takvog zaključivanja dolazi kada sadrži ili može sadržavati veliku količinu informacija. Na primjer, to može biti zahtjev za popis svih kreiranih host objekata na poslužitelju za upravljanje. Za takve zahtjeve, API prema zadanim postavkama vraća popis od 50 objekata (možete povećati ograničenje na 500 objekata u odgovoru). A kako ne biste povlačili informacije nekoliko puta, mijenjajući parametar pomaka u API zahtjevu, postoji metoda api_query koja to radi automatski. Primjeri poziva gdje je potrebna ova metoda: 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-paketi. Zapravo, vidimo riječi u množini u nazivima ovih API poziva, tako da će te pozive biti lakše obraditi api_upit

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

Izlaz za ovaj zahtjev ispod rezanja:

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

Obrada rezultata API poziva

Nakon ovoga možete koristiti varijable i metode klase APIResponse(i unutar upravitelja konteksta i izvan njega). Na satu APIResponse Predefinirane su 4 metode i 5 varijabli, a detaljnije ćemo se zadržati na najvažnijima.

Pojednostavljivanje Check Point API-ja s Python SDK-om

uspjeh

Za početak, bilo bi dobro provjeriti je li API poziv bio uspješan i vratio rezultat. Za to postoji metoda uspjeh:

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

Vraća True ako je API poziv bio uspješan (kod odgovora - 200) i False ako nije uspio (bilo koji drugi kod odgovora). Praktično ga je koristiti odmah nakon API poziva za prikaz različitih informacija ovisno o kodu odgovora.

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

statusni kod

Vraća kod odgovora nakon što je upućen API poziv.

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

Mogući kodovi odgovora: 200,400,401,403,404,409,500,501.

postavi_status_uspjeha

U tom slučaju, možda će biti potrebno promijeniti vrijednost statusa uspjeha. Tehnički, tamo možete staviti bilo što, čak i obični niz. Ali pravi primjer bio bi ponovno postavljanje ovog parametra na False pod određenim popratnim uvjetima. U nastavku obratite pažnju na primjer kada postoje zadaci koji se izvode na poslužitelju za upravljanje, ali mi ćemo ovaj zahtjev smatrati neuspješnim (postavit ćemo varijablu uspjeha na Lažan, unatoč činjenici da je API poziv bio uspješan i vratio kod 200).

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

odgovor()

Metoda odgovora omogućuje vam pregled rječnika s kodom odgovora (status_code) i tijelom odgovora (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']}}

datum

Omogućuje vam da vidite samo tijelo odgovora (tijelo) bez nepotrebnih informacija.

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

poruka_pogreške

Ova informacija dostupna je samo ako se dogodi pogreška tijekom obrade API zahtjeva (kod odgovora ne 200). Primjer izlaza

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

Korisni primjeri

Sljedeći su primjeri koji koriste API pozive koji su dodani u Management API 1.6.

Prvo, pogledajmo kako funkcioniraju pozivi add-host и dodaj-raspon-adresa. Recimo da trebamo kreirati sve IP adrese podmreže 192.168.0.0/24, čiji je zadnji oktet 5, kao objekte tipa host, a sve ostale IP adrese napisati kao objekte tipa raspona adresa. U tom slučaju isključite adresu podmreže i adresu emitiranja.

Dakle, ispod je skripta koja rješava ovaj problem i stvara 50 objekata tipa host i 51 objekt tipa raspona adresa. Za rješavanje problema potreban je 101 API poziv (ne računajući posljednji poziv za objavljivanje). Također, pomoću modula timeit izračunavamo vrijeme potrebno za izvršavanje skripte do objave promjena.

Skripta koja koristi 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')

U mom laboratorijskom okruženju, ovoj skripti je potrebno između 30 i 50 sekundi da se izvrši, ovisno o opterećenju poslužitelja za upravljanje.

Pogledajmo sada kako riješiti isti problem pomoću API poziva dodavanje-objekata-serija, podrška za koju je dodana u API verziji 1.6. Ovaj poziv vam omogućuje stvaranje više objekata odjednom u jednom API zahtjevu. Štoviše, to mogu biti objekti različitih vrsta (na primjer, hostovi, podmreže i rasponi adresa). Dakle, naš zadatak se može riješiti u okviru jednog API poziva.

Skripta koja koristi 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')

A pokretanje ove skripte u mom laboratorijskom okruženju traje od 3 do 7 sekundi, ovisno o opterećenju poslužitelja za upravljanje. To jest, u prosjeku, na 101 API objektu, skupni tip poziva radi 10 puta brže. Na većem broju objekata razlika će biti još impresivnija.

Sada da vidimo kako raditi s set-objekata-serije. Pomoću ovog API poziva možemo skupno promijeniti bilo koji parametar. Postavimo prvu polovicu adresa iz prethodnog primjera (do .124 hostova, kao i raspone) na sienu boju, a drugoj polovici adresa dodijelimo kaki boju.

Promjena boje objekata stvorenih u prethodnom primjeru

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

Možete izbrisati više objekata u jednom API pozivu pomoću brisanje-objekata-serija. Sada pogledajmo primjer koda koji briše sve hostove stvorene prethodno putem dodavanje-objekata-serija.

Brisanje objekata korištenjem 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)

Sve funkcije koje se pojavljuju u novim izdanjima softvera Check Point odmah preuzimaju API pozive. Tako su se u R80.40 pojavile takve "značajke" kao što su Vraćanje na reviziju i Smart Task, a za njih su odmah pripremljeni odgovarajući API pozivi. Štoviše, sve funkcionalnosti pri prelasku s naslijeđenih konzola na način rada Unified Policy također dobivaju API podršku. Na primjer, dugo očekivano ažuriranje u verziji softvera R80.40 bilo je premještanje pravila HTTPS Inspection iz Legacy moda u Unified Policy mod, a ova je funkcionalnost odmah primila API pozive. Ovdje je primjer koda koji dodaje pravilo na najvišu poziciju pravila HTTPS inspekcije koje isključuje 3 kategorije iz inspekcije (zdravstvo, financije, državne službe), kojima je zabranjena inspekcija u skladu sa zakonom u nizu zemalja.

Dodajte pravilo politici HTTPS inspekcije

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

Pokretanje Python skripti na poslužitelju za upravljanje Check Pointom

Sve je isto PROČITAJ ME.md sadrži informacije o tome kako pokrenuti Python skripte izravno s kontrolnog poslužitelja. Ovo može biti zgodno kada se ne možete spojiti na API poslužitelj s drugog računala. Snimio sam šestominutni video u kojem gledam ugradnju modula cpapi i značajke pokretanja Python skripti na kontrolnom poslužitelju. Kao primjer, pokreće se skripta koja automatizira konfiguraciju novog pristupnika za zadatak kao što je revizija mreže Sigurnosna provjera. Među značajkama s kojima sam se morao suočiti: funkcija se još nije pojavila u Pythonu 2.7 ulazni, pa se za obradu podataka koje korisnik unese koristi funkcija sirovi_unos. Inače, kod je isti kao i za pokretanje s drugih strojeva, samo je praktičnije koristiti funkciju prijava_kao_root, kako ne biste ponovno navodili vlastito korisničko ime, lozinku i IP adresu poslužitelja za upravljanje.

Skripta za brzo postavljanje sigurnosne provjere

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

Primjer datoteke s rječnikom lozinki Additional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Zaključak

Ovaj članak ispituje samo osnovne mogućnosti rada Python SDK i modul cpapi(kao što ste mogli pretpostaviti, ovo su zapravo sinonimi), a proučavanjem koda u ovom modulu otkrit ćete još više mogućnosti u radu s njim. Moguće je da ćete ga htjeti nadopuniti vlastitim klasama, funkcijama, metodama i varijablama. Uvijek možete podijeliti svoj rad i pogledati druge skripte za Check Point u odjeljku CodeHub u zajednici Šah Matovi, koji okuplja i programere i korisnike proizvoda.

Sretno kodiranje i hvala na čitanju do kraja!

Izvor: www.habr.com

Dodajte komentar