Check Point API vienkārŔoŔana, izmantojot Python SDK

Check Point API vienkārÅ”oÅ”ana, izmantojot Python SDKPilns mijiedarbÄ«bas spēks ar API tiek atklāts, ja to izmanto kopā ar programmas kodu, kad kļūst iespējams dinamiski Ä£enerēt API pieprasÄ«jumus un rÄ«kus API atbilžu analÄ«zei. Tomēr tas joprojām paliek nemanāms Python programmatÅ«ras izstrādes komplekts (turpmāk tekstā ā€” Python SDK), kas paredzēta Check Point Management API, bet velti. Tas ievērojami vienkārÅ”o izstrādātāju un automatizācijas entuziastu dzÄ«vi. Python pēdējā laikā ir ieguvis milzÄ«gu popularitāti, un es nolēmu aizpildÄ«t robu un pārskatÄ«t galvenās funkcijas. Check Point API Python izstrādes komplekts. Å is raksts kalpo kā lielisks papildinājums citam rakstam par HabrĆ© Check Point R80.10 API. PārvaldÄ«ba, izmantojot CLI, skriptus un daudz ko citu. Mēs apskatÄ«sim, kā rakstÄ«t skriptus, izmantojot Python SDK, un sÄ«kāk aplÅ«kosim jauno Management API funkcionalitāti versijā 1.6 (atbalstÄ«ta sākot no R80.40). Lai saprastu rakstu, jums bÅ«s nepiecieÅ”amas pamatzināŔanas par darbu ar API un Python.

Check Point aktīvi izstrādā API, un Ŕobrīd ir izlaistas:

Python SDK paÅ”laik atbalsta tikai mijiedarbÄ«bu ar pārvaldÄ«bas API un Gaia API. Å ajā modulÄ« mēs apskatÄ«sim svarÄ«gākās klases, metodes un mainÄ«gos.

Check Point API vienkārŔoŔana, izmantojot Python SDK

Moduļa uzstādīŔana

Modulis cpapi ātri un vienkārÅ”i instalē no oficiālajā Check Point repozitorijā vietnē github via pip. Detalizētas uzstādÄ«Å”anas instrukcijas ir pieejamas README.md. Å is modulis ir pielāgots darbam ar Python versijām 2.7 un 3.7. Å ajā rakstā tiks sniegti piemēri, izmantojot Python 3.7. Tomēr Python SDK var palaist tieÅ”i no Check Point Management Server (Smart Management), taču tie atbalsta tikai Python 2.7, tāpēc pēdējā sadaļā tiks nodroÅ”ināts kods versijai 2.7. Uzreiz pēc moduļa instalÄ“Å”anas iesaku apskatÄ«t piemērus direktorijās examples_python2 Šø examples_python3.

Darba sākŔana

Lai mēs varētu strādāt ar cpapi moduļa komponentiem, mums ir jāimportē no moduļa cpapi vismaz divas obligātās klases:

APIClient Šø APIClientArgs

from cpapi import APIClient, APIClientArgs

Klase APIClientArgs ir atbildīgs par savienojuma parametriem ar API serveri un klasi APIClient ir atbildīgs par mijiedarbību ar API.

Savienojuma parametru noteikŔana

Lai definētu dažādus parametrus savienojumam ar API, jums ir jāizveido klases gadÄ«jums APIClientArgs. Principā tā parametri ir iepriekÅ” definēti un, palaižot skriptu vadÄ«bas serverÄ«, tie nav jānorāda.

client_args = APIClientArgs()

Bet, darbojoties treŔās puses resursdatorā, jums ir jānorāda vismaz API servera (pazÄ«stams arÄ« kā pārvaldÄ«bas serveri) IP adrese vai resursdatora nosaukums. Tālāk esoÅ”ajā piemērā mēs definējam servera savienojuma parametru un pieŔķiram tam pārvaldÄ«bas servera IP adresi kā virkni.

client_args = APIClientArgs(server='192.168.47.241')

Apskatīsim visus parametrus un to noklusējuma vērtības, ko var izmantot, veidojot savienojumu ar API serveri:

APIClientArgs klases metodes __init__ argumenti

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

Es uzskatu, ka argumenti, ko var izmantot APIClientArgs klases gadījumos, ir intuitīvi Check Point administratoriem un tiem nav nepiecieŔami papildu komentāri.

Savienojuma izveide, izmantojot APIClient un konteksta pārvaldnieku

Klase APIClient Ērtākais veids, kā to izmantot, ir konteksta pārvaldnieks. Viss, kas jānodod APIClient klases instancē, ir savienojuma parametri, kas tika definēti iepriekŔējā darbÄ«bā.

with APIClient(client_args) as client:

Konteksta pārvaldnieks automātiski neveiks pieteikÅ”anās zvanu API serverim, taču, izejot no tā, tas veiks atteikÅ”anās zvanu. Ja pēc darba ar API izsaukumiem kāda iemesla dēļ atteikÅ”anās nav nepiecieÅ”ama, jāsāk strādāt, neizmantojot konteksta pārvaldnieku:

client = APIClient(clieng_args)

Savienojuma pārbaude

VienkārŔākais veids, kā pārbaudÄ«t, vai savienojums atbilst norādÄ«tajiem parametriem, ir izmantot Å”o metodi pārbaudÄ«t_pirkstu nospiedumu. Ja servera API sertifikāta pirksta nospieduma sha1 jaucējsummas pārbaude neizdodas (atgrieztā metode Nepatiess), tad to parasti izraisa savienojuma problēmas un mēs varam apturēt programmas izpildi (vai dot lietotājam iespēju labot savienojuma datus):

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

LÅ«dzu, ņemiet vērā, ka turpmāk klasē APIClient pārbaudÄ«s katru API zvanu (metodes api_call Šø api_query, mēs par tiem runāsim nedaudz tālāk) sha1 pirkstu nospiedumu sertifikāts API serverÄ«. Bet, ja, pārbaudot API servera sertifikāta sha1 pirksta nospiedumu, tiek konstatēta kļūda (sertifikāts nav zināms vai ir mainÄ«ts), metode pārbaudÄ«t_pirkstu nospiedumu nodroÅ”inās iespēju automātiski pievienot/mainÄ«t informāciju par to lokālajā maŔīnā. Å o pārbaudi var pilnÄ«bā atspējot (bet to var ieteikt tikai tad, ja skripti tiek palaisti paŔā API serverÄ«, kad tiek izveidots savienojums ar 127.0.0.1), izmantojot APIClientArgs argumentu - unsafe_auto_accept (vairāk par APIClientArgs skatiet sadaļā ā€œSavienojuma parametru definÄ“Å”anaā€).

client_args = APIClientArgs(unsafe_auto_accept=True)

Piesakieties API serverī

Š£ APIClient ir 3 metodes, lai pieteiktos API serverÄ«, un katra no tām saprot nozÄ«mi sid(session-id), kas tiek automātiski izmantots katrā nākamajā API izsaukumā galvenē (nosaukums Ŕī parametra galvenē ir X-chkp-sid), tāpēc Å”is parametrs nav jāapstrādā tālāk.

pieteikŔanās metode

Opcija, izmantojot pieteikumvārdu un paroli (piemērā lietotājvārds admin un parole 1q2w3e tiek nodoti kā pozicionālie argumenti):

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

PieteikÅ”anās metodē ir pieejami arÄ« papildu izvēles parametri; Å”eit ir to nosaukumi un noklusējuma vērtÄ«bas:

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

PieteikŔanās_ar_api_key metodi

Opcija, izmantojot api atslēgu (tiek atbalstÄ«ta, sākot no pārvaldÄ«bas versijas R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" Ŕī ir API atslēgas vērtÄ«ba vienam no lietotājiem pārvaldÄ«bas serverÄ« ar API atslēgas autorizācijas metodi):

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

Metodē login_with_api_key ir pieejami tie paÅ”i izvēles parametri kā metodē Pieslēgties.

login_as_root metode

Iespēja pieteikties vietējā maŔīnā ar API serveri:

     login = client.login_as_root()

Šai metodei ir pieejami tikai divi izvēles parametri:

domain=None, payload=None

Un visbeidzot API izsauc sevi

Mums ir divas iespējas veikt API zvanus, izmantojot metodes api_call Šø api_query. Noskaidrosim, kāda ir atŔķirÄ«ba starp tām.

api_call

Å Ä« metode ir piemērota visiem zvaniem. VajadzÄ«bas gadÄ«jumā mums ir jānodod pēdējā API izsaukuma daļa un lietderÄ«gā slodze pieprasÄ«juma pamattekstā. Ja krava ir tukÅ”a, to vispār nevar pārsÅ«tÄ«t:

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

Šī pieprasījuma izvade zem griezuma:

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

Šī pieprasījuma izvade zem griezuma:

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

Ä»aujiet man uzreiz izdarÄ«t atrunu, ka Ŕī metode ir piemērojama tikai zvaniem, kuru izvade ir saistÄ«ta ar nobÄ«di. Šāds secinājums rodas, ja tas satur vai var saturēt lielu informācijas daudzumu. Piemēram, tas varētu bÅ«t pieprasÄ«jums pēc visu izveidoto saimniekdatora objektu saraksta pārvaldÄ«bas serverÄ«. Šādiem pieprasÄ«jumiem API pēc noklusējuma atgriež sarakstu ar 50 objektiem (atbildē varat palielināt ierobežojumu lÄ«dz 500 objektiem). Un, lai informācija netiktu izvilkta vairākas reizes, mainot nobÄ«des parametru API pieprasÄ«jumā, ir api_query metode, kas to veic automātiski. Zvanu piemēri, kur Ŕī metode ir nepiecieÅ”ama: raidÄ«jumu sesijas, raidÄ«jumu vadÄ«tāji, Å”ovu tÄ«kli, rādÄ«Å”anas aizstājējzÄ«mes, Å”ovu grupas, rādÄ«Å”anas adreÅ”u diapazoni, vienkārŔās demonstrÄ“Å”anas vārtejas, vienkārŔās demonstrÄ“Å”anas kopas, raidÄ«jumu piekļuves lomas, uzticamo klientu demonstrÄ“Å”ana, Å”ovu paketes. Faktiski Å”o API izsaukumu nosaukumos redzami vārdi daudzskaitļa formā, tāpēc Å”os zvanus bÅ«s vieglāk apstrādāt api_query

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

Šī pieprasījuma izvade zem griezuma:

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

API zvanu rezultātu apstrāde

Pēc tam varat izmantot klases mainÄ«gos un metodes APIResponse(gan konteksta pārvaldniekā, gan ārpus tā). Klasē APIResponse Ir iepriekÅ” definētas 4 metodes un 5 mainÄ«gie, pie svarÄ«gākajām mēs pakavēsimies sÄ«kāk.

Check Point API vienkārŔoŔana, izmantojot Python SDK

veiksme

Vispirms būtu ieteicams pārliecināties, vai API izsaukums bija veiksmīgs un atgrieza rezultātu. Tam ir metode veiksme:

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

Atgriež True, ja API izsaukums bija veiksmÄ«gs (atbildes kods ā€” 200), un False, ja tas nav veiksmÄ«gs (jebkurÅ” cits atbildes kods). To ir ērti lietot uzreiz pēc API izsaukuma, lai parādÄ«tu dažādu informāciju atkarÄ«bā no atbildes koda.

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

statusa kods

Atgriež atbildes kodu pēc API izsaukuma.

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

Iespējamie atbildes kodi: 200,400,401,403,404,409,500,501.

set_success_status

Šādā gadÄ«jumā var bÅ«t nepiecieÅ”ams mainÄ«t veiksmes statusa vērtÄ«bu. Tehniski tur var likt jebko, pat parastu virkni. Taču reāls piemērs varētu bÅ«t Ŕī parametra atiestatÄ«Å”ana uz False noteiktos papildu apstākļos. Tālāk pievērsiet uzmanÄ«bu piemēram, kad pārvaldÄ«bas serverÄ« darbojas uzdevumi, taču mēs uzskatÄ«sim Å”o pieprasÄ«jumu par neveiksmÄ«gu (veiksmes mainÄ«go iestatÄ«sim uz Nepatiess, neskatoties uz to, ka API izsaukums bija veiksmÄ«gs un atgrieza kodu 200).

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

atbilde ()

Atbildes metode ļauj skatīt vārdnīcu ar atbildes kodu (statusa_kods) un atbildes pamattekstu (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']}}

dati

Ļauj redzēt tikai atbildes pamattekstu (ķermeni) bez liekas informācijas.

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

kļūdas ziņojums

Šī informācija ir pieejama tikai tad, ja API pieprasījuma apstrādes laikā radās kļūda (atbildes kods nē 200). Izvades piemērs

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

Noderīgi piemēri

Tālāk ir sniegti piemēri, kuros tiek izmantoti API izsaukumi, kas tika pievienoti pārvaldÄ«bas API 1.6.

Vispirms apskatÄ«sim, kā darbojas zvani pievienoÅ”anas resursdators Šø add-adreÅ”u diapazons. Pieņemsim, ka mums ir jāizveido visas apakÅ”tÄ«kla 192.168.0.0/24 IP adreses, kuru pēdējais oktets ir 5, kā resursdatora tipa objekti un visas pārējās IP adreses jāraksta kā adreÅ”u diapazona tipa objekti. Šādā gadÄ«jumā izslēdziet apakÅ”tÄ«kla adresi un apraides adresi.

Tātad, zemāk ir skripts, kas atrisina Å”o problēmu un izveido 50 resursdatora tipa objektus un 51 objektu adreses diapazona tipa. Lai atrisinātu problēmu, ir nepiecieÅ”ams 101 API izsaukums (neņemot vērā galÄ«go publicÄ“Å”anas zvanu). Tāpat, izmantojot timeit moduli, mēs aprēķinām laiku, kas nepiecieÅ”ams skripta izpildei lÄ«dz izmaiņu publicÄ“Å”anai.

Skripts, izmantojot add-host un 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')

Manā laboratorijas vidē Ŕī skripta izpilde aizņem no 30 lÄ«dz 50 sekundēm atkarÄ«bā no pārvaldÄ«bas servera slodzes.

Tagad redzēsim, kā atrisināt to paÅ”u problēmu, izmantojot API zvanu pievieno-objekti-partija, kuras atbalsts tika pievienots API versijā 1.6. Å is izsaukums ļauj vienā API pieprasÄ«jumā vienlaikus izveidot vairākus objektus. Turklāt tie var bÅ«t dažāda veida objekti (piemēram, resursdatori, apakÅ”tÄ«kli un adreÅ”u diapazoni). Tādējādi mÅ«su uzdevumu var atrisināt viena API izsaukuma ietvaros.

Skripts, izmantojot 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')

Un Ŕī skripta palaiÅ”ana manā laboratorijas vidē aizņem no 3 lÄ«dz 7 sekundēm atkarÄ«bā no pārvaldÄ«bas servera slodzes. Tas nozÄ«mē, ka vidēji 101 API objektā pakeÅ”u veida izsaukums darbojas 10 reizes ātrāk. Lielākam objektu skaitam atŔķirÄ«ba bÅ«s vēl iespaidÄ«gāka.

Tagad redzēsim, kā strādāt ar set-objects-batch. Izmantojot Å”o API izsaukumu, mēs varam lielapjoma mainÄ«t jebkuru parametru. IestatÄ«sim adreÅ”u pirmo pusi no iepriekŔējā piemēra (lÄ«dz .124 saimniekiem un arÄ« diapazoniem) uz krāsu sienna un pieŔķirsim haki krāsu adreÅ”u otrajai pusei.

IepriekŔējā piemērā izveidoto objektu krāsas maiņa

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

Varat dzēst vairākus objektus vienā API izsaukumā, izmantojot delete-objects-batch. Tagad apskatÄ«sim koda piemēru, kas dzÄ“Å” visus saimniekdatorus, kas iepriekÅ” izveidoti, izmantojot pievieno-objekti-partija.

Objektu dzēŔana, izmantojot 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)

Visas funkcijas, kas parādās jaunajos Check Point programmatÅ«ras laidienos, nekavējoties iegÅ«st API izsaukumus. Tādējādi R80.40 parādÄ«jās tādas ā€œfunkcijasā€ kā Revert to revision un Smart Task, un tām nekavējoties tika sagatavoti atbilstoÅ”i API izsaukumi. Turklāt visas funkcionalitātes, pārejot no mantotajām konsolēm uz vienotās politikas režīmu, iegÅ«st arÄ« API atbalstu. Piemēram, programmatÅ«ras versijas R80.40 ilgi gaidÄ«tais atjauninājums bija HTTPS pārbaudes politikas pārvietoÅ”ana no mantotā režīma uz vienotās politikas režīmu, un Ŕī funkcionalitāte nekavējoties saņēma API zvanus. Tālāk ir sniegts koda piemērs, kas HTTPS pārbaudes politikas augŔējai pozÄ«cijai pievieno kārtulu, kas no pārbaudēm izslēdz 3 kategorijas (veselÄ«bas, finanÅ”u, valdÄ«bas pakalpojumus), kurām saskaņā ar likumu vairākās valstÄ«s ir aizliegts pārbaudÄ«t.

Pievienojiet kārtulu HTTPS pārbaudes politikai

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

Python skriptu palaiŔana Check Point pārvaldības serverī

Viss ir vienāds README.md satur informāciju par to, kā palaist Python skriptus tieÅ”i no vadÄ«bas servera. Tas var bÅ«t ērti, ja nevarat izveidot savienojumu ar API serveri no citas iekārtas. Es ierakstÄ«ju seÅ”u minÅ«Å”u video, kurā aplÅ«koju moduļa instalÄ“Å”anu cpapi un Python skriptu palaiÅ”anas funkcijas vadÄ«bas serverÄ«. Piemēram, tiek palaists skripts, kas automatizē jaunas vārtejas konfigurÄ“Å”anu uzdevumam, piemēram, tÄ«kla auditÄ“Å”anai. DroŔības pārbaude. Starp funkcijām, ar kurām man bija jātiek galā: funkcija Python 2.7 vēl nav parādÄ«jusies ievade, lai apstrādātu lietotāja ievadÄ«to informāciju, tiek izmantota funkcija raw_input. Citādi kods ir tāds pats kā palaiÅ”anai no citām maŔīnām, tikai ērtāk izmantot funkciju login_as_root, lai vēlreiz nenorādÄ«tu savu lietotājvārdu, paroli un pārvaldÄ«bas servera IP adresi.

Skripts droŔības pārbaudes ātrai iestatīŔanai

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

Piemērs failam ar paroles vārdnīcu Additional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","ŠæŠ°Ń€Š¾Š»ŃŒ","ŠŸŠ°Ń€Š¾Š»ŃŒ","ŠšŠ»ŃŽŃ‡","ŠŗŠ»ŃŽŃ‡","шŠøфр","ŠØŠøфр"] }

Secinājums

Å ajā rakstā aplÅ«kotas tikai darba pamatiespējas Python SDK un modulis cpapi(kā jau varēja uzminēt, tie patiesÄ«bā ir sinonÄ«mi), un, izpētot kodu Å”ajā modulÄ«, jÅ«s atklāsiet vēl vairāk iespēju strādāt ar to. Iespējams, vēlēsities to papildināt ar savām klasēm, funkcijām, metodēm un mainÄ«gajiem. Sadaļā vienmēr varat kopÄ«got savus darbus un skatÄ«t citus Check Point skriptus CodeHub sabiedrÄ«bā CheckMates, kas apvieno gan produktu izstrādātājus, gan lietotājus.

LaimÄ«gu kodÄ“Å”anu un paldies, ka izlasÄ«jāt lÄ«dz beigām!

Avots: www.habr.com

Pievieno komentāru