تبسيط واجهة برمجة تطبيقات Check Point باستخدام Python SDK

تبسيط واجهة برمجة تطبيقات Check Point باستخدام Python SDKيتم الكشف عن القوة الكاملة للتفاعل مع واجهات برمجة التطبيقات عند استخدامها مع رمز البرنامج، عندما يصبح من الممكن إنشاء طلبات وأدوات واجهة برمجة التطبيقات ديناميكيًا لتحليل استجابات واجهة برمجة التطبيقات. ومع ذلك، فإنه لا يزال غير ملحوظ مجموعة أدوات تطوير برامج Python (يشار إليها فيما يلي باسم Python SDK) لـ واجهة برمجة تطبيقات إدارة النقاطولكن عبثا. إنه يبسط بشكل كبير حياة المطورين وعشاق الأتمتة. لقد اكتسبت بايثون شعبية هائلة في الآونة الأخيرة وقررت سد الفجوة ومراجعة الميزات الرئيسية. مجموعة تطوير Check Point API Python. هذه المقالة بمثابة إضافة ممتازة لمقال آخر عن حبري تحقق من نقطة R80.10 API. تحكم عبر CLI والنصوص والمزيد. سنلقي نظرة على كيفية كتابة البرامج النصية باستخدام Python SDK ونلقي نظرة فاحصة على وظيفة Management API الجديدة في الإصدار 1.6 (مدعومة بدءًا من R80.40). لفهم المقالة، ستحتاج إلى معرفة أساسية حول العمل مع واجهات برمجة التطبيقات (APIs) وPython.

تعمل Check Point بشكل نشط على تطوير واجهة برمجة التطبيقات (API) وفي الوقت الحالي تم إصدار ما يلي:

يدعم Python SDK حاليًا التفاعل مع Management API و واجهة برمجة تطبيقات غايا. سننظر في أهم الفئات والأساليب والمتغيرات في هذه الوحدة.

تبسيط واجهة برمجة تطبيقات Check Point باستخدام Python SDK

تركيب الوحدة

وحدة com.cpapi يتم تثبيته بسرعة وسهولة من مستودع Check Point الرسمي على جيثب من خلال بذرة. تعليمات التثبيت التفصيلية متوفرة في README.md. تم تكييف هذه الوحدة للعمل مع إصدارات Python 2.7 و3.7. في هذه المقالة، سيتم تقديم أمثلة باستخدام Python 3.7. ومع ذلك، يمكن تشغيل Python SDK مباشرة من Check Point Management Server (الإدارة الذكية)، ولكنها تدعم فقط Python 2.7، لذا سيوفر القسم الأخير رمزًا للإصدار 2.7. مباشرة بعد تثبيت الوحدة، أوصي بالنظر إلى الأمثلة الموجودة في الدلائل example_python2 и example_python3.

الشروع في العمل

لكي نتمكن من العمل مع مكونات وحدة cpapi، نحتاج إلى الاستيراد من الوحدة com.cpapi فئتين مطلوبتين على الأقل:

APIClient и APIClientArgs

from cpapi import APIClient, APIClientArgs

فئة APIClientArgs مسؤول عن معلمات الاتصال بخادم API والفئة APIClient هو المسؤول عن التفاعل مع API.

تحديد معلمات الاتصال

لتحديد معلمات مختلفة للاتصال بواجهة برمجة التطبيقات (API)، تحتاج إلى إنشاء مثيل للفئة APIClientArgs. من حيث المبدأ، يتم تحديد معلماته مسبقًا، وعند تشغيل البرنامج النصي على خادم التحكم، لا يلزم تحديدها.

client_args = APIClientArgs()

ولكن عند التشغيل على مضيف تابع لجهة خارجية، يتعين عليك تحديد عنوان IP أو اسم المضيف على الأقل لخادم واجهة برمجة التطبيقات (المعروف أيضًا باسم خادم الإدارة). في المثال أدناه، نحدد معلمة اتصال الخادم ونخصص لها عنوان IP لخادم الإدارة كسلسلة.

client_args = APIClientArgs(server='192.168.47.241')

دعونا نلقي نظرة على جميع المعلمات وقيمها الافتراضية التي يمكن استخدامها عند الاتصال بخادم API:

وسيطات الأسلوب __init__ لفئة APIClientArgs

class APIClientArgs:
    """
    This class provides arguments for APIClient configuration.
    All the arguments are configured with their default values.
    """

    # port is set to None by default, but it gets replaced with 443 if not specified
    # context possible values - web_api (default) or gaia_api
    def __init__(self, port=None, fingerprint=None, sid=None, server="127.0.0.1", http_debug_level=0,
                 api_calls=None, debug_file="", proxy_host=None, proxy_port=8080,
                 api_version=None, unsafe=False, unsafe_auto_accept=False, context="web_api"):
        self.port = port
        # management server fingerprint
        self.fingerprint = fingerprint
        # session-id.
        self.sid = sid
        # management server name or IP-address
        self.server = server
        # debug level
        self.http_debug_level = http_debug_level
        # an array with all the api calls (for debug purposes)
        self.api_calls = api_calls if api_calls else []
        # name of debug file. If left empty, debug data will not be saved to disk.
        self.debug_file = debug_file
        # HTTP proxy server address (without "http://")
        self.proxy_host = proxy_host
        # HTTP proxy port
        self.proxy_port = proxy_port
        # Management server's API version
        self.api_version = api_version
        # Indicates that the client should not check the server's certificate
        self.unsafe = unsafe
        # Indicates that the client should automatically accept and save the server's certificate
        self.unsafe_auto_accept = unsafe_auto_accept
        # The context of using the client - defaults to web_api
        self.context = context

أعتقد أن الوسائط التي يمكن استخدامها في مثيلات فئة APIClientArgs تعتبر بديهية لمسؤولي Check Point ولا تتطلب تعليقات إضافية.

الاتصال عبر APIClient ومدير السياق

فئة APIClient الطريقة الأكثر ملاءمة لاستخدامها هي من خلال مدير السياق. كل ما يجب تمريره إلى مثيل فئة APIClient هو معلمات الاتصال التي تم تعريفها في الخطوة السابقة.

with APIClient(client_args) as client:

لن يقوم مدير السياق بإجراء مكالمة تسجيل دخول إلى خادم واجهة برمجة التطبيقات (API) تلقائيًا، ولكنه سيقوم بإجراء مكالمة تسجيل خروج عند تسجيل الخروج. إذا لم يكن تسجيل الخروج مطلوبًا لسبب ما بعد الانتهاء من العمل مع استدعاءات واجهة برمجة التطبيقات (API)، فستحتاج إلى بدء العمل دون استخدام مدير السياق:

client = APIClient(clieng_args)

اختبار الاتصال

أسهل طريقة للتحقق مما إذا كان الاتصال يلبي المعلمات المحددة هي استخدام هذه الطريقة check_fingerprint. إذا فشل التحقق من مجموع تجزئة sha1 لبصمة شهادة API للخادم (يتم إرجاع الطريقة خطأ)، فإن هذا عادةً ما يكون بسبب مشاكل في الاتصال ويمكننا إيقاف تنفيذ البرنامج (أو منح المستخدم الفرصة لتصحيح بيانات الاتصال):

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

يرجى ملاحظة أنه في المستقبل الطبقة APIClient سوف يتحقق من كل استدعاء API (methods api_call и api_query، سنتحدث عنها بمزيد من التفصيل) شهادة بصمة sha1 على خادم API. ولكن إذا تم اكتشاف خطأ عند التحقق من بصمة sha1 لشهادة خادم API (الشهادة غير معروفة أو تم تغييرها)، فإن الطريقة check_fingerprint سيوفر الفرصة لإضافة/تغيير المعلومات المتعلقة به على الجهاز المحلي تلقائيًا. يمكن تعطيل هذا التحقق تمامًا (ولكن لا يمكن التوصية بهذا إلا إذا تم تشغيل البرامج النصية على خادم API نفسه، عند الاتصال بـ 127.0.0.1)، باستخدام وسيطة APIClientArgs - unsafe_auto_accept (راجع المزيد حول APIClientArgs سابقًا في "تعريف معلمات الاتصال").

client_args = APIClientArgs(unsafe_auto_accept=True)

تسجيل الدخول إلى خادم API

У APIClient هناك ما يصل إلى 3 طرق لتسجيل الدخول إلى خادم API، وكل منها يفهم المعنى SID(معرف الجلسة)، والذي يتم استخدامه تلقائيًا في كل استدعاء لاحق لواجهة برمجة التطبيقات (API) في الرأس (الاسم الموجود في رأس هذه المعلمة هو X-chkp-sid)، لذلك ليست هناك حاجة لمزيد من معالجة هذه المعلمة.

طريقة تسجيل الدخول

خيار استخدام تسجيل الدخول وكلمة المرور (في المثال، يتم تمرير اسم المستخدم admin وكلمة المرور 1q2w3e كوسائط موضعية):

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

تتوفر أيضًا معلمات اختيارية إضافية في طريقة تسجيل الدخول، وإليك أسمائها وقيمها الافتراضية:

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

طريقة تسجيل الدخول_مع_api_key

خيار باستخدام مفتاح واجهة برمجة التطبيقات (مدعوم بدءًا من إصدار الإدارة R80.40/Management API v1.6، "3TsbPJ8ZKjaJGvFyoFqHFA==" هذه هي قيمة مفتاح API لأحد المستخدمين على خادم الإدارة باستخدام طريقة ترخيص مفتاح API):

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

في الأسلوب تسجيل الدخول_مع_api_key تتوفر نفس المعلمات الاختيارية كما في الطريقة تسجيل الدخول.

طريقة تسجيل الدخول_as_root

خيار تسجيل الدخول إلى جهاز محلي باستخدام خادم API:

     login = client.login_as_root()

لا يوجد سوى معلمتين اختياريتين متاحتين لهذه الطريقة:

domain=None, payload=None

وأخيرًا، تطلق واجهة برمجة التطبيقات (API) على نفسها اسمًا

لدينا خياران لإجراء مكالمات API من خلال الطرق api_call и api_query. دعونا معرفة ما هو الفرق بينهما.

api_call

هذه الطريقة قابلة للتطبيق على أي مكالمات. نحتاج إلى تمرير الجزء الأخير لاستدعاء واجهة برمجة التطبيقات والحمولة في نص الطلب إذا لزم الأمر. إذا كانت الحمولة فارغة، فلا يمكن إرسالها على الإطلاق:

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

إخراج هذا الطلب أسفل القطع:

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

إخراج هذا الطلب أسفل القطع:

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

اسمحوا لي أن أحجز على الفور أن هذه الطريقة قابلة للتطبيق فقط على المكالمات التي تتضمن مخرجاتها إزاحة. يحدث مثل هذا الاستدلال عندما يحتوي أو قد يحتوي على كمية كبيرة من المعلومات. على سبيل المثال، قد يكون هذا طلبًا للحصول على قائمة بجميع الكائنات المضيفة التي تم إنشاؤها على خادم الإدارة. بالنسبة لمثل هذه الطلبات، تقوم واجهة برمجة التطبيقات (API) بإرجاع قائمة مكونة من 50 كائنًا بشكل افتراضي (يمكنك زيادة الحد الأقصى إلى 500 كائن في الاستجابة). ولكي لا يتم سحب المعلومات عدة مرات، قم بتغيير معلمة الإزاحة في طلب API، هناك طريقة api_query تقوم بهذا العمل تلقائيًا. أمثلة على المكالمات التي تتطلب هذه الطريقة: جلسات العرض، عرض المضيفين، عرض الشبكات، عرض أحرف البدل، عرض المجموعات، عرض نطاقات العناوين، عرض البوابات البسيطة، عرض المجموعات البسيطة، إظهار أدوار الوصول، إظهار العملاء الموثوق بهم، عرض الحزم. في الواقع، نرى كلمات جمع في اسم استدعاءات واجهة برمجة التطبيقات هذه، لذلك سيكون التعامل مع هذه الاستدعاءات أسهل api_query

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

إخراج هذا الطلب أسفل القطع:

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

بعد ذلك يمكنك استخدام المتغيرات والأساليب الخاصة بالفئة استجابة API(سواء داخل مدير السياق أو خارجه). في الفصل استجابة API تم تحديد 4 طرق و5 متغيرات مسبقًا، وسنتناول أهمها بمزيد من التفصيل.

تبسيط واجهة برمجة تطبيقات Check Point باستخدام Python SDK

تحقيق النجاح

في البداية، سيكون من الجيد التأكد من نجاح استدعاء واجهة برمجة التطبيقات (API) وإرجاع النتيجة. هناك طريقة لهذا تحقيق النجاح :

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

يُرجع True إذا كان استدعاء API ناجحًا (رمز الاستجابة - 200) ويعيد خطأ إذا لم يكن ناجحًا (أي رمز استجابة آخر). من الملائم استخدامه فورًا بعد استدعاء واجهة برمجة التطبيقات (API) لعرض معلومات مختلفة اعتمادًا على رمز الاستجابة.

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

كود الحالة

إرجاع رمز الاستجابة بعد إجراء استدعاء API.

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

رموز الاستجابة المحتملة: 200,400,401,403,404,409,500,501.

set_success_status

في هذه الحالة، قد يكون من الضروري تغيير قيمة حالة النجاح. من الناحية الفنية، يمكنك وضع أي شيء هناك، حتى سلسلة عادية. لكن المثال الحقيقي هو إعادة تعيين هذه المعلمة إلى False في ظل ظروف مصاحبة معينة. أدناه، انتبه إلى المثال عندما تكون هناك مهام قيد التشغيل على خادم الإدارة، ولكننا سنعتبر هذا الطلب غير ناجح (سنقوم بتعيين متغير النجاح على خطأ، على الرغم من نجاح استدعاء واجهة برمجة التطبيقات (API) وإرجاع الرمز 200).

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

إجابة()

تتيح لك طريقة الاستجابة عرض القاموس مع رمز الاستجابة (status_code) ونص الاستجابة (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']}}

البيانات

يسمح لك برؤية نص الاستجابة (النص) فقط دون معلومات غير ضرورية.

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

رسالة خطأ

تتوفر هذه المعلومات فقط عند حدوث خطأ أثناء معالجة طلب واجهة برمجة التطبيقات (رمز الاستجابة لا 200). مثال الإخراج

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

أمثلة مفيدة

فيما يلي الأمثلة التي تستخدم استدعاءات API التي تمت إضافتها في Management API 1.6.

أولاً، دعونا نلقي نظرة على كيفية عمل المكالمات إضافة مضيف и إضافة نطاق العنوان. لنفترض أننا بحاجة إلى إنشاء جميع عناوين IP للشبكة الفرعية 192.168.0.0/24، آخر ثماني بتات منها هي 5، ككائنات من نوع المضيف، وكتابة جميع عناوين IP الأخرى ككائنات من نوع نطاق العناوين. في هذه الحالة، استبعاد عنوان الشبكة الفرعية وعنوان البث.

لذا، يوجد أدناه برنامج نصي يحل هذه المشكلة وينشئ 50 كائنًا من نوع المضيف و51 كائنًا من نوع نطاق العناوين. لحل المشكلة، يلزم إجراء 101 استدعاء لواجهة برمجة التطبيقات (بدون احتساب استدعاء النشر النهائي). أيضًا، باستخدام وحدة timeit، نحسب الوقت الذي يستغرقه تنفيذ البرنامج النصي حتى يتم نشر التغييرات.

البرنامج النصي باستخدام إضافة المضيف ونطاق العنوان الإضافي

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

في بيئة معملي، يستغرق تنفيذ هذا البرنامج النصي ما بين 30 إلى 50 ثانية، اعتمادًا على التحميل الموجود على خادم الإدارة.

الآن دعونا نرى كيفية حل نفس المشكلة باستخدام استدعاء API إضافة كائنات دفعة، والذي تمت إضافة الدعم له في إصدار API 1.6. يتيح لك هذا الاستدعاء إنشاء العديد من الكائنات مرة واحدة في طلب API واحد. علاوة على ذلك، يمكن أن تكون هذه كائنات من أنواع مختلفة (على سبيل المثال، المضيفين والشبكات الفرعية ونطاقات العناوين). وبالتالي، يمكن حل مهمتنا في إطار استدعاء API واحد.

البرنامج النصي باستخدام 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')

ويستغرق تشغيل هذا البرنامج النصي في بيئة معملي من 3 إلى 7 ثوانٍ، اعتمادًا على التحميل الموجود على خادم الإدارة. أي، في المتوسط، على 101 كائن API، يتم تشغيل استدعاء النوع الدفعي بشكل أسرع 10 مرات. وفي عدد أكبر من الكائنات، سيكون الفرق أكثر إثارة للإعجاب.

الآن دعونا نرى كيفية العمل مع مجموعة الكائنات دفعة. باستخدام استدعاء API هذا، يمكننا تغيير أي معلمة بشكل مجمّع. لنقم بتعيين النصف الأول من العناوين من المثال السابق (ما يصل إلى .124 مضيفًا، والنطاقات أيضًا) إلى اللون سيينا، وقم بتعيين اللون الكاكي للنصف الثاني من العناوين.

تغيير لون الكائنات التي تم إنشاؤها في المثال السابق

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

يمكنك حذف كائنات متعددة في استدعاء API واحد باستخدام حذف الكائنات دفعة. الآن دعونا نلقي نظرة على مثال التعليمات البرمجية الذي يحذف جميع المضيفات التي تم إنشاؤها مسبقًا عبر إضافة كائنات دفعة.

حذف الكائنات باستخدام دفعة حذف الكائنات

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)

جميع الوظائف التي تظهر في الإصدارات الجديدة من برنامج Check Point تحصل فورًا على مكالمات API. وهكذا، في R80.40 ظهرت "ميزات" مثل "الرجوع إلى المراجعة" و"المهمة الذكية"، وتم إعداد استدعاءات واجهة برمجة التطبيقات (API) المقابلة لها على الفور. علاوة على ذلك، فإن جميع الوظائف عند الانتقال من وحدات التحكم القديمة إلى وضع السياسة الموحدة تحصل أيضًا على دعم واجهة برمجة التطبيقات. على سبيل المثال، كان التحديث الذي طال انتظاره في إصدار البرنامج R80.40 هو نقل سياسة فحص HTTPS من الوضع القديم إلى وضع السياسة الموحدة، وقد تلقت هذه الوظيفة على الفور استدعاءات واجهة برمجة التطبيقات (API). فيما يلي مثال للكود الذي يضيف قاعدة إلى الموضع العلوي لسياسة فحص HTTPS والتي تستثني 3 فئات من التفتيش (الصحة والمالية والخدمات الحكومية)، والتي يحظر عليها التفتيش وفقًا للقانون في عدد من البلدان.

أضف قاعدة إلى سياسة فحص HTTPS

from cpapi import APIClient, APIClientArgs

client_args = APIClientArgs(server="192.168.47.240")

data = {
  "layer" : "Default Layer",
  "position" : "top",
  "name" : "Legal Requirements",
  "action": "bypass",
  "site-category": ["Health", "Government / Military", "Financial Services"]
}

with APIClient(client_args) as client: 
     login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
     add_https_rule = client.api_call("add-https-rule", data)
     publish = client.api_call("publish")

تشغيل برامج Python النصية على خادم إدارة Check Point

كل شيء متشابه README.md يحتوي على معلومات حول كيفية تشغيل البرامج النصية لبايثون مباشرة من خادم التحكم. قد يكون هذا مناسبًا عندما لا تتمكن من الاتصال بخادم API من جهاز آخر. لقد سجلت مقطع فيديو مدته ست دقائق ألقي فيه نظرة على تثبيت الوحدة com.cpapi ومميزات تشغيل برامج بايثون النصية على خادم التحكم. على سبيل المثال، يتم تشغيل برنامج نصي يقوم بأتمتة تكوين البوابة الجديدة لمهمة مثل تدقيق الشبكة فحص الأمان. ومن بين الميزات التي كان علي التعامل معها: الوظيفة لم تظهر بعد في Python 2.7 إدخال، لمعالجة المعلومات التي يدخلها المستخدم، يتم استخدام وظيفة المدخلات الخام. بخلاف ذلك، يكون الرمز هو نفسه المستخدم في التشغيل من الأجهزة الأخرى، ولكنه أكثر ملاءمة لاستخدام الوظيفة تسجيل الدخول_as_root، حتى لا تحدد اسم المستخدم وكلمة المرور وعنوان IP الخاص بخادم الإدارة مرة أخرى.

برنامج نصي للإعداد السريع لفحص الأمان

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

ملف مثال مع قاموس كلمة المرور extra_pass.conf
{
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"] }

اختتام

تتناول هذه المقالة فقط الإمكانيات الأساسية للعمل بايثون SDK والوحدة النمطية com.cpapi(كما قد تكون خمنت، هذه في الواقع مرادفات)، ومن خلال دراسة الكود الموجود في هذه الوحدة، ستكتشف المزيد من الفرص للعمل معها. من الممكن أنك سوف ترغب في استكماله بالفئات والوظائف والأساليب والمتغيرات الخاصة بك. يمكنك دائمًا مشاركة عملك وعرض البرامج النصية الأخرى لـ Check Point في القسم CodeHub في المجتمع CheckMates، والذي يجمع بين مطوري المنتجات والمستخدمين.

ترميز سعيد وشكرا للقراءة حتى النهاية!

المصدر: www.habr.com

إضافة تعليق