Zjednodušujeme práci s Check Point API pomocí Python SDK

Zjednodušujeme práci s Check Point API pomocí Python SDKVeškerá síla interakce s API se odhaluje při spolupráci s programovým kódem, kdy vznikají možnosti dynamicky vytvářet API dotazy a nástroje pro analýzu API odpovědí. Přesto zůstává málo viditelné Python Software Development Kit (dále jen Python SDK) pro Check Point Management API, a to je škoda. Výrazně usnadňuje život vývojářům a nadšencům automatizace. Python v poslední době získal obrovskou popularitu a rozhodl jsem se vyplnit mezeru a přehlednout hlavní možnosti Check Point API Python Development Kit. Tento článek slouží jako skvělý doplněk dalšího článku na Habré Check Point R80.10 API. Správa přes CLI, skripty a další. My se pak podíváme, jak psát skripty s využitím Python SDK a podrobněji se zaměříme na nové funkce Management API ve verzi 1.6 (podporováno od R80.40). Pro pochopení článku budou potřebné základní znalosti o práci s API a Pythonem.

Check Point aktivně rozvíjí API a v současné době vznikly:

Python SDK v současnosti podporuje interakci pouze s Management API a Gaia API.Podíváme se na nejdůležitější třídy, metody a proměnné v tomto modulu.

Zjednodušujeme práci s Check Point API pomocí Python SDK

Instalace modulu

Modul cpapi se instaluje rychle a jednoduše z oficiálního repozitáře Check Point na GitHubu prostřednictvím pip. Podrobný návod k instalaci naleznete v README.md. Tento modul je přizpůsoben pro práci s verzemi Python 2.7 a 3.7. V tomto článku budou uvedeny příklady s využitím Python 3.7. Nicméně, Python SDK lze spouštět přímo ze správcovského serveru Check Point (Smart Management), avšak na nich je podporována pouze verze Python 2.7, proto v posledním oddíle bude uveden kód pro verzi 2.7. Ihned po instalaci modulu doporučuji podívat se na příklady ve složkách examples_python2 a examples_python3.

Začínáme

Abychom mohli pracovat s komponentami modulu cpapi, musíme importovat z modulu cpapi alespoň dvě potřebné třídy:

APIClient a APIClientArgs

from cpapi import APIClient, APIClientArgs

Třída APIClientArgs odpovídá za parametry připojení k API serveru, zatímco třída APIClient odpovídá za interakci s API.

Definujeme parametry připojení

Pro určení různých parametrů připojení k API je nutné vytvořit instanci třídy APIClientArgs. V podstatě jsou její parametry předdefinovány a při spuštění skriptu na serveru správy je není nutné uvádět.

client_args = APIClientArgs()

Ale při spuštění na externím hostiteli je třeba uvést alespoň IP adresu nebo jméno hostitele API serveru (to je také server správy). V příkladu níže definujeme připojovací parametr server a přiřadíme mu jako řetězec IP adresu serveru správy.

client_args = APIClientArgs(server='192.168.47.241')

Podívejme se na všechny parametry a jejich výchozí hodnoty, které lze použít při připojení k API serveru:

Argumenty metody __init__ třídy APIClientArgs

class APIClientArgs:
    """
    Tato třída poskytuje argumenty pro konfiguraci APIClient.
    Všechny argumenty jsou nakonfigurovány s výchozími hodnotami.
    """

    # port je implicitně nastaven na None, ale pokud není uveden, nahradí se 443
    # možné hodnoty kontextu - web_api (výchozí) nebo 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
        # otisk serveru správy
        self.fingerprint = fingerprint
        # id relace.
        self.sid = sid
        # jméno nebo IP adresa serveru správy
        self.server = server
        # úroveň ladění
        self.http_debug_level = http_debug_level
        # pole se všemi API voláními (pro účely ladění)
        self.api_calls = api_calls if api_calls else []
        # název souboru pro ladění. Pokud zůstane prázdný, ladicí data nebudou uložena na disk.
        self.debug_file = debug_file
        # adresa HTTP proxy serveru (bez "http://")
        self.proxy_host = proxy_host
        # port HTTP proxy
        self.proxy_port = proxy_port
        # API verze serveru správy
        self.api_version = api_version
        # Naznačuje, že klient by neměl kontrolovat certifikát serveru
        self.unsafe = unsafe
        # Naznačuje, že klient by měl automaticky akceptovat a ukládat certifikát serveru
        self.unsafe_auto_accept = unsafe_auto_accept
        # Kontext používání klienta - ve výchozím nastavení web_api
        self.context = context

Domnívám se, že argumenty, které lze použít v instancích třídy APIClientArgs, jsou intuitivně jasné správcům Check Point a nepotřebují další komentáře.

Připojujeme se přes APIClient a správce kontextu

Třída APIClient nejlépe se používá přes správce kontextu. Vše, co je potřeba předat instanci třídy APIClient, jsou parametry připojení, které byly definovány v předchozím kroku.

with APIClient(client_args) as client:

Správce kontextu nebude automaticky provádět login na API server, ale provede logout při odhlášení. Pokud z nějakého důvodu není logout při ukončení práce s API hovory potřeba, je třeba zahájit práci bez použití správce kontextu:

client = APIClient(clieng_args)

Kontrola připojení

Nejjednodušší způsob, jak zkontrolovat, zda připojení odpovídá zadaným parametrům, je použít metodu check_fingerprint. Pokud kontrola SHA1 hash certifikátu API serveru neproběhla (metoda vrátila Při provádění scénáře Nornir se do konzole vyprodukují podrobné logy.), obvykle to způsobí problémy s připojením a můžeme zastavit vykonávání programu (nebo dát uživateli možnost opravit připojovací údaje):

    if client.check_fingerprint() is False:
        print("Nebylo možné získat fingerprint serveru - Zkontrolujte připojení se serverem.")
        exit(1)

Mějte na paměti, že třída APIClient bude kontrolovat při každém API volání (metody api_call a api_query, o nichž bude řeč později) SHA1 fingerprint certifikátu na API serveru. Pokud při kontrole SHA1 fingerprint certifikátu API serveru dojde k chybě (certifikát je neznámý nebo byl změněn), metoda check_fingerprint umožní přidat/změnit informace o něm na lokálním počítači automaticky. Tuto kontrolu je možné zcela deaktivovat (ale to se doporučuje pouze v případě spuštění skriptů na samotném API serveru, při připojení k 127.0.0.1), pomocí argumentu APIClientArgs — unsafe_auto_accept (více informací o APIClientArgs dříve v části 'Definování parametrů připojení').

client_args = APIClientArgs(unsafe_auto_accept=True)

Přihlášení na API server

V APIClient existují celkem 3 metody přihlášení na API server, a každá z nich ukládá hodnotu sid(session-id), kterou automaticky používá v každém dalším API volání v hlavičce (název v hlavičce tohoto parametru — X-chkp-sid), takže tento parametr není třeba dodatečně zpracovávat.

Metoda přihlášení

Varianta s použitím přihlašovacího jména a hesla (v příkladu je uživatelské jméno admin a heslo 1q2w3e předáno jako poziční argumenty):

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

V metodě login jsou také k dispozici další volitelné parametry, uvádím jejich jména a výchozí hodnoty:

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

Metoda login_with_api_key

Varianta s použitím API klíče (podporováno od verze managementu R80.40 / Management API v1.6, „3TsbPJ8ZKjaJGvFyoFqHFA==“ toto je hodnota API klíče pro jednoho z uživatelů na řídicím serveru s metodou autorizace API key):

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

V metodě login_with_api_key jsou k dispozici stejné volitelné parametry jako v metodě login.

Metoda login_as_root

Varianta přihlášení na lokální stroj s API serverem:

     login = client.login_as_root()

Pro tuto metodu jsou k dispozici pouze dva volitelné parametry:

domain=None, payload=None

A nakonec samotné API volání

Máme dvě možnosti, jak provádět API volání přes metody api_call a api_query. Pojďme se podívat na rozdíl mezi nimi.

api_call

Tento způsob je použitelný pro jakákoli volání. Musíme předat poslední část pro API volání a payload v těle žádosti při potřebě. Pokud je payload prázdný, může se zcela vynechat:

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

Výstup pro tuto žádost níže:

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 pro tuto žádost níže:

Ve [25]: show_host                                                              
Out[25]: 
APIResponse({
    "data": {
        "color": "černá",
        "comments": "",
        "domain": {
            "domain-type": "doména",
            "name": "SMC Uživatel",
            "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": "odemčený",
            "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": "černá",
            "comments": "",
            "domain": {
                "domain-type": "doména",
                "name": "SMC Uživatel",
                "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": "odemčený",
                "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

Hned na začátek chci říci, že tato metoda se používá pouze pro volání, jejichž výstup předpokládá offset. Tento výstup se generuje v případě, že obsahuje nebo může obsahovat velké množství informací. Například to může být dotaz na seznam všech vytvořených objektů typu host na serveru řízení. Pro takové dotazy API standardně vrací seznam 50 objektů (může být zvýšen limit na 500 objektů v odpovědi). A aby se informace nevyžadovaly několikrát, měníc parametry offset v API dotazu, existuje metoda api_query, která tuto práci vykonává automaticky. Příklady volání, kde je tato metoda potřebná: show-sessions, show-hosts, show-networks, show-wildcards, show-groups, show-address-ranges, show-simple-gateways, show-simple-clusters, show-access-roles, show-trusted-clients, show-packages. Ve skutečnosti vidíme v názvu těchto API volání slova v množném čísle, takže tato volání se budou lépe zpracovávat prostřednictvím api_query

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

Výstup pro tuto žádost níže:

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

Zpracování výsledků API volání

Po tomto můžete používat proměnné a metody třídy APIResponse(jak uvnitř kontextového manažera, tak vně). Třída má APIResponse předdefinovány 4 metody a 5 proměnných, na nejdůležitějších se blíže zastavíme.

Zjednodušujeme práci s Check Point API pomocí Python SDK

success

Na začátek by bylo dobré se ujistit, že API volání proběhlo úspěšně a vrátilo výsledek. K tomu slouží metoda success:

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

Vrací True pokud API volání proběhlo úspěšně (Kód odpovědi — 200) a False pokud neúspěšně (jakýkoli jiný kód odpovědi). Je vhodné ho použít ihned po API volání, abyste podle kódu odpovědi zobrazili různé informace.

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

statuscode

Vrací kód odpovědi po provedení API volání.

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

Možné kódy odpovědí: 200,400,401,403,404,409,500,501.

set_success_status

Při tom může být potřeba změnit hodnotu stavu success. Technicky tam lze vložit cokoliv, dokonce i běžný řetězec. Reálným příkladem může být resetování tohoto parametru na False za určitých doplňkových podmínek. Níže si všimněte příkladu, kdy jsou úkoly prováděny na správním serveru, ale tento požadavek považujeme za neúspěšný (nastavíme proměnnou success na Při provádění scénáře Nornir se do konzole vyprodukují podrobné logy., přestože API volání bylo úspěš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

response()

Metoda response umožňuje zobrazit slovník s kódem odpovědi (status_code) a tělem odpovědi (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 zobrazit pouze tělo odpovědi (body) bez zbytečných informací.

In [93]: api_versions.data                                                      
Out[93]: 
{'current-version': '1.6',
 'supported-versions': ['1', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6']}

error_message

Tato informace je dostupná pouze tehdy, když při zpracování API požadavku došlo k chybě (kód odpovědi ne 200). Příklad výstupu

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

Užitečné příklady

Níže jsou uvedeny příklady, které používají API volání, jež byla přidána ve verzi Management API 1.6.

Nejprve se podívejme na práci s voláními add-host a add-address-range. Předpokládejme, že potřebujeme vytvořit jako objekty typu host všechny ip adresy podsítě 192.168.0.0/24, jejichž poslední oktet je 5, a všechny ostatní ip adresy zapsat jako objekty typu rozsah adres. Přitom adresu podsítě a šířkově vysílací adresu vyloučíme.

Takže níže je uveden skript, který řeší tento úkol a vytváří 50 objektů typu host a 51 objekt typu rozsah adres. Na vyřešení úkolu je potřeba 101 API volání (nepočítaje poslední volání publish). Také pomocí modulu timeit počítáme čas na provedení skriptu do okamžiku publikování změn.

Skript s použitím 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 mém laboratorním prostředí trvá provedení tohoto skriptu od 30 do 50 sekund v závislosti na zátěži řídicího serveru.

A nyní se podívejme, jak vyřešit tento úkol pomocí API volání add-objects-batch, jehož podpora byla přidána ve verzi API 1.6. Toto volání umožňuje vytvořit více objektů najednou jedním API požadavkem. Mohou to být objekty různých typů (například hostitelé, podsítě a adresní rozsahy). Naše úloha tedy může být splněna v rámci jednoho API volání.

Skript se použitím 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 provedení tohoto skriptu v mém laboratorním prostředí trvá od 3 do 7 sekund v závislosti na zátěži řídicího serveru. To znamená, že v průměru je volání API typu batch na 101 objektech 10krát rychlejší. Při větším počtu objektů bude rozdíl ještě působivější.

Nyní se podívejme, jak pracovat s set-objects-batch. S pomocí tohoto API volání můžeme hromadně změnit libovolný parametr. Pojďme nastavit první polovinu adres z minulého příkladu (do .124 hostitele, a to i pro rozsahy) na barvu sienna a druhé polovině adres přiřadíme barvu khaki.

Změna barvy objektů vytvořených v předchozím příkladu

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

Mnoho objektů lze odstranit v jednom API volání pomocí delete-objects-batch. A teď se podívejme na příklad kódu, který odstraňuje všechny dříve vytvořené hostitele prostřednictvím add-objects-batch.

Odstranění objektů pomocí 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šechny funkce, které se objevují v nových verzích softwaru Check Point, okamžitě zahrnují i API volání. V R80.40 se objevily funkce jako Revert to revision a Smart Task, a pro ně byla okamžitě připravena odpovídající API volání. Kromě toho veškerá funkcionalita při přechodu z Legacy konzolí do režimu Unified Policy rovněž získává podporu API. Například dlouho očekávanou aktualizací ve verzi softwaru R80.40 byla migrace politiky HTTPS Inspection z Legacy režimu do režimu Unified Policy, a tento funkční prvek okamžitě obdržel API volání. Zde je příklad kódu, který přidává na vrcholovou pozici politiku HTTPS Inspection pravidlo, které vylučuje z inspekce 3 kategorie (Zdraví, Finance, Státní služby), které jsou zakázány inspektovat podle legislativy v řadě zemí.

Přidat pravidlo do politiky HTTPS Inspection

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

data = {
  "layer" : "Default Layer",
  "position" : "top",
  "name" : "Právní požadavky",
  "action": "bypass",
  "site-category": ["Zdraví", "Vláda / Vojenské", "Finanční služby"]
}

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

Spuštění Python skriptů na správním serveru Check Point

Vše ve stejném README.md obsahuje informace o tom, jak spouštět skripty v Pythonu přímo ze správního serveru. To může být užitečné, když nemáte možnost připojit se k API serveru z jiného stroje. Nahrál jsem šestiminutové video, ve kterém zkoumám instalaci modulu cpapi a zvláštnosti spuštění Python skriptů na správním serveru. Jako příklad spouští se skript, který automatizuje konfiguraci nového brány pro úkoly, jako je audit sítě Security CheckUp. Mezi zvláštnosti, se kterými jsem se setkal: ve verzi Python 2.7 ještě neexistovala funkce input, proto pro zpracování informací, které zadává uživatel, se používá funkce raw_input. Jinak je kód stejný jako pro spuštění z jiných strojů, jen je pohodlnější používat funkci login_as_root, abychom nemuseli znovu uvádět své vlastní uživatelské jméno, heslo a IP adresu správního serveru.

Přehrát video

Skript pro rychlé nastavení 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("Nemohu získat otisk serveru - Zkontrolujte připojení k serveru.")
       #     exit(1)
        login_res = client.login_as_root()

        if login_res.success is False:
            print("Přihlášení se nezdařilo:n{}".format(login_res.error_message))
            exit(1)

        gw_name = raw_input("Zadejte název brány:")
        gw_ip = raw_input("Zadejte IP adresu brány:")
        if sys.stdin.isatty():
            sic = getpass.getpass("Zadejte jednorázové heslo pro bránu (SIC): ")
        else:
            print("Pozor! Vaše heslo bude zobrazeno na obrazovce!")
            sic = raw_input("Zadejte jednorázové heslo pro bránu (SIC): ")
        version = raw_input("Zadejte verzi brány (např. 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("Zabezpečené připojení k bráně nebylo navázáno!")
            exit(1)
        elif add_gw.success:
            print("Brána byla úspěšně přidána.")
            gw_uid = add_gw.data['uid']
            gw_name = add_gw.data['name']
        else:
            print("Nepodařilo se přidat bránu - {}".format(add_gw.error_message))
            exit(1)

        change_policy = client.api_call("set-access-layer", {"name" : "Síť", "applications-and-url-filtering": "true", "content-awareness": "true"})
        if change_policy.success:
            print("Politika byla úspěšně změněna")
        else:
            print("Nepodařilo se změnit politiku - {}".format(change_policy.error_message))
        change_rule = client.api_call("set-access-rule", {"name" : "Pravidlo pro úklid", "layer" : "Síť", "action": "Přijmout", "track": {"type": "Podrobný záznam", "accounting": "true"}})
        if change_rule.success:
            print("Pravidlo pro úklid bylo úspěšně změněno")
        else:
            print("Nepodařilo se změnit pravidlo pro úklid - {}".format(change_rule.error_message))

        # publikovat výsledek
        publish_res = client.api_call("publish", {})
        if publish_res.success:
            print("Změny byly úspěšně publikovány.")
        else:
                print("Nepodařilo se publikovat změny - {}".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("Přístupová politika byla nainstalována")
        else:
                print("Nepodařilo se nainstalovat přístupovou politiku - {}".format(install_tp_policy.error_message))

        install_tp_policy = client.api_call("install-policy", {"policy-package" : "Standard", "access" : 'false',  "threat-prevention" : 'true', "targets" : gw_uid})
        if install_tp_policy.success:
            print("Politika prevence hrozeb byla nainstalována")
        else:
            print("Nepodařilo se nainstalovat politiku prevence hrozeb - {}".format(install_tp_policy.error_message))
        
        # přidat hesla a fráze do slovníku
        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" : "Přidat hesla a fráze", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
                if add_password_dictionary.success:
                    print("Řádek slovníku hesel {} byl úspěšně přidán".format(line_num))
                else:
                    print("Nepodařilo se přidat slovník - {}".format(add_password_dictionary.error_message))

main()

Ukázkový soubor se slovníkem hesel additional_pass.conf
{
"hesla" : ["malware","malicious","infected","Infected"],
"fráze" : ["heslo","Heslo","Pass","pass","codigo","klíč","pwd","пароль","Пароль","Ключ","klíč","šifrovat","Šifrovat"]
}

Závěr

Tento článek se zaměřuje pouze na základní možnosti práce Python SDK a modulu cpapi(jak jste mohli uhodnout, to jsou ve skutečnosti synonyma), a studiem kódu v tomto modulu objevíte ještě více možností jeho využití. Není vyloučeno, že se vám podaří doplnit ho o své vlastní třídy, funkce, metody a proměnné. Vždy se můžete podělit o své výtvory a prohlédnout si další skripty pro Check Point v sekci CodeHub v komunitě CheckMates, která spojuje jak vývojáře produktů, tak uživatele.

Příjemné programování a děkujeme, že jste dočetli až do konce!

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster