Forenkling av Check Point API med Python SDK

Forenkling av Check Point API med Python SDKDen fulle kraften i interaksjon med API-er avsløres når den brukes sammen med programkode, når det blir mulig å dynamisk generere API-forespørsler og verktøy for å analysere API-svar. Imidlertid er det fortsatt umerkelig Python programvareutviklingssett (heretter referert til som Python SDK) for Check Point Management API, men til ingen nytte. Det forenkler livet til utviklere og automasjonsentusiaster betydelig. Python har fått enorm popularitet i det siste, og jeg bestemte meg for å fylle tomrommet og gjennomgå hovedfunksjonene. Check Point API Python Development Kit. Denne artikkelen fungerer som et utmerket tillegg til en annen artikkel om Habré Check Point R80.10 API. Styring via CLI, skript og mer. Vi skal se på hvordan du skriver skript ved å bruke Python SDK og se nærmere på den nye Management API-funksjonaliteten i versjon 1.6 (støttet fra R80.40). For å forstå artikkelen trenger du grunnleggende kunnskap om å jobbe med APIer og Python.

Check Point utvikler aktivt API og for øyeblikket har følgende blitt utgitt:

Python SDK støtter foreløpig bare interaksjon med Management API og Gaia API. Vi skal se på de viktigste klassene, metodene og variablene i denne modulen.

Forenkling av Check Point API med Python SDK

Installere modulen

Modul cpapi installeres raskt og enkelt fra offisielle Check Point-depot på github via pip. Detaljerte installasjonsinstruksjoner er tilgjengelig i README.md. Denne modulen er tilpasset for å fungere med Python versjoner 2.7 og 3.7. I denne artikkelen vil det bli gitt eksempler ved bruk av Python 3.7. Python SDK kan imidlertid kjøres direkte fra Check Point Management Server (Smart Management), men de støtter kun Python 2.7, så den siste delen vil gi kode for versjon 2.7. Umiddelbart etter installasjon av modulen anbefaler jeg å se på eksemplene i katalogene examples_python2 и examples_python3.

Komme i gang

For at vi skal kunne jobbe med komponentene i cpapi-modulen, må vi importere fra modulen cpapi minst to obligatoriske klasser:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Klasse APIClientArgs er ansvarlig for tilkoblingsparametere til API-serveren og klassen APIClient er ansvarlig for interaksjon med API.

Bestemme tilkoblingsparametere

For å definere ulike parametere for å koble til API, må du opprette en forekomst av klassen APIClientArgs. I prinsippet er parameterne forhåndsdefinert, og når du kjører skriptet på kontrollserveren, trenger de ikke spesifiseres.

client_args = APIClientArgs()

Men når du kjører på en tredjepartsvert, må du spesifisere minst IP-adressen eller vertsnavnet til API-serveren (også kjent som administrasjonsserveren). I eksemplet nedenfor definerer vi servertilkoblingsparameteren og tildeler den IP-adressen til administrasjonsserveren som en streng.

client_args = APIClientArgs(server='192.168.47.241')

La oss se på alle parameterne og deres standardverdier som kan brukes når du kobler til API-serveren:

Argumenter for __init__-metoden til APIClientArgs-klassen

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

Jeg tror at argumentene som kan brukes i forekomster av APIClientArgs-klassen er intuitive for Check Point-administratorer og krever ikke ytterligere kommentarer.

Koble til via APIClient og kontekstbehandling

Klasse APIClient Den mest praktiske måten å bruke den på er gjennom kontekstbehandlingen. Alt som må sendes til en forekomst av APIClient-klassen er tilkoblingsparametrene som ble definert i forrige trinn.

with APIClient(client_args) as client:

Kontekstbehandlingen vil ikke automatisk foreta et påloggingskall til API-serveren, men det vil foreta et utloggingskall når den avsluttes. Hvis det av en eller annen grunn ikke er nødvendig å logge ut etter å ha fullført arbeidet med API-kall, må du begynne å jobbe uten å bruke kontekstbehandlingen:

client = APIClient(clieng_args)

Kontrollerer tilkoblingen

Den enkleste måten å sjekke om tilkoblingen oppfyller de angitte parametrene er å bruke metoden check_fingerprint. Hvis verifiseringen av sha1-hash-summen for fingeravtrykket til server-API-sertifikatet mislykkes (metoden returneres Falsk), så er dette vanligvis forårsaket av tilkoblingsproblemer og vi kan stoppe kjøringen av programmet (eller gi brukeren muligheten til å korrigere tilkoblingsdataene):

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

Vær oppmerksom på at klassen i fremtiden APIClient vil sjekke hvert API-kall (metoder api_call и api_query, vi skal snakke om dem litt lenger) sha1 fingeravtrykksertifikat på API-serveren. Men hvis, når du sjekker sha1-fingeravtrykket til API-serversertifikatet, oppdages en feil (sertifikatet er ukjent eller har blitt endret), metoden check_fingerprint vil gi muligheten til å legge til/endre informasjon om det på den lokale maskinen automatisk. Denne sjekken kan deaktiveres fullstendig (men dette kan bare anbefales hvis skript kjøres på selve API-serveren, når du kobler til 127.0.0.1), ved å bruke APIClientArgs-argumentet - unsafe_auto_accept (se mer om APIClientArgs tidligere i "Definere tilkoblingsparametere").

client_args = APIClientArgs(unsafe_auto_accept=True)

Logg på API-server

У APIClient det er så mange som 3 metoder for å logge på API-serveren, og hver av dem forstår betydningen sid(session-id), som brukes automatisk i hvert påfølgende API-kall i overskriften (navnet i overskriften til denne parameteren er X-chkp-side), så det er ikke nødvendig å behandle denne parameteren ytterligere.

innloggingsmetode

Alternativ ved å bruke pålogging og passord (i eksemplet sendes brukernavnet admin og passordet 1q2w3e som posisjonsargumenter):

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

Ytterligere valgfrie parametere er også tilgjengelige i påloggingsmetoden; her er deres navn og standardverdier:

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

Login_with_api_key metode

Alternativ ved å bruke en API-nøkkel (støttes fra administrasjonsversjon R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" dette er API-nøkkelverdien for en av brukerne på administrasjonsserveren med API-nøkkelautorisasjonsmetoden):

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

I metode login_with_api_key de samme valgfrie parameterne er tilgjengelige som i metoden Logg inn.

login_as_root-metoden

Mulighet for å logge på en lokal maskin med en API-server:

     login = client.login_as_root()

Det er bare to valgfrie parametere tilgjengelig for denne metoden:

domain=None, payload=None

Og til slutt kaller API seg selv

Vi har to alternativer for å foreta API-kall gjennom metoder api_call и api_query. La oss finne ut hva forskjellen er mellom dem.

api_call

Denne metoden kan brukes for alle samtaler. Vi må sende den siste delen for api-kallet og nyttelasten i forespørselskroppen om nødvendig. Hvis nyttelasten er tom, kan den ikke overføres i det hele tatt:

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

Utdata for denne forespørselen under kuttet:

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

Utdata for denne forespørselen under kuttet:

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

La meg ta en reservasjon med en gang om at denne metoden kun gjelder for samtaler hvis utgang involverer offset. En slik slutning oppstår når den inneholder eller kan inneholde en stor mengde informasjon. Dette kan for eksempel være en forespørsel om en liste over alle opprettede vertsobjekter på administrasjonsserveren. For slike forespørsler returnerer API en liste med 50 objekter som standard (du kan øke grensen til 500 objekter i svaret). Og for ikke å trekke informasjonen flere ganger, endre offset-parameteren i API-forespørselen, er det en api_query-metode som gjør dette automatisk. Eksempler på samtaler der denne metoden er nødvendig: show-økter, show-verter, show-nettverk, show-jokertegn, show-grupper, show-adresseområder, show-enkle-gatewayer, show-enkle-klynger, show-tilgangsroller, show-trusted-clients, show-pakker. Faktisk ser vi flertallsord i navnet på disse API-kallene, så disse kallene vil være lettere å håndtere gjennom api_query

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

Utdata for denne forespørselen under kuttet:

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

Behandler resultatene av API-anrop

Etter dette kan du bruke variablene og metodene til klassen APIResponse(både i kontekstlederen og utenfor). På timen APIResponse 4 metoder og 5 variabler er forhåndsdefinert; vi vil dvele ved de viktigste mer detaljert.

Forenkling av Check Point API med Python SDK

suksess

Til å begynne med vil det være en god idé å sørge for at API-kallet var vellykket og returnerte et resultat. Det finnes en metode for dette suksess:

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

Returnerer True hvis API-kallet var vellykket (svarkode - 200) og False hvis ikke vellykket (en hvilken som helst annen svarkode). Det er praktisk å bruke umiddelbart etter et API-kall for å vise forskjellig informasjon avhengig av svarkoden.

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

statuskode

Returnerer svarkoden etter at et API-kall er utført.

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

Mulige svarkoder: 200,400,401,403,404,409,500,501.

set_success_status

I dette tilfellet kan det være nødvendig å endre verdien av suksessstatusen. Teknisk sett kan du sette hva som helst der, til og med en vanlig streng. Men et reelt eksempel ville være å tilbakestille denne parameteren til False under visse medfølgende forhold. Ta hensyn til eksemplet nedenfor når det kjører oppgaver på administrasjonsserveren, men vi vil vurdere denne forespørselen som mislykket (vi vil sette suksessvariabelen til Falsk, til tross for at API-kallet var vellykket og returnerte kode 200).

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

respons()

Svarmetoden lar deg se ordboken med svarkoden (status_code) og svarteksten (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']}}

dato

Lar deg se bare brødteksten til svaret (body) uten unødvendig informasjon.

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

feilmelding

Denne informasjonen er bare tilgjengelig når det oppstod en feil under behandlingen av API-forespørselen (svarkode no 200). Eksempelutgang

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

Nyttige eksempler

Følgende er eksempler som bruker API-kallene som ble lagt til i Management API 1.6.

La oss først se på hvordan samtaler fungerer add-host и add-address-range. La oss si at vi må opprette alle IP-adresser til undernettet 192.168.0.0/24, hvorav den siste oktetten er 5, som objekter av vertstypen, og skrive alle andre IP-adresser som objekter av adresseområdetypen. I dette tilfellet ekskluderer du subnettadressen og kringkastingsadressen.

Så nedenfor er et skript som løser dette problemet og oppretter 50 objekter av vertstypen og 51 objekter av typen adresseområde. For å løse problemet kreves 101 API-kall (ikke medregnet det endelige publiseringskallet). Ved å bruke timeit-modulen beregner vi også tiden det tar å kjøre skriptet til endringene er publisert.

Skript ved hjelp av add-host og 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')

I mitt laboratoriemiljø tar dette skriptet mellom 30 og 50 sekunder å kjøre, avhengig av belastningen på administrasjonsserveren.

La oss nå se hvordan du løser det samme problemet ved å bruke et API-kall add-objects-batch, støtte som ble lagt til i API-versjon 1.6. Dette kallet lar deg lage mange objekter samtidig i en API-forespørsel. Dessuten kan disse være objekter av forskjellige typer (for eksempel verter, subnett og adresseområder). Dermed kan oppgaven vår løses innenfor rammen av ett API-kall.

Skript ved hjelp av 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')

Og å kjøre dette skriptet i laboratoriemiljøet mitt tar fra 3 til 7 sekunder, avhengig av belastningen på administrasjonsserveren. Det vil si at i gjennomsnitt, på 101 API-objekter, kjører et batchtype-kall 10 ganger raskere. På et større antall objekter vil forskjellen være enda mer imponerende.

La oss nå se hvordan vi jobber med sett-objekter-batch. Ved å bruke dette API-kallet kan vi masseendre alle parametere. La oss sette den første halvdelen av adressene fra forrige eksempel (opptil .124 verter, og områder også) til fargen sienna, og tilordne fargen khaki til den andre halvdelen av adressene.

Endre fargen på objektene som ble opprettet i forrige eksempel

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

Du kan slette flere objekter i ett API-kall ved å bruke slette-objekter-batch. La oss nå se på et kodeeksempel som sletter alle verter som er opprettet tidligere via add-objects-batch.

Slette objekter ved hjelp av 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)

Alle funksjoner som vises i nye utgivelser av Check Point-programvare, får umiddelbart API-kall. I R80.40 dukket derfor opp slike "funksjoner" som Gå tilbake til revisjon og Smart Task, og tilsvarende API-kall ble umiddelbart forberedt for dem. Dessuten får all funksjonalitet når du flytter fra eldre konsoller til Unified Policy-modus også API-støtte. For eksempel var den etterlengtede oppdateringen i programvareversjon R80.40 flyttingen av HTTPS-inspeksjonspolicyen fra Legacy-modus til Unified Policy-modus, og denne funksjonaliteten mottok umiddelbart API-kall. Her er et eksempel på kode som legger til en regel til topplasseringen i HTTPS-inspeksjonspolicyen som ekskluderer 3 kategorier fra inspeksjon (helse, finans, offentlige tjenester), som er forbudt fra inspeksjon i henhold til loven i en rekke land.

Legg til en regel i HTTPS-inspeksjonspolicyen

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

Kjører Python-skript på Check Point-administrasjonsserveren

Alt er det samme README.md inneholder informasjon om hvordan du kjører Python-skript direkte fra kontrollserveren. Dette kan være praktisk når du ikke kan koble til API-serveren fra en annen maskin. Jeg tok opp en seks minutters video der jeg ser på installasjonen av modulen cpapi og funksjoner for å kjøre Python-skript på kontrollserveren. Som et eksempel kjøres et skript som automatiserer konfigurasjonen av en ny gateway for en oppgave som nettverksrevisjon Sikkerhetssjekk. Blant funksjonene jeg måtte forholde meg til: funksjonen har ennå ikke dukket opp i Python 2.7 inngang, så for å behandle informasjonen som brukeren legger inn, brukes en funksjon rå_inngang. Ellers er koden den samme som for oppstart fra andre maskiner, bare det er mer praktisk å bruke funksjonen login_as_root, for ikke å spesifisere ditt eget brukernavn, passord og IP-adresse til administrasjonsserveren igjen.

Skript for rask oppsett av sikkerhetssjekk

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

En eksempelfil med en passordordbok additional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Konklusjon

Denne artikkelen undersøker bare de grunnleggende arbeidsmulighetene Python SDK og modul cpapi(som du kanskje har gjettet, er dette faktisk synonymer), og ved å studere koden i denne modulen vil du oppdage enda flere muligheter i å jobbe med den. Det er mulig du vil supplere med dine egne klasser, funksjoner, metoder og variabler. Du kan alltid dele arbeidet ditt og se andre skript for Check Point i delen CodeHub i samfunnet CheckMates, som samler både produktutviklere og brukere.

Lykke til med koding og takk for at du leste til slutten!

Kilde: www.habr.com

Legg til en kommentar