Poenostavitev API-ja Check Point s SDK-jem Python

Poenostavitev API-ja Check Point s SDK-jem PythonPolna moč interakcije z API-ji se razkrije pri uporabi skupaj s programsko kodo, ko postane mogoče dinamično generirati API zahteve in orodja za analizo API odzivov. Vendar pa še vedno ostaja neopazen Komplet za razvoj programske opreme Python (v nadaljnjem besedilu Python SDK) za Check Point Management API, a zaman. Bistveno poenostavi življenje razvijalcem in navdušencem nad avtomatizacijo. Python je v zadnjem času pridobil izjemno priljubljenost in odločil sem se, da zapolnim vrzel in pregledam glavne funkcije. Check Point API Python Development Kit. Ta članek je odličen dodatek k drugemu članku na Habréju Check Point R80.10 API. Upravljanje prek CLI, skriptov in več. Ogledali si bomo, kako pisati skripte z uporabo Python SDK in podrobneje preučiti novo funkcionalnost API-ja za upravljanje v različici 1.6 (podprto od R80.40). Za razumevanje članka boste potrebovali osnovno znanje o delu z API-ji in Pythonom.

Check Point aktivno razvija API in trenutno je bilo izdano naslednje:

Python SDK trenutno podpira samo interakcijo z API-jem za upravljanje in Gaia API. V tem modulu si bomo ogledali najpomembnejše razrede, metode in spremenljivke.

Poenostavitev API-ja Check Point s SDK-jem Python

Namestitev modula

Modul cpapi se hitro in enostavno namesti iz uradno skladišče Check Point na githubu s pomočjo pip. Podrobna navodila za namestitev so na voljo v PREBERITE.md. Ta modul je prilagojen za delo z različicama Python 2.7 in 3.7. V tem članku bodo podani primeri z uporabo Pythona 3.7. Vendar pa je Python SDK mogoče zagnati neposredno s strežnika za upravljanje Check Point (Smart Management), vendar podpirajo samo Python 2.7, zato bo zadnji razdelek zagotovil kodo za različico 2.7. Takoj po namestitvi modula priporočam, da si ogledate primere v imenikih primeri_python2 и primeri_python3.

Začetek

Da lahko delamo s komponentami modula cpapi, moramo uvoziti iz modula cpapi vsaj dva obvezna razreda:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Razred APIClientArgs je odgovoren za parametre povezave s strežnikom API in razred APIClient je odgovoren za interakcijo z API-jem.

Določanje parametrov povezave

Če želite določiti različne parametre za povezovanje z API-jem, morate ustvariti primerek razreda APIClientArgs. Načeloma so njeni parametri vnaprej določeni in jih pri zagonu skripte na nadzornem strežniku ni treba podajati.

client_args = APIClientArgs()

Ko pa se izvaja na gostitelju tretje osebe, morate podati vsaj naslov IP ali ime gostitelja strežnika API (znanega tudi kot strežnik za upravljanje). V spodnjem primeru definiramo parameter povezave s strežnikom in mu kot niz dodelimo naslov IP strežnika za upravljanje.

client_args = APIClientArgs(server='192.168.47.241')

Oglejmo si vse parametre in njihove privzete vrednosti, ki jih je mogoče uporabiti pri povezovanju s strežnikom API:

Argumenti metode __init__ razreda 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

Menim, da so argumenti, ki jih je mogoče uporabiti v primerih razreda APIClientArgs, skrbnikom Check Point intuitivni in ne zahtevajo dodatnih komentarjev.

Povezovanje prek APIClient in upravitelja konteksta

Razred APIClient Najprimernejši način za uporabo je prek upravitelja konteksta. Vse, kar je treba posredovati primerku razreda APIClient, so parametri povezave, ki so bili definirani v prejšnjem koraku.

with APIClient(client_args) as client:

Upravljalnik konteksta ne bo samodejno izvedel klica za prijavo v strežnik API-ja, vendar bo izvedel klic za odjavo, ko ga zapusti. Če iz nekega razloga po končanem delu s klici API-ja odjava ni potrebna, morate začeti delati brez uporabe upravitelja konteksta:

client = APIClient(clieng_args)

Preizkus povezave

Najlažji način za preverjanje, ali povezava ustreza navedenim parametrom, je uporaba metode preveri_prstni odtis. Če preverjanje zgoščene vsote sha1 za prstni odtis potrdila API strežnika ne uspe (vrnjena metoda False), potem je to običajno posledica težav s povezavo in lahko zaustavimo izvajanje programa (ali damo uporabniku možnost, da popravi podatke o povezavi):

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

Upoštevajte, da bo v prihodnje razred APIClient bo preveril vsak klic API (metode api_call и api_query, o njih bomo govorili malo dlje) potrdilo o prstnem odtisu sha1 na strežniku API. Če pa se pri preverjanju prstnega odtisa sha1 potrdila strežnika API odkrije napaka (certifikat ni znan ali je bil spremenjen), metoda preveri_prstni odtis bo omogočil samodejno dodajanje/spreminjanje informacij o njem na lokalnem računalniku. To preverjanje je mogoče popolnoma onemogočiti (vendar je to mogoče priporočiti samo, če se skripti izvajajo na samem strežniku API, ko se povezujete z 127.0.0.1), z uporabo argumenta APIClientArgs - unsafe_auto_accept (več o APIClientArgs si oglejte prej v “Določanje parametrov povezave”).

client_args = APIClientArgs(unsafe_auto_accept=True)

Prijavite se v API strežnik

У APIClient obstajajo kar 3 metode za prijavo v API strežnik in vsak od njih razume pomen sid(id-seje), ki se samodejno uporabi pri vsakem naslednjem klicu API-ja v glavi (ime v glavi tega parametra je X-chkp-sid), zato tega parametra ni treba nadalje obdelovati.

način prijave

Možnost uporabe prijave in gesla (v primeru sta uporabniško ime admin in geslo 1q2w3e posredovana kot pozicijski argumenti):

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

V načinu prijave so na voljo tudi dodatni neobvezni parametri; tukaj so njihova imena in privzete vrednosti:

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

Metoda login_with_api_key

Možnost uporabe ključa API (podprto od različice za upravljanje R80.40/API za upravljanje v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" to je vrednost ključa API za enega od uporabnikov na strežniku za upravljanje z metodo avtorizacije ključa API):

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

V metodi login_with_api_key na voljo so enaki neobvezni parametri kot pri metodi prijava.

metoda login_as_root

Možnost prijave v lokalni stroj s strežnikom API:

     login = client.login_as_root()

Za to metodo sta na voljo samo dva izbirna parametra:

domain=None, payload=None

In končno se API kliče sam

Imamo dve možnosti za klice API prek metod api_call и api_query. Ugotovimo, kakšna je razlika med njimi.

api_call

Ta metoda je uporabna za vse klice. Po potrebi moramo posredovati zadnji del za klic api in tovor v telesu zahteve. Če je tovor prazen, ga sploh ni mogoče prenesti:

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

Izhod za to zahtevo pod rezom:

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

Izhod za to zahtevo pod rezom:

In [25]: show_host                                                              
Out[25]: 
APIResponse({
    "data": {
        "color": "black",
        "comments": "",
        "domain": {
            "domain-type": "domain",
            "name": "SMC User",
            "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
        },
        "groups": [],
        "icon": "Objects/host",
        "interfaces": [],
        "ipv4-address": "8.8.8.8",
        "meta-info": {
            "creation-time": {
                "iso-8601": "2020-05-01T21:49+0300",
                "posix": 1588358973517
            },
            "creator": "admin",
            "last-modifier": "admin",
            "last-modify-time": {
                "iso-8601": "2020-05-01T21:49+0300",
                "posix": 1588358973517
            },
            "lock": "unlocked",
            "validation-state": "ok"
        },
        "name": "h_8.8.8.8",
        "nat-settings": {
            "auto-rule": false
        },
        "read-only": false,
        "tags": [],
        "type": "host",
        "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
    },
    "res_obj": {
        "data": {
            "color": "black",
            "comments": "",
            "domain": {
                "domain-type": "domain",
                "name": "SMC User",
                "uid": "41e821a0-3720-11e3-aa6e-0800200c9fde"
            },
            "groups": [],
            "icon": "Objects/host",
            "interfaces": [],
            "ipv4-address": "8.8.8.8",
            "meta-info": {
                "creation-time": {
                    "iso-8601": "2020-05-01T21:49+0300",
                    "posix": 1588358973517
                },
                "creator": "admin",
                "last-modifier": "admin",
                "last-modify-time": {
                    "iso-8601": "2020-05-01T21:49+0300",
                    "posix": 1588358973517
                },
                "lock": "unlocked",
                "validation-state": "ok"
            },
            "name": "h_8.8.8.8",
            "nat-settings": {
                "auto-rule": false
            },
            "read-only": false,
            "tags": [],
            "type": "host",
            "uid": "c210af07-1939-49d3-a351-953a9c471d9e"
        },
        "status_code": 200
    },
    "status_code": 200,
    "success": true
})

api_query

Naj takoj rezerviram, da je ta metoda uporabna samo za klice, katerih rezultat vključuje odmik. Do takega sklepanja pride, če vsebuje ali lahko vsebuje veliko količino informacij. To je lahko na primer zahteva za seznam vseh ustvarjenih gostiteljskih objektov na strežniku za upravljanje. Za takšne zahteve API privzeto vrne seznam 50 objektov (v odgovoru lahko omejitev povečate na 500 objektov). In da ne bi večkrat potegnili informacij, spreminjanje parametra odmika v zahtevi API, obstaja metoda api_query, ki to delo opravi samodejno. Primeri klicev, kjer je potrebna ta 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, razstavni paketi. Pravzaprav vidimo množinske besede v imenu teh klicev API-ja, zato bo te klice lažje obravnavati api_query

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

Izhod za to zahtevo pod rezom:

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

Obdelava rezultatov klicev API

Po tem lahko uporabite spremenljivke in metode razreda APIResponse(tako znotraj upravitelja konteksta kot zunaj). V razredu APIResponse Vnaprej so določene 4 metode in 5 spremenljivk, na najpomembnejših se bomo podrobneje posvetili.

Poenostavitev API-ja Check Point s SDK-jem Python

uspeh

Za začetek bi bilo dobro, da se prepričate, ali je bil klic API uspešen in je vrnil rezultat. Za to obstaja metoda uspeh:

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

Vrne True, če je bil klic API-ja uspešen (odzivna koda - 200) in False, če ni bil uspešen (katera koli druga odzivna koda). Priročno ga je uporabiti takoj po klicu API-ja za prikaz različnih informacij glede na odzivno kodo.

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

statusna koda

Po opravljenem klicu API-ja vrne odzivno kodo.

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

Možne odzivne kode: 200,400,401,403,404,409,500,501.

set_success_status

V tem primeru bo morda treba spremeniti vrednost statusa uspeha. Tehnično lahko tja postavite karkoli, tudi običajno vrvico. Toda pravi primer bi bila ponastavitev tega parametra na False pod določenimi spremljajočimi pogoji. Spodaj bodite pozorni na primer, ko se na strežniku za upravljanje izvajajo naloge, vendar bomo to zahtevo obravnavali kot neuspešno (spremenljivko uspeha bomo nastavili na False, kljub dejstvu, da je bil klic API uspešen in je vrnil kodo 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 odziva vam omogoča ogled slovarja s kodo odziva (koda_statusa) in telesom odgovora (telo).

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

Omogoča ogled samo telesa odgovora (telo) brez nepotrebnih informacij.

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

obvestilo o napaki

Te informacije so na voljo le, če je med obdelavo zahteve API prišlo do napake (odzivna koda ne 200). Primer izhoda

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

Uporabni primeri

Sledijo primeri, ki uporabljajo klice API-ja, ki so bili dodani v API-ju za upravljanje 1.6.

Najprej si poglejmo, kako delujejo klici add-host и dodaj obseg-naslovov. Recimo, da moramo ustvariti vse naslove IP podomrežja 192.168.0.0/24, katerih zadnji oktet je 5, kot objekte tipa gostitelja, vse druge naslove IP pa zapisati kot objekte tipa obsega naslovov. V tem primeru izključite naslov podomrežja in oddajni naslov.

Torej, spodaj je skript, ki rešuje to težavo in ustvari 50 objektov tipa gostitelja in 51 objektov tipa obsega naslovov. Za rešitev težave je potreben 101 klic API-ja (brez štetja končnega objave). Prav tako z modulom timeit izračunamo čas, ki je potreben za izvedbo skripta do objave sprememb.

Skript z uporabo add-host in 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')

V mojem laboratorijskem okolju traja izvajanje tega skripta od 30 do 50 sekund, odvisno od obremenitve strežnika za upravljanje.

Zdaj pa poglejmo, kako rešiti isto težavo s klicem API-ja dodajanje predmetov-serija, za katerega je bila podpora dodana v API različici 1.6. Ta klic vam omogoča ustvarjanje več objektov hkrati v eni zahtevi API. Poleg tega so to lahko predmeti različnih vrst (na primer gostitelji, podomrežja in obsegi naslovov). Tako lahko našo nalogo rešimo v okviru enega API klica.

Skript z uporabo 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')

Zagon tega skripta v mojem laboratorijskem okolju traja od 3 do 7 sekund, odvisno od obremenitve strežnika za upravljanje. To pomeni, da se v povprečju na 101 objektu API paketni klic izvaja 10-krat hitreje. Na večjem številu objektov bo razlika še bolj impresivna.

Zdaj pa poglejmo, kako delati s set-predmetov-serija. S tem klicem API-ja lahko množično spremenimo kateri koli parameter. Nastavimo prvo polovico naslovov iz prejšnjega primera (do .124 gostiteljev in tudi obsege) na barvo sienna, drugi polovici naslovov pa dodelimo barvo kaki.

Spreminjanje barve predmetov, ustvarjenih v prejšnjem primeru

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

Z enim klicem API-ja lahko izbrišete več objektov brisanje-predmetov-paket. Zdaj pa si poglejmo primer kode, ki izbriše vse gostitelje, ustvarjene prej prek dodajanje predmetov-serija.

Brisanje predmetov z uporabo 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)

Vse funkcije, ki se pojavijo v novih izdajah programske opreme Check Point, takoj pridobijo klice API. Tako so se v R80.40 pojavile takšne "funkcije", kot sta Povrnitev na revizijo in Pametno opravilo, zanje pa so bili takoj pripravljeni ustrezni klici API-ja. Poleg tega vse funkcije ob prehodu s podedovanih konzol v način poenotenih pravilnikov pridobijo tudi podporo za API. Na primer, dolgo pričakovana posodobitev v različici programske opreme R80.40 je bila premik pravilnika o pregledovanju HTTPS iz podedovanega načina v način poenotene politike in ta funkcionalnost je takoj prejela klice API-ja. Tu je primer kode, ki doda pravilo na najvišji položaj pravilnika o inšpekcijskih pregledih HTTPS, ki iz inšpekcijskih pregledov izključuje 3 kategorije (zdravje, finance, vladne službe), ki jih je v skladu z zakonodajo v številnih državah prepovedano pregledovati.

Dodajte pravilo pravilniku o pregledu HTTPS

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

Izvajanje skriptov Python na strežniku za upravljanje Check Point

Vse je isto PREBERITE.md vsebuje informacije o tem, kako izvajati skripte Python neposredno iz nadzornega strežnika. To je lahko priročno, če se ne morete povezati s strežnikom API z drugega računalnika. Posnel sem šestminutni video, v katerem si ogledam namestitev modula cpapi in funkcije izvajanja skriptov Python na nadzornem strežniku. Kot primer se izvede skript, ki avtomatizira konfiguracijo novega prehoda za nalogo, kot je revizija omrežja Varnostni pregled. Med funkcijami, s katerimi sem se moral soočiti: funkcija se še ni pojavila v Pythonu 2.7 vhod, zato se za obdelavo informacij, ki jih vnese uporabnik, uporablja funkcija surov_vnos. V nasprotnem primeru je koda enaka kot pri zagonu iz drugih strojev, le da je uporaba funkcije bolj priročna login_as_root, da ne boste znova podajali lastnega uporabniškega imena, gesla in IP naslova strežnika za upravljanje.

Skripta za hitro nastavitev varnostnega pregleda

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

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

Zaključek

Ta članek obravnava le osnovne možnosti dela SDK za Python in modul cpapi(kot ste morda uganili, gre pravzaprav za sopomenke), s preučevanjem kode v tem modulu pa boste odkrili še več možnosti pri delu z njo. Možno je, da ga boste želeli dopolniti z lastnimi razredi, funkcijami, metodami in spremenljivkami. Vedno lahko delite svoje delo in si ogledate druge skripte za Check Point v razdelku CodeHub v skupnosti CheckMates, ki združuje tako razvijalce izdelkov kot uporabnike.

Veselo kodiranje in hvala za branje do konca!

Vir: www.habr.com

Dodaj komentar