Forenkling af Check Point API med Python SDK

Forenkling af Check Point API med Python SDKDen fulde kraft af interaktion med API'er afsløres, når den bruges sammen med programkode, når det bliver muligt dynamisk at generere API-anmodninger og værktøjer til at analysere API-svar. Det er dog stadig ubemærket Python Software Development Kit (herefter benævnt Python SDK) for Check Point Management API, men forgæves. Det forenkler livet for udviklere og automationsentusiaster markant. Python har vundet enorm popularitet på det seneste, og jeg besluttede at udfylde hullet og gennemgå de vigtigste funktioner. Check Point API Python Development Kit. Denne artikel fungerer som en fremragende tilføjelse til en anden artikel om Habré Check Point R80.10 API. Administration via CLI, scripts og mere. Vi vil se på, hvordan man skriver scripts ved hjælp af Python SDK og se nærmere på den nye Management API-funktionalitet i version 1.6 (understøttet fra R80.40). For at forstå artiklen skal du have grundlæggende viden om at arbejde med API'er og Python.

Check Point udvikler aktivt API'et, og i øjeblikket er følgende blevet frigivet:

Python SDK understøtter i øjeblikket kun interaktion med Management API og Gaia API. Vi vil se på de vigtigste klasser, metoder og variabler i dette modul.

Forenkling af Check Point API med Python SDK

Modul installation

Modul cpapi installeres hurtigt og nemt fra officielt Check Point-lager på github via pip. Detaljerede installationsvejledninger er tilgængelige i README.md. Dette modul er tilpasset til at fungere med Python version 2.7 og 3.7. I denne artikel vil der blive givet eksempler ved brug af Python 3.7. Python SDK kan dog køres direkte fra Check Point Management Server (Smart Management), men de understøtter kun Python 2.7, så det sidste afsnit vil give kode til version 2.7. Umiddelbart efter installation af modulet anbefaler jeg at se på eksemplerne i mapperne eksempler_python2 и eksempler_python3.

Kom godt i gang

For at vi kan arbejde med komponenterne i cpapi-modulet, skal vi importere fra modulet cpapi mindst to obligatoriske klasser:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

Klasse APIClientArgs er ansvarlig for forbindelsesparametre til API-serveren og klassen APIClient er ansvarlig for interaktion med API.

Bestemmelse af forbindelsesparametre

For at definere forskellige parametre for tilslutning til API'en skal du oprette en forekomst af klassen APIClientArgs. I princippet er dens parametre foruddefineret, og når scriptet køres på kontrolserveren, skal de ikke specificeres.

client_args = APIClientArgs()

Men når du kører på en tredjepartsvært, skal du som minimum angive IP-adressen eller værtsnavnet på API-serveren (også kendt som administrationsserveren). I eksemplet nedenfor definerer vi serverforbindelsesparameteren og tildeler den administrationsserverens IP-adresse som en streng.

client_args = APIClientArgs(server='192.168.47.241')

Lad os se på alle de parametre og deres standardværdier, der kan bruges, når der oprettes forbindelse til API-serveren:

Argumenter for __init__-metoden i 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 mener, at de argumenter, der kan bruges i forekomster af APIClientArgs-klassen, er intuitive for Check Point-administratorer og ikke kræver yderligere kommentarer.

Tilslutning via APIClient og konteksthåndtering

Klasse APIClient Den mest bekvemme måde at bruge det på er gennem kontekstadministratoren. Det eneste, der skal sendes til en forekomst af APIClient-klassen, er forbindelsesparametrene, der blev defineret i det foregående trin.

with APIClient(client_args) as client:

Kontekstmanageren vil ikke automatisk foretage et login-kald til API-serveren, men den vil foretage et logout-kald, når den afsluttes. Hvis det af en eller anden grund ikke er nødvendigt at logge ud efter at have afsluttet arbejdet med API-kald, skal du begynde at arbejde uden at bruge konteksthåndteringen:

client = APIClient(clieng_args)

Forbindelsestest

Den nemmeste måde at kontrollere, om forbindelsen opfylder de angivne parametre, er at bruge metoden check_fingerprint. Hvis verifikationen af ​​sha1-hash-summen for fingeraftrykket af server-API-certifikatet mislykkes (metoden returneres False), så er dette normalt forårsaget af forbindelsesproblemer, og vi kan stoppe udførelsen af ​​programmet (eller give brugeren mulighed for at rette forbindelsesdataene):

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

Bemærk venligst, at klassen fremover APIClient vil tjekke hvert API-kald (metoder api_kald и api_query, vi taler om dem lidt længere) sha1 fingeraftrykscertifikat på API-serveren. Men hvis der, når du kontrollerer sha1-fingeraftrykket for API-servercertifikatet, opdages en fejl (certifikatet er ukendt eller er blevet ændret), metoden check_fingerprint vil give mulighed for automatisk at tilføje/ændre information om det på den lokale maskine. Denne kontrol kan deaktiveres fuldstændigt (men dette kan kun anbefales, hvis scripts køres på selve API-serveren, når der oprettes forbindelse til 127.0.0.1), ved hjælp af APIClientArgs-argumentet - unsafe_auto_accept (se mere om APIClientArgs tidligere i "Definition af forbindelsesparametre").

client_args = APIClientArgs(unsafe_auto_accept=True)

Log ind på API-server

У APIClient der er så mange som 3 metoder til at logge ind på API-serveren, og hver af dem forstår betydningen sid(session-id), som bruges automatisk i hvert efterfølgende API-kald i headeren (navnet i overskriften på denne parameter er X-chkp-side), så det er ikke nødvendigt at behandle denne parameter yderligere.

login metode

Mulighed for brug af login og adgangskode (i eksemplet sendes brugernavnet admin og adgangskoden 1q2w3e som positionelle argumenter):

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

Yderligere valgfri parametre er også tilgængelige i login-metoden; her er deres navne og standardværdier:

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

Login_with_api_key metode

Mulighed ved hjælp af en api-nøgle (understøttet fra administrationsversion R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" dette er API-nøgleværdien for en af ​​brugerne på administrationsserveren med API-nøgleautorisationsmetoden):

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

I metode login_with_api_key de samme valgfrie parametre er tilgængelige som i metoden Logge på.

login_as_root metode

Mulighed for at logge ind på en lokal maskine med en API-server:

     login = client.login_as_root()

Der er kun to valgfrie parametre tilgængelige for denne metode:

domain=None, payload=None

Og endelig kalder API'en sig selv

Vi har to muligheder for at foretage API-kald gennem metoder api_kald и api_query. Lad os finde ud af, hvad forskellen er mellem dem.

api_kald

Denne metode er anvendelig for alle opkald. Vi skal videregive den sidste del til api-kaldet og nyttelasten i anmodningsteksten, hvis det er nødvendigt. Hvis nyttelasten er tom, kan den slet ikke overføres:

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

Output for denne anmodning under cut:

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

Output for denne anmodning under cut:

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

Lad mig tage forbehold med det samme, at denne metode kun er anvendelig for opkald, hvis output involverer offset. En sådan slutning opstår, når den indeholder eller kan indeholde en stor mængde information. For eksempel kan dette være en anmodning om en liste over alle oprettede værtsobjekter på administrationsserveren. For sådanne anmodninger returnerer API'en som standard en liste med 50 objekter (du kan øge grænsen til 500 objekter i svaret). Og for ikke at trække oplysningerne flere gange, ændre offset-parameteren i API-anmodningen, er der en api_query-metode, der gør dette automatisk. Eksempler på opkald, hvor denne metode er nødvendig: show-sessioner, show-værter, show-netværk, show-wildcards, show-grupper, show-adresseområder, show-simple-gateways, show-simple-clusters, show-adgangsroller, show-trusted-clients, show-pakker. Faktisk ser vi flertalsord i navnet på disse API-kald, så disse opkald vil være nemmere at håndtere gennem api_query

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

Output for denne anmodning under cut:

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

Behandling af resultaterne af API-kald

Herefter kan du bruge klassens variabler og metoder APIResponse(både i kontekstmanageren og udenfor). I klassen APIResponse 4 metoder og 5 variable er foruddefinerede; vi vil dvæle ved de vigtigste mere detaljeret.

Forenkling af Check Point API med Python SDK

succes

Til at begynde med ville det være en god idé at sikre sig, at API-kaldet var vellykket og gav et resultat. Der er en metode til dette succes:

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

Returnerer True, hvis API-kaldet var vellykket (svarkode - 200) og False, hvis det ikke lykkedes (enhver anden svarkode). Det er praktisk at bruge umiddelbart efter et API-kald til at vise forskellige oplysninger afhængigt af svarkoden.

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

statuskode

Returnerer svarkoden efter et API-kald er foretaget.

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

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

set_success_status

I dette tilfælde kan det være nødvendigt at ændre værdien af ​​successtatus. Teknisk set kan du sætte hvad som helst der, selv en almindelig streng. Men et rigtigt eksempel ville være at nulstille denne parameter til Falsk under visse ledsagende forhold. Nedenfor skal du være opmærksom på eksemplet, når der kører opgaver på administrationsserveren, men vi vil betragte denne anmodning som mislykket (vi indstiller succesvariablen til False, på trods af at API-kaldet var vellykket og returnerede 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 giver dig mulighed for at se ordbogen 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']}}

data

Giver dig mulighed for kun at se brødteksten af ​​svaret (body) uden unødvendig information.

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

fejl besked

Disse oplysninger er kun tilgængelige, når der opstod en fejl under behandlingen af ​​API-anmodningen (svarkode nej 200). Eksempel output

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

Nyttige eksempler

Følgende er eksempler, der bruger de API-kald, der blev tilføjet i Management API 1.6.

Lad os først se på, hvordan opkald fungerer tilføjelsesvært и tilføje-adresse-område. Lad os sige, at vi skal oprette alle IP-adresser på undernettet 192.168.0.0/24, hvoraf den sidste oktet er 5, som objekter af værtstypen, og skrive alle andre IP-adresser som objekter af adresseområdetypen. I dette tilfælde skal du ekskludere undernetadressen og broadcastadressen.

Så nedenfor er et script, der løser dette problem og opretter 50 objekter af værtstypen og 51 objekter af typen adresseområde. For at løse problemet kræves der 101 API-kald (det endelige publiceringskald ikke medregnet). Ved hjælp af timeit-modulet beregner vi også den tid, det tager at udføre scriptet, indtil ændringerne er publiceret.

Script ved hjælp af 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 mit laboratoriemiljø tager dette script mellem 30 og 50 sekunder at udføre, afhængigt af belastningen på administrationsserveren.

Lad os nu se, hvordan man løser det samme problem ved hjælp af et API-kald tilføje-objekter-batch, der blev tilføjet understøttelse i API-version 1.6. Dette kald giver dig mulighed for at oprette mange objekter på én gang i en API-anmodning. Desuden kan disse være objekter af forskellige typer (for eksempel værter, undernet og adresseområder). Dermed kan vores opgave løses inden for rammerne af ét API-kald.

Script ved hjælp af 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 at køre dette script i mit laboratoriemiljø tager fra 3 til 7 sekunder, afhængigt af belastningen på administrationsserveren. Det vil sige, at på 101 API-objekter i gennemsnit kører et batch-type kald 10 gange hurtigere. På et større antal objekter vil forskellen være endnu mere imponerende.

Lad os nu se, hvordan man arbejder med sæt-objekter-batch. Ved at bruge dette API-kald kan vi masseændre enhver parameter. Lad os sætte den første halvdel af adresserne fra det forrige eksempel (op til .124 værter, og områder også) til farven sienna, og tildele farven kaki til den anden halvdel af adresserne.

Ændring af farven på de objekter, der blev oprettet i det foregående 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 et API-kald vha slet-objekter-batch. Lad os nu se på et kodeeksempel, der sletter alle værter, der tidligere er oprettet via tilføje-objekter-batch.

Sletning af objekter ved hjælp af 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 funktioner, der vises i nye udgivelser af Check Point-software, får straks API-kald. I R80.40 dukkede sådanne "funktioner" som Revert to revision og Smart Task op, og tilsvarende API-kald blev straks forberedt til dem. Desuden får al funktionalitet, når du flytter fra ældre konsoller til Unified Policy-tilstand, også API-understøttelse. For eksempel var den længe ventede opdatering i softwareversion R80.40 flytningen af ​​HTTPS-inspektionspolitikken fra Legacy-tilstand til Unified Policy-tilstand, og denne funktionalitet modtog straks API-kald. Her er et eksempel på kode, der tilføjer en regel til den øverste placering af HTTPS-inspektionspolitikken, der udelukker 3 kategorier fra inspektion (sundhed, finans, offentlige tjenester), som er forbudt fra inspektion i overensstemmelse med loven i en række lande.

Føj en regel til HTTPS-inspektionspolitikken

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

Kører Python-scripts på Check Point-administrationsserveren

Alt er det samme README.md indeholder information om, hvordan man kører Python-scripts direkte fra kontrolserveren. Dette kan være praktisk, når du ikke er i stand til at oprette forbindelse til API-serveren fra en anden maskine. Jeg optog en seks minutters video, hvor jeg ser på installationen af ​​modulet cpapi og funktioner til at køre Python-scripts på kontrolserveren. Som et eksempel køres et script, der automatiserer konfigurationen af ​​en ny gateway til en opgave såsom netværksrevision Sikkerhedstjek. Blandt de funktioner, som jeg skulle forholde mig til: Funktionen er endnu ikke dukket op i Python 2.7 indgang, så for at behandle de oplysninger, som brugeren indtaster, bruges en funktion rå_input. Ellers er koden den samme som for lancering fra andre maskiner, kun det er mere praktisk at bruge funktionen login_as_root, for ikke at angive dit eget brugernavn, adgangskode og IP-adresse på administrationsserveren igen.

Script til hurtig opsætning af sikkerhedstjek

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 adgangskodeordbog additional_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

Konklusion

Denne artikel undersøger kun de grundlæggende muligheder for arbejde Python SDK og modul cpapi(som du måske har gættet, er disse faktisk synonymer), og ved at studere koden i dette modul vil du opdage endnu flere muligheder i at arbejde med den. Det er muligt, at du vil supplere det med dine egne klasser, funktioner, metoder og variabler. Du kan altid dele dit arbejde og se andre scripts til Check Point i afsnittet CodeHub i samfundet CheckMates, som samler både produktudviklere og brugere.

God kodning og tak fordi du læste til slutningen!

Kilde: www.habr.com

Tilføj en kommentar