Zjednodušenie rozhrania Check Point API pomocou súpravy Python SDK

Zjednodušenie rozhrania Check Point API pomocou súpravy Python SDKPlná sila interakcie s API sa prejaví pri použití spolu s programovým kódom, keď je možné dynamicky generovať API požiadavky a nástroje na analýzu odpovedí API. Stále však zostáva nepostrehnuteľný Python Software Development Kit (ďalej len Python SDK) pre Check Point Management API, ale márne. Výrazne zjednodušuje život vývojárom a nadšencom automatizácie. Python si v poslednej dobe získal obrovskú popularitu a rozhodol som sa vyplniť medzeru a preskúmať hlavné funkcie. Check Point API Python Development Kit. Tento článok slúži ako výborný doplnok k ďalšiemu článku o Habrém Check Point R80.10 API. Správa cez CLI, skripty a ďalšie. Pozrieme sa na to, ako písať skripty pomocou Python SDK a bližšie sa pozrieme na novú funkciu Management API vo verzii 1.6 (podporovaná od R80.40). Na pochopenie článku budete potrebovať základné znalosti práce s API a Pythonom.

Check Point aktívne vyvíja API a momentálne boli vydané nasledovné:

Súprava Python SDK v súčasnosti podporuje iba interakciu s rozhraním Management API a Gaia API. V tomto module sa pozrieme na najdôležitejšie triedy, metódy a premenné.

Zjednodušenie rozhrania Check Point API pomocou súpravy Python SDK

Inštalácia modulu

Modul cpapi inštaluje sa rýchlo a jednoducho z oficiálne úložisko Check Point na github skrz jadro. Podrobné pokyny na inštaláciu sú k dispozícii v README.md. Tento modul je prispôsobený na prácu s verziami Pythonu 2.7 a 3.7. V tomto článku budú uvedené príklady s použitím Pythonu 3.7. Súpravu Python SDK je však možné spustiť priamo zo servera Check Point Management Server (Smart Management), ale podporujú iba Python 2.7, takže posledná časť bude obsahovať kód pre verziu 2.7. Ihneď po inštalácii modulu odporúčam pozrieť si príklady v adresároch example_python2 и example_python3.

Začíname

Aby sme mohli pracovať s komponentmi modulu cpapi, potrebujeme importovať z modulu cpapi aspoň dve povinné triedy:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Trieda APIClientArgs je zodpovedný za parametre pripojenia k serveru API a triede APIClient je zodpovedný za interakciu s API.

Určenie parametrov pripojenia

Ak chcete definovať rôzne parametre na pripojenie k API, musíte vytvoriť inštanciu triedy APIClientArgs. V zásade sú jeho parametre preddefinované a pri spustení skriptu na riadiacom serveri ich nie je potrebné špecifikovať.

client_args = APIClientArgs()

Ak však beží na hostiteľovi tretej strany, musíte zadať aspoň IP adresu alebo názov hostiteľa servera API (známeho aj ako server na správu). V nižšie uvedenom príklade definujeme parameter serverového pripojenia a priradíme mu IP adresu riadiaceho servera ako reťazec.

client_args = APIClientArgs(server='192.168.47.241')

Pozrime sa na všetky parametre a ich predvolené hodnoty, ktoré možno použiť pri pripájaní k serveru API:

Argumenty metódy __init__ triedy 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

Verím, že argumenty, ktoré možno použiť v inštanciách triedy APIClientArgs, sú pre správcov Check Pointu intuitívne a nevyžadujú si ďalšie komentáre.

Pripojenie cez APIClient a kontextový manažér

Trieda APIClient Najpohodlnejší spôsob použitia je cez kontextového manažéra. Všetko, čo je potrebné odovzdať inštancii triedy APIClient, sú parametre pripojenia, ktoré boli definované v predchádzajúcom kroku.

with APIClient(client_args) as client:

Správca kontextu nevykoná automaticky prihlasovacie volanie na server API, ale pri jeho ukončení vykoná odhlasovacie volanie. Ak sa z nejakého dôvodu po ukončení práce s volaniami API nevyžaduje odhlásenie, musíte začať pracovať bez použitia kontextového manažéra:

client = APIClient(clieng_args)

Test pripojenia

Najjednoduchší spôsob, ako skontrolovať, či pripojenie spĺňa špecifikované parametre, je použiť metódu check_fingerprint. Ak overenie súčtu hash sha1 pre odtlačok certifikátu servera API zlyhá (vrátená metóda Falošný), potom je to zvyčajne spôsobené problémami s pripojením a môžeme zastaviť vykonávanie programu (alebo dať používateľovi príležitosť opraviť údaje pripojenia):

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

Upozorňujeme, že v budúcnosti bude trieda APIClient skontroluje každé volanie API (metódy api_call и api_query, budeme o nich hovoriť trochu ďalej) certifikát odtlačku prsta sha1 na serveri API. Ak sa však pri kontrole odtlačku sha1 certifikátu servera API zistí chyba (certifikát je neznámy alebo bol zmenený), metóda check_fingerprint poskytne možnosť pridať/zmeniť informácie o ňom na lokálnom počítači automaticky. Túto kontrolu možno úplne zakázať (toto však možno odporučiť iba vtedy, ak sú skripty spustené na samotnom serveri API pri pripájaní k 127.0.0.1) pomocou argumentu APIClientArgs - unsafe_auto_accept (viac o APIClientArgs vyššie v časti „Definovanie parametrov pripojenia“).

client_args = APIClientArgs(unsafe_auto_accept=True)

Prihláste sa na server API

У APIClient existujú až 3 spôsoby prihlásenia na server API a každý z nich chápe význam sid(session-id), ktorý sa automaticky použije pri každom nasledujúcom volaní API v hlavičke (názov v hlavičke tohto parametra je X-chkp-sid), takže tento parameter nie je potrebné ďalej spracovávať.

spôsob prihlásenia

Možnosť pomocou prihlasovacieho mena a hesla (v príklade sa ako pozičné argumenty odovzdávajú používateľské meno admin a heslo 1q2w3e):

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

V spôsobe prihlásenia sú k dispozícii aj ďalšie voliteľné parametre, tu sú ich názvy a predvolené hodnoty:

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

Metóda Login_with_api_key

Možnosť s použitím kľúča API (podporované od verzie správy R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" toto je hodnota kľúča API pre jedného z používateľov na správcovskom serveri s metódou autorizácie kľúča API):

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

V metóde login_with_api_key k dispozícii sú rovnaké voliteľné parametre ako v metóde Prihlásiť sa.

metóda login_as_root

Možnosť prihlásiť sa na lokálny počítač pomocou servera API:

     login = client.login_as_root()

Pre túto metódu sú k dispozícii iba dva voliteľné parametre:

domain=None, payload=None

A nakoniec sa API volá samé

Máme dve možnosti, ako uskutočniť volania API prostredníctvom metód api_call и api_query. Poďme zistiť, aký je medzi nimi rozdiel.

api_call

Táto metóda je použiteľná pre všetky hovory. V tele žiadosti musíme v prípade potreby odovzdať poslednú časť pre volanie API a užitočné zaťaženie. Ak je užitočné zaťaženie prázdne, nemožno ho vôbec preniesť:

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

Výstup pre túto požiadavku 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'})

Výstup pre túto požiadavku 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

Dovoľte mi hneď urobiť výhradu, že táto metóda je použiteľná iba pre volania, ktorých výstup zahŕňa offset. K takémuto záveru dochádza vtedy, keď obsahuje alebo môže obsahovať veľké množstvo informácií. Môže to byť napríklad požiadavka na zoznam všetkých vytvorených hostiteľských objektov na serveri správy. Pre takéto požiadavky API štandardne vracia zoznam 50 objektov (v odpovedi môžete zvýšiť limit na 500 objektov). A aby sa informácie nevyťahovali viackrát, zmena parametra offset v požiadavke API, existuje metóda api_query, ktorá to robí automaticky. Príklady volaní, kde je táto metóda potrebná: show-sessions, show-hosters, show-networks, show-widcards, show-groups, show-address-ranges, show-simple-gateways, show-simple-clusters, show-access-role, show-dôveryhodní-klienti, výstavné balíčky. V skutočnosti vidíme v názve týchto volaní API slová v množnom čísle, takže tieto volania budú ľahšie zvládnuteľné api_query

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

Výstup pre túto požiadavku 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
})

Spracovanie výsledkov volaní API

Potom môžete použiť premenné a metódy triedy APIResponse(vo vnútri kontextového manažéra aj mimo neho). V triede APIResponse Preddefinované sú 4 metódy a 5 premenných, tým najdôležitejším sa budeme venovať podrobnejšie.

Zjednodušenie rozhrania Check Point API pomocou súpravy Python SDK

úspech

Na začiatok by bolo dobré uistiť sa, že volanie API bolo úspešné a vrátilo výsledok. Existuje na to metóda úspech:

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

Vráti True, ak bolo volanie API úspešné (kód odpovede - 200) a False, ak nebolo úspešné (akýkoľvek iný kód odpovede). Je vhodné použiť ihneď po volaní API na zobrazenie rôznych informácií v závislosti od kódu odpovede.

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

stavový kód

Vráti kód odpovede po uskutočnení volania API.

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

Možné kódy odpovede: 200,400,401,403,404,409,500,501.

set_success_status

V tomto prípade môže byť potrebné zmeniť hodnotu stavu úspechu. Technicky tam môžete dať čokoľvek, aj obyčajnú šnúrku. Ale skutočným príkladom by bolo resetovanie tohto parametra na False za určitých sprievodných podmienok. Nižšie venujte pozornosť príkladu, keď na správcovskom serveri bežia úlohy, ale túto požiadavku budeme považovať za neúspešnú (premennú úspešnosti nastavíme na Falošný, napriek tomu, že volanie API bolo úspešné a vrátilo kód 200).

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

odpoveď()

Metóda odpovede vám umožňuje zobraziť slovník s kódom odpovede (kód_stavu) a telom odpovede (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

Umožňuje vidieť iba telo odpovede (telo) bez zbytočných informácií.

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

chybná správa

Tieto informácie sú dostupné len vtedy, keď sa vyskytla chyba pri spracovaní požiadavky API (kód odpovede nie 200). Príklad výstupu

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

Užitočné príklady

Nasledujú príklady, ktoré používajú volania API, ktoré boli pridané v Management API 1.6.

Najprv sa pozrime, ako fungujú hovory pridať hostiteľa и add-address-range. Povedzme, že potrebujeme vytvoriť všetky IP adresy podsiete 192.168.0.0/24, ktorej posledný oktet je 5, ako objekty typu hostiteľ a všetky ostatné adresy IP zapísať ako objekty typu rozsahu adries. V tomto prípade vylúčte adresu podsiete a adresu vysielania.

Nižšie je uvedený skript, ktorý rieši tento problém a vytvorí 50 objektov typu hostiteľ a 51 objektov typu rozsahu adries. Na vyriešenie problému je potrebných 101 volaní API (bez započítania posledného zverejnenia). Pomocou modulu timeit tiež vypočítame čas potrebný na vykonanie skriptu, kým sa zmeny nezverejnia.

Skript pomocou add-host a 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 mojom laboratórnom prostredí trvá spustenie tohto skriptu 30 až 50 sekúnd v závislosti od zaťaženia servera na správu.

Teraz sa pozrime, ako vyriešiť rovnaký problém pomocou volania API pridať-objekty-dávka, podpora pre ktorú bola pridaná vo verzii API 1.6. Toto volanie vám umožňuje vytvoriť veľa objektov naraz v jednej požiadavke API. Okrem toho to môžu byť objekty rôznych typov (napríklad hostitelia, podsiete a rozsahy adries). Našu úlohu tak možno vyriešiť v rámci jedného volania API.

Skript pomocou 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 spustenie tohto skriptu v mojom laboratórnom prostredí trvá 3 až 7 sekúnd, v závislosti od zaťaženia servera na správu. To znamená, že v priemere na 101 objektoch API beží volanie typu dávky 10-krát rýchlejšie. Na väčšom počte objektov bude rozdiel ešte pôsobivejší.

Teraz sa pozrime, ako s ním pracovať set-objects-batch. Pomocou tohto volania API môžeme hromadne zmeniť ľubovoľný parameter. Nastavme prvú polovicu adries z predchádzajúceho príkladu (až do 124 hostiteľov a tiež rozsahy) na farbu sienna a priraďme farbu khaki k druhej polovici adries.

Zmena farby objektov vytvorených v predchádzajúcom príklade

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

Pomocou jedného volania API môžete odstrániť viacero objektov vymazať-objekty-dávka. Teraz sa pozrime na príklad kódu, ktorý odstráni všetkých hostiteľov vytvorených predtým cez pridať-objekty-dávka.

Mazanie objektov pomocou 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)

Všetky funkcie, ktoré sa objavujú v nových vydaniach softvéru Check Point, okamžite získavajú volania API. V R80.40 sa teda objavili také „funkcie“ ako Vrátiť sa k revízii a Inteligentná úloha, pre ktoré boli okamžite pripravené zodpovedajúce volania API. Navyše všetky funkcie pri prechode zo starších konzol do režimu Unified Policy tiež získavajú podporu API. Napríklad dlho očakávanou aktualizáciou vo verzii softvéru R80.40 bol presun politiky kontroly HTTPS z režimu Legacy do režimu Unified Policy a táto funkcionalita okamžite prijala volania API. Tu je príklad kódu, ktorý pridáva na popredné miesto v pravidlách kontroly HTTPS pravidlo, ktoré vylučuje z kontroly 3 kategórie (Zdravie, Financie, Služby verejnej správy), ktorých kontrola je v súlade so zákonom v mnohých krajinách zakázaná.

Pridajte pravidlo do pravidiel kontroly 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")

Spúšťanie skriptov Python na serveri správy Check Point

Všetko je rovnaké README.md obsahuje informácie o tom, ako spúšťať Python skripty priamo z riadiaceho servera. To môže byť výhodné, keď sa nemôžete pripojiť k serveru API z iného počítača. Nahral som šesťminútové video, v ktorom sa pozerám na inštaláciu modulu cpapi a funkcie spúšťania skriptov Python na riadiacom serveri. Napríklad sa spustí skript, ktorý automatizuje konfiguráciu novej brány pre úlohu, ako je audit siete Kontrola zabezpečenia. Medzi funkciami, s ktorými som sa musel zaoberať: funkcia sa ešte neobjavila v Pythone 2.7 vstup, takže na spracovanie informácií, ktoré používateľ zadá, slúži funkcia raw_input. Inak je kód rovnaký ako pri spúšťaní z iných strojov, len je pohodlnejšie používať funkciu login_as_root, aby ste znova neuviedli svoje vlastné používateľské meno, heslo a IP adresu riadiaceho servera.

Skript pre rýchle nastavenie 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("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()

Príklad súboru so slovníkom hesiel Additional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Záver

Tento článok skúma len základné možnosti práce Python SDK a modul cpapi(ako ste možno uhádli, sú to vlastne synonymá) a študovaním kódu v tomto module objavíte ešte viac možností pri práci s ním. Je možné, že ho budete chcieť doplniť o vlastné triedy, funkcie, metódy a premenné. Vždy môžete zdieľať svoju prácu a zobraziť ďalšie skripty pre Check Point v sekcii CodeHub v komunite CheckMates, ktorá združuje vývojárov produktov aj používateľov.

Príjemné kódovanie a ďakujem za prečítanie až do konca!

Zdroj: hab.com

Pridať komentár