Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
django-defender — एक सरल, अत्यधिक तेज़ Django पुन: प्रयोज्य ऐप जो लोगों को लॉगिन प्रयासों को ब्रूट फोर्स करने से रोकता है। | Kitploit
उपकरण/GitHubGitHub/jazzband/django-defender
रक्षात्मक उपकरणपासवर्ड हमलेवेब सुरक्षाप्रमाणीकरण
GitHubjazzband/django-defender

django-defender

एक सरल, अत्यधिक तेज़ Django पुन: प्रयोज्य ऐप जो लोगों को लॉगिन प्रयासों को ब्रूट फोर्स करने से रोकता है।

रिपॉजिटरी देखें
1.1k1446 महीने पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

django-defender

.. image:: https://jazzband.co/static/img/badge.svg :target: https://jazzband.co/ :alt: Jazzband

.. image:: https://img.shields.io/pypi/pyversions/django-defender.svg :alt: Supported Python versions :target: https://pypi.org/project/django-defender/

.. image:: https://img.shields.io/pypi/djversions/django-defender.svg :target: https://pypi.org/project/django-defender/ :alt: Supported Django versions

.. image:: https://github.com/jazzband/django-defender/workflows/Test/badge.svg :target: https://github.com/jazzband/django-defender/actions :alt: GitHub Actions

.. image:: https://codecov.io/gh/jazzband/django-defender/branch/master/graph/badge.svg :target: https://codecov.io/gh/jazzband/django-defender :alt: Coverage

.. image:: https://readthedocs.org/projects/django-defender/badge/?version=latest :alt: Documentation Status :target: https://django-defender.readthedocs.io/en/latest/?badge=latest

एक सरल Django पुन: प्रयोज्य ऐप जो लोगों को ब्रूट-फोर्सिंग लॉगिन प्रयासों से रोकता है। लक्ष्य इसे यथासंभव तेज़ बनाना है, ताकि लॉगिन प्रयासों को धीमा न किया जाए।

हम एक कैश का उपयोग करेंगे ताकि प्रत्येक लॉगिन प्रयास पर डेटाबेस को हिट न करना पड़े। पहला संस्करण Redis पर आधारित होगा, लेकिन लक्ष्य इसे कॉन्फ़िगरेबल बनाना है ताकि लोग अपनी आवश्यकताओं के अनुसार कोई भी बैकएंड उपयोग कर सकें।

django-defender का उपयोग करने वाली साइटें

यदि आप अपनी साइट पर defender का उपयोग कर रहे हैं, तो सूची में जोड़ने के लिए PR सबमिट करें।

  • https://hub.docker.com
  • https://www.mycosbuilder.com

दस्तावेज़ीकरण

दस्तावेज़ीकरण Read the Docs पर उपलब्ध है:

https://django-defender.readthedocs.io

विशेषताएँ

  • सभी लॉगिन प्रयासों को डेटाबेस में लॉग करें

  • IP पतों के लिए विभिन्न हेडर वाले रिवर्स प्रॉक्सी के लिए समर्थन

  • आधारित दर सीमा

    • उपयोगकर्ता नाम
    • IP पता
  • ब्लैकलिस्ट के लिए Redis का उपयोग करें

  • कॉन्फ़िगरेशन

    • Redis सर्वर

      • होस्ट
      • पोर्ट
      • डेटाबेस
      • पासवर्ड
      • कुंजी उपसर्ग
    • ब्लॉक अवधि

    • ब्लॉक से पहले गलत प्रयासों की संख्या

  • 95% कोड कवरेज

  • पूर्ण दस्तावेज़ीकरण

  • लॉगिन प्रयासों को डेटाबेस में संग्रहीत करने की क्षमता

  • लॉगिन प्रयास डेटाबेस तालिका को साफ करने के लिए प्रबंधन कमांड

  • प्रशासन पृष्ठ

    • अवरुद्ध उपयोगकर्ता नामों और IP पतों की सूची
    • हाल के लॉगिन प्रयासों की सूची
    • लोगों को अनब्लॉक करने की क्षमता
  • कस्टम प्रमाणीकरण विधि में आसानी से अनुकूलित किया जा सकता है।

  • उपयोगकर्ता नाम या IP को ब्लॉक करने पर सिग्नल भेजे जाते हैं

प्रशासन पृष्ठ


.. image:: https://cloud.githubusercontent.com/assets/261601/5950540/8895b570-a729-11e4-9dc3-6b00e46c8043.png :target: https://cloud.githubusercontent.com/assets/261601/5950540/8895b570-a729-11e4-9dc3-6b00e46c8043.png :alt: alt tag

.. image:: https://cloud.githubusercontent.com/assets/261601/5950541/88a35194-a729-11e4-981b-3a55b44ef9d5.png :target: https://cloud.githubusercontent.com/assets/261601/5950541/88a35194-a729-11e4-981b-3a55b44ef9d5.png :alt: alt tag

आवश्यकताएँ

  • Python: 3.8, 3.9, 3.10, 3.11, 3.12, PyPy
  • Django: 3.2, 4.2, 5.0, 5.1, 5.2
  • Redis: 5.x, 6.x, 7.x

स्थापना

कोड डाउनलोड करें, और विधि के अनुसार निम्नलिखित में से किसी एक तरीके से सेटअप चलाएं।

PyPI से उत्पादन-तैयार संस्करण स्थापित करने के लिए:

.. code-block:: bash

pip install django-defender

स्रोत कोड से डाउनलोड करने के बाद विकास संस्करण स्थापित करने के लिए:

.. code-block:: bash

python setup.py install

GitHub रिपॉजिटरी से मास्टर शाखा विकास संस्करण स्थापित करने के लिए:

.. code-block:: bash

pip install -e git+http://github.com/kencochran django-defender.git#egg=django_defender-dev

सबसे पहले, आपको इस प्रोजेक्ट को अपनी settings.py में INSTALLED_APPS की सूची में जोड़ना होगा।

.. code-block:: python

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', # ... 'defender', # ... ]

इसके बाद, FailedLoginMiddleware मिडलवेयर स्थापित करें।

.. code-block:: python

MIDDLEWARE_CLASSES = [ 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'defender.middleware.FailedLoginMiddleware', ]

यदि आप Django प्रशासन के माध्यम से अवरुद्ध उपयोगकर्ताओं का प्रबंधन करना चाहते हैं, तो अपनी urls.py में निम्नलिखित जोड़ें।

.. code-block:: python

urlpatterns = [ path('admin/defender/', include('defender.urls')), # defender admin path('admin/', admin.site.urls), # normal admin # your own patterns follow... ]

माइग्रेशन


आपको अपने डेटाबेस में संचालन के लिए आवश्यक तालिकाएँ बनानी होंगी।

.. code-block:: bash

python manage.py migrate defender

प्रबंधन कमांड


cleanup_django_defender

यदि आपकी वेबसाइट पर बहुत अधिक ट्रैफ़िक है, तो AccessAttempts तालिका जल्दी भर जाएगी। यदि आपको ऑडिटिंग उद्देश्यों के लिए डेटा रखने की आवश्यकता नहीं है, तो इसे साफ रखने में मदद करने के लिए एक प्रबंधन कमांड है।

यह यह निर्धारित करने के लिए आपकी DEFENDER_ACCESS_ATTEMPT_EXPIRATION सेटिंग को देखेगा कि कौन से रिकॉर्ड हटाए जाएंगे। यदि निर्दिष्ट नहीं किया गया है, तो डिफ़ॉल्ट 24 घंटे है।

.. code-block:: bash

$ python manage.py cleanup_django_defender

आप इसे तालिका का आकार कम रखने के लिए दैनिक या साप्ताहिक क्रॉन जॉब के रूप में सेट कर सकते हैं।

.. code-block:: bash

रोज़ सुबह 12:24 बजे चलाएं।

24 0 * * * /usr/bin/python manage.py cleanup_django_defender >> /var/log/django_defender_cleanup.log

दीर्घकालिक लक्ष्य

  • प्लग करने योग्य बैकएंड, ताकि लोग Redis के अलावा कुछ और उपयोग कर सकें
  • जब उनका खाता अवरुद्ध हो तो उपयोगकर्ताओं को ईमेल करें
  • उपयोगकर्ता नाम और IP के लिए एक श्वेतसूची जोड़ें जिन्हें हम कभी ब्लॉक नहीं करेंगे (प्रशासक, आदि)
  • IP पतों के लिए एक स्थायी ब्लैकलिस्ट जोड़ें
  • ज्ञात प्रॉक्सी IP के लिए स्कैन करें और उन अनुरोधों को ब्लॉक न करें जो उनसे आते हैं (एक अच्छे IP के ब्लॉक होने की संभावना में सुधार)
  • पुराने (कॉन्फ़िगरेबल) लॉगिन प्रयासों को हटाने के लिए प्रबंधन कमांड जोड़ें।

प्रदर्शन


defender का लक्ष्य इसे यथासंभव तेज़ बनाना है ताकि लॉगिन प्रक्रिया धीमी न हो। यह सुनिश्चित करने के लिए कि हमारे लक्ष्य पूरे हो रहे हैं, हमें एप्लिकेशन का परीक्षण करने का एक तरीका चाहिए ताकि यह सुनिश्चित हो सके कि हम सही रास्ते पर हैं। ऐसा करने का सबसे अच्छा तरीका यह तुलना करना है कि सामान्य Django लॉगिन defender और django-axes के साथ कितनी तेज़ी से होता है।

सामान्य Django लॉगिन हमारा आधार रेखा होगी, और हम उम्मीद करते हैं कि यह तीनों विधियों में सबसे तेज़ होगी, क्योंकि कोई अतिरिक्त जाँच नहीं हो रही है।

defender लॉगिन संभवतः Django लॉगिन से धीमा होगा, और उम्मीद है कि django-axes लॉगिन से तेज़ होगा। लक्ष्य सामान्य रॉ लॉगिन और defender के बीच जितना संभव हो उतना कम अंतर रखना है।

django-axes लॉगिन गति संभवतः तीनों में सबसे धीमी होगी क्योंकि यह अधिक जाँच करता है और बहुत सारे डेटाबेस क्वेरी करता है।

लॉगिन की गति निर्धारित करने का सबसे अच्छा तरीका प्रत्येक सेटअप के साथ एक एप्लिकेशन के विरुद्ध लोड परीक्षण करना और प्रत्येक प्रकार के लॉगिन समय की तुलना करना है।

लोड परीक्षण


यह सुनिश्चित करने के लिए कि हम सभी विभिन्न प्रकार के लॉगिन को कवर करते हैं, हमारे लोड परीक्षण में एक से अधिक परीक्षण होने चाहिए।

#. सभी सफल: हम केवल सफल लॉगिन के साथ एक लोड परीक्षण करेंगे।

#. मिश्रित: कुछ सफल कुछ असफल: हम कुछ सफल लॉगिन और कुछ असफलताओं के साथ लोड परीक्षण करेंगे ताकि देख सकें कि असफलता प्रदर्शन को कैसे प्रभावित करती है।

#. सभी असफलताएँ: हम सभी असफल लॉगिन के साथ लोड परीक्षण करेंगे और प्रदर्शन में अंतर देखेंगे।

हमें एक नमूना एप्लिकेशन की आवश्यकता होगी जिसका उपयोग हम लोड परीक्षण के लिए कर सकें, जिसमें एकमात्र अंतर कॉन्फ़िगरेशन है जहाँ हम defender, axes, या उनमें से कोई भी लोड करते हैं।

हम एक होस्टेड लोड परीक्षण सेवा, या jmeter जैसी किसी चीज़ का उपयोग कर सकते हैं। किसी भी तरह, हमें सभी परीक्षणों के लिए सुसंगत रहना होगा। यदि हम jmeter का उपयोग करते हैं, तो हमारे पास दूसरों के लिए अपने परीक्षण चलाने के लिए हमारा jmeter कॉन्फ़िगरेशन होना चाहिए।

लोड परीक्षणों के परिणाम


हम परिणाम यहाँ पोस्ट करेंगे। हम प्रत्येक परीक्षण की व्याख्या करेंगे, और कुछ चार्ट के साथ परिणाम दिखाएंगे।

django-axes क्यों नहीं

django-axes बहुत अच्छा है लेकिन यह सब कुछ डेटाबेस में रखता है, और जब आपके पास बहुत सारा डेटा होता है तो यह एक अड़चन का कारण बनता है। यह प्रमाणीकरण अनुरोधों को 200-300ms तक धीमा कर देता है। यह कुछ साइटों के लिए बहुत अधिक नहीं हो सकता है, लेकिन दूसरों के लिए यह बहुत लंबा है।

यह django-axes के एक फोर्क के रूप में शुरू हुआ, और उनके जितना संभव हो उतना कोड का उपयोग कर रहा है, और अनावश्यक भागों को हटा रहा है, और लॉगिन में सुधार करने के लिए लुकअप को तेज़ कर रहा है।

django-defender कैसे काम करता है

#. जब कोई लॉगिन करने का प्रयास करता है, तो हम पहले जाँचते हैं कि क्या वे वर्तमान में अवरुद्ध हैं। हम उपयोगकर्ता नाम की जाँच करते हैं जिसका वे उपयोग करने का प्रयास कर रहे हैं, साथ ही IP पता भी। यदि वे अवरुद्ध हैं, तो चरण 5 पर जाएँ। यदि अवरुद्ध नहीं हैं, तो चरण 2 पर जाएँ।

#. वे अवरुद्ध नहीं हैं, इसलिए हम जाँचते हैं कि क्या लॉगिन मान्य था। यदि मान्य है, तो चरण 6 पर जाएँ। यदि मान्य नहीं है, तो चरण 3 पर जाएँ।

#. लॉगिन प्रयास मान्य नहीं था। इस प्रयास के लिए उनके उपयोगकर्ता नाम और IP पते को कैश में जोड़ें। यदि यह उन्हें सीमा से अधिक ले जाता है, तो उन्हें अवरुद्ध सूची में जोड़ें, और फिर चरण 5 पर जाएँ। यदि सीमा से अधिक नहीं है, तो चरण 4 पर जाएँ।

#. लॉगिन अमान्य था, लेकिन सीमा से अधिक नहीं। उन्हें पुनः प्रयास करने के लिए लॉगिन स्क्रीन पर वापस भेजें।

#. उपयोगकर्ता अवरुद्ध है: उन्हें अवरुद्ध पृष्ठ पर भेजें, उन्हें बताएं कि वे अवरुद्ध हैं, और अनुमानित समय दें कि वे कब अनब्लॉक होंगे।

#. लॉगिन मान्य है। किसी भी असफल लॉगिन प्रयास को रीसेट करें, और उनके गंतव्य पर अग्रेषित करें।

कैश बैकएंड

Defender असफल प्रयासों को सहेजने के लिए कैश का उपयोग करता है।

कैश कुंजियाँ


काउंटर:

  • prefix:failed:ip:[ip] (count, TTL)
  • prefix:failed:username:[username] (count, TTL)

बूलियन (यदि मौजूद है तो अवरुद्ध है):

  • prefix:blocked:ip:[ip] (true, TTL)
  • prefix:blocked:username:[username] (true, TTL)

django-defender को अनुकूलित करना

आपके पास django-defender को थोड़ा अनुकूलित करने के लिए कुछ विकल्प उपलब्ध हैं। इन्हें आपकी settings.py फ़ाइल में परिभाषित किया जाना चाहिए।

  • DEFENDER_LOGIN_FAILURE_LIMIT\ : Int: असफल लॉगिन के लिए रिकॉर्ड बनाए जाने से पहले अनुमत लॉगिन प्रयासों की संख्या। [डिफ़ॉल्ट: 3\ ]

  • DEFENDER_LOGIN_FAILURE_LIMIT_USERNAME\ : Int: उपयोगकर्ता नाम पर असफल लॉगिन के लिए रिकॉर्ड बनाए जाने से पहले अनुमत लॉगिन प्रयासों की संख्या। [डिफ़ॉल्ट: DEFENDER_LOGIN_FAILURE_LIMIT\ ]

  • DEFENDER_LOGIN_FAILURE_LIMIT_IP\ : Int: एक IP से असफल लॉगिन के लिए रिकॉर्ड बनाए जाने से पहले अनुमत लॉगिन प्रयासों की संख्या। [डिफ़ॉल्ट: DEFENDER_LOGIN_FAILURE_LIMIT\ ]

  • DEFENDER_BEHIND_REVERSE_PROXY\ : Boolean: क्या defender रिवर्स प्रॉक्सी के पीछे है? [डिफ़ॉल्ट: False\ ]

  • DEFENDER_REVERSE_PROXY_HEADER\ : String: आपके रिवर्स प्रॉक्सी IP पते के साथ http हेडर का नाम [डिफ़ॉल्ट: HTTP_X_FORWARDED_FOR\ ]

  • DEFENDER_LOCK_OUT_BY_IP_AND_USERNAME\ : Boolean: IP और उपयोगकर्ता नाम के संयोजन के आधार पर उपयोगकर्ता को लॉक आउट करता है। यह एक उपयोगकर्ता को उसी IP पते के पीछे से ऐप तक पहुँचने वाले अन्य सभी उपयोगकर्ताओं के लिए एप्लिकेशन तक पहुँच से वंचित करने से रोकता है। [डिफ़ॉल्ट: \ ]

DEFENDER_ATTEMPT_COOLOFF_TIME और DEFENDER_LOCKOUT_COOLOFF_TIME का उपयोग करने का तर्क


जबकि अकेले DEFENDER_COOLOFF_TIME का उपयोग अधिकांश उपयोग मामलों के लिए पर्याप्त है, defender का उपयोग कुछ विशिष्ट परिदृश्यों जैसे उच्च सुरक्षा सेटिंग में करते समय, डेवलपर्स अधिक सूक्ष्म नियंत्रण चाह सकते हैं कि लॉकआउट के लिए विचाराधीन रहने के दौरान अमान्य लॉगिन प्रयासों को कितने समय तक "याद" रखा जाए, जबकि उन लॉकआउट कुंजियों को सिस्टम से वास्तव में लॉक आउट करने के समय की तुलना में। DEFENDER_ATTEMPT_COOLOFF_TIME और DEFENDER_LOCKOUT_COOLOFF_TIME इस सटीक सूक्ष्म कॉन्फ़िगरेशन की अनुमति देते हैं।

हम एक निम्न सुरक्षा और निम्न पैमाने के उदाहरण पर भी विचार कर सकते हैं जैसे एक हाई स्कूल की वेबसाइट। ऐसी वेबसाइट स्कूल के कुछ कंप्यूटरों पर चल सकती है और स्कूल के आईटी स्टाफ और कंप्यूटर विज्ञान शिक्षकों (यदि भाग्यशाली हैं तो) द्वारा प्रशासित हो सकती है। इस परिदृश्य में हम कल्पना कर सकते हैं कि वेबसाइट के महत्वपूर्ण हिस्से प्रमाणीकरण के बिना पहुँच योग्य हैं, लेकिन वेबसाइट में लॉग इन करने से कुछ अपेक्षाकृत विशेषाधिकार प्राप्त जानकारी जैसे छात्र का नाम, ईमेल, ग्रेड और क्लास शेड्यूल तक पहुँच मिल सकती है। अंत में चूंकि खाते के साथ एक ईमेल जुड़ा हुआ है, हम मान लेंगे कि पासवर्ड रीसेट कार्यक्षमता है जो पूरा होने पर खाते को अनब्लॉक कर देती है। ऐसे मामले में, कोई कल्पना कर सकता है कि लंबे समय तक असफल लॉगिन को याद रखने की कोई आवश्यकता नहीं है क्योंकि एप्लिकेशन केवल संभावित सेवा से इनकार हमलों से बचाना चाहेगा। इसे DEFENDER_ATTEMPT_COOLOFF_TIME कम रखकर, मान लीजिए 30 सेकंड, और DEFENDER_LOCKOUT_COOLOFF_TIME को बहुत अधिक जैसे 600 सेकंड पर सेट करके प्राप्त किया जा सकता है। DEFENDER_ATTEMPT_COOLOFF_TIME कम रखकर और DEFENDER_LOCKOUT_COOLOFF_TIME अधिक सेट करके बुरे अभिनेताओं को महत्वपूर्ण अवधि के लिए लॉकआउट करके, तेज़ ब्रूट फोर्स लॉगिन हमले अभी भी विफल होंगे और उनके छोटे सर्वर के पास अपने कैश में अन्य डेटा के लिए अधिक स्थान होगा। और ऊपर वर्णित पासवर्ड रीसेट कार्यक्षमता प्रदान करके, ये काल्पनिक प्रशासक वास्तविक उपयोगकर्ताओं को अनब्लॉक करने में अपनी आवश्यक भागीदारी को सीमित कर सकते हैं जबकि अपनी वेबसाइट की इच्छित पहुँच क्षमता बनाए रख सकते हैं।

जबकि पिछला उदाहरण कुछ हद तक काल्पनिक है, इन कॉन्फ़िगरेशन की पूरी शक्ति निम्नलिखित स्पष्टीकरण और उदाहरण के साथ प्रदर्शित की गई है।

जब DEFENDER_STORE_ACCESS_ATTEMPTS True है, तो DEFENDER_LOCKOUT_COOLOFF_TIME को पूर्णांकों की सूची के रूप में भी कॉन्फ़िगर किया जा सकता है। जब एक सूची के रूप में कॉन्फ़िगर किया जाता है, तो कॉन्फ़िगर की गई लॉकआउट कुंजी के लिए पिछले असफल लॉगिन प्रयासों की संख्या को DEFENDER_LOGIN_FAILURE_LIMIT से विभाजित किया जाता है ताकि DEFENDER_ACCESS_ATTEMPT_EXPIRATION द्वारा परिभाषित अवधि के लिए असफल लॉगिन की संख्या का जानबूझकर अधिक अनुमान लगाया जा सके। यह एक अधिक अनुमान बन जाता है क्योंकि इस गणना को करते समय असफल लॉगिन प्रयासों के बीच के समय पर विचार नहीं किया जाता है। हालाँकि यह कठोर लग सकता है, कुछ विशिष्ट परिदृश्यों में धीमे हमलों के खिलाफ अतिरिक्त सुरक्षा सिस्टम के वास्तविक उपयोगकर्ताओं को होने वाली संभावित असुविधा के लायक हो सकती है।

इसका एक ऐसा उदाहरण एक सार्वजनिक वेब सुलभ वेब एप्लिकेशन हो सकता है जो अपने उपयोगकर्ताओं की संवेदनशील जानकारी (मान लीजिए व्यक्तिगत वित्तीय रिकॉर्ड) रखता है। एप्लिकेशन और उसमें मौजूद डेटा न्यूनतम रुकावट के साथ सुलभ होना चाहिए, हालाँकि सुरक्षा अभिन्न है इसलिए देरी को एक बिंदु तक सहन किया जा सकता है। इन परिस्थितियों में हम अधिकतम सुरक्षा के लिए DEFENDER_COOLOFF_TIME को बहुत बड़े पूर्णांक या 0 पर सेट करने की इच्छा कर सकते हैं। लेकिन इसका मतलब यह होगा कि यदि कोई वास्तविक उपयोगकर्ता सिस्टम से लॉक आउट हो जाता है, तो हमें उन्हें मैन्युअल रूप से अनब्लॉक करने के लिए एक प्रशासक की आवश्यकता होगी जो निश्चित रूप से बोझिल और महंगा है। DEFENDER_ATTEMPT_COOLOFF_TIME को पर्याप्त बड़ी संख्या पर सेट करके, मान लीजिए 600, और DEFENDER_LOCKOUT_COOLOFF_TIME को बढ़ते पूर्णांकों की सूची (जैसे [60, 120, 300, 600, 0]) पर सेट करके, हम अपने सैद्धांतिक एप्लिकेशन की तुलना में संरक्षित कर सकते हैं यदि हमने केवल DEFENDER_COOLOFF_TIME को 600 पर सेट किया होता, जबकि अपने उपयोगकर्ताओं को काफी कम बाधित करते हैं।

अन्य प्रमाणीकरण विधियों के लिए अनुकूलन

defender का उपयोग Django प्रमाणीकरण प्रणाली के अलावा अन्य प्रमाणीकरण के लिए किया जा सकता है। उदाहरण के लिए, यदि django-rest-framework प्रमाणीकरण को ब्रूट-फोर्स हमले से संरक्षित करना है, तो एक कस्टम प्रमाणीकरण विधि लागू की जा सकती है।

djangorestframework.BasicAuthentication पर आधारित नमूना BasicAuthenticationDefender वर्ग यहाँ दिया गया है:

.. code-block:: python

import base64 import binascii

from django.utils.translation import gettext_lazy as _

from rest_framework import HTTP_HEADER_ENCODING, exceptions from rest_framework.authentication import ( BasicAuthentication, get_authorization_header, )

from defender import utils from defender import config

class BasicAuthenticationDefender(BasicAuthentication):इसे काम करने के लिए BasicAuthenticationDefender को अपने settings.py में अन्य सभी प्रमाणीकरण विधियों से ऊपर DEFAULT_AUTHENTICATION_CLASSES में जोड़ें।

अन्य प्रमाणीकरण विधियों के अनुकूल होना :- djangorestframework में django-rest-auth

defender को django-rest-framework और django-rest-auth के संयोजन के साथ शामिल किया जा सकता है, जिसका उपयोग उपयोगकर्ताओं को प्रमाणित करने के लिए किया जा सकता है।

संदर्भ


  • https://www.django-rest-framework.org/
  • https://django-rest-auth.readthedocs.io/en/latest/

नीचे rest_framework.authentication.TokenAuthentication पर आधारित एक नमूना BasicAuthenticationDefender वर्ग दिया गया है, जो उपयोगकर्ता प्रमाणीकरण के लिए django-rest-auth लाइब्रेरी का उपयोग करता है।

.. code-block:: python

import base64 import binascii

from django.conf import settings from django.contrib.auth import get_user_model, authenticate from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm from django.contrib.auth.tokens import default_token_generator from django.utils.http import urlsafe_base64_decode as uid_decoder from django.utils.translation import gettext_lazy as _ from django.utils.encoding import force_str from rest_framework import serializers, exceptions, HTTP_HEADER_ENCODING from rest_framework.exceptions import ValidationError from defender import utils as defender_utils from defender import config from rest_framework.authentication import ( get_authorization_header, )

Get the UserModel

UserModel = get_user_model()

class BasicAuthenticationDefender(serializers.Serializer):

root@kitploit:~
  username = serializers.CharField(required=False, allow_blank=True)
  email = serializers.EmailField(required=False, allow_blank=True)
  password = serializers.CharField(style={'input_type': 'password'})

  def authenticate(self, **kwargs):
    request = self.context['request']

    if hasattr(settings, 'ACCOUNT_AUTHENTICATION_METHOD'):
        login_field = settings.ACCOUNT_AUTHENTICATION_METHOD
    else:
        login_field = 'username'
    userid = self.username_from_request(request, login_field)

    if defender_utils.is_already_locked(request, username=userid):
        detail = "You have attempted to login {failure_limit} times with no success. "
                 .format(
                     failure_limit=config.FAILURE_LIMIT,
                     cooloff_time_seconds=config.LOCKOUT_COOLOFF_TIME[defender_utils.get_lockout_cooloff_time(username=userid)]
                 )
        raise exceptions.AuthenticationFailed(_(detail))

    login_unsuccessful = False
    login_exception = None
    try:
        response = authenticate(request, **kwargs)
        if response == None:
            login_unsuccessful = True
            msg = _('Unable to log in with provided credentials.')
            # raise exceptions.ValidationError(msg)
            login_exception = exceptions.ValidationError(msg)
    except exceptions.AuthenticationFailed as e:
        login_unsuccessful = True
        login_exception = e

    defender_utils.add_login_attempt_to_db(request,
                                           login_valid=not login_unsuccessful,
                                           username=userid)

    user_not_blocked = defender_utils.check_request(request,
                                                    login_unsuccessful=login_unsuccessful,
                                                    username=userid)
    if user_not_blocked and not login_unsuccessful:
        return response

    raise login_exception

  def _validate_email(self, email, password):
    user = None

    if email and password:
        user = self.authenticate(email=email, password=password)
    else:
        msg = _('Must include "email" and "password".')
        raise exceptions.ValidationError(msg)

    return user

  def _validate_username(self, username, password):
    user = None

    if username and password:
        user = self.authenticate(username=username, password=password)
    else:
        msg = _('Must include "username" and "password".')
        raise exceptions.ValidationError(msg)

    return user

  def _validate_username_email(self, username, email, password):
    user = None

    if email and password:
        user = self.authenticate(email=email, password=password)
    elif username and password:
        user = self.authenticate(username=username, password=password)
    else:
        msg = _('Must include either "username" or "email" and "password".')
        raise exceptions.ValidationError(msg)

    return user

  def validate(self, attrs):
    username = attrs.get('username')
    email = attrs.get('email')
    password = attrs.get('password')

    user = None

    if 'allauth' in settings.INSTALLED_APPS:
        from allauth.account import app_settings

        # Authentication through email
        if app_settings.AUTHENTICATION_METHOD == app_settings.AuthenticationMethod.EMAIL:
            user = self._validate_email(email, password)

        # Authentication through username
        elif app_settings.AUTHENTICATION_METHOD == app_settings.AuthenticationMethod.USERNAME:
            user = self._validate_username(username, password)

        # Authentication through either username or email
        else:
            user = self._validate_username_email(username, email, password)

    else:
        # Authentication without using allauth
        if email:
            try:
                username = UserModel.objects.get(
                    email__iexact=email).username()
            except UserModel.DoesNotExist:
                pass

        if username:
            user = self._validate_username_email(username, '', password)

    # Did we get back an active user?
    if user:
        if not user.is_active:
            msg = _('User account is disabled.')
            raise exceptions.ValidationError(msg)
    else:
        msg = _('Unable to log in with provided credentials.')
        raise exceptions.ValidationError(msg)

    # If required, is the email verified?
    if 'rest_auth.registration' in settings.INSTALLED_APPS:
        from allauth.account import app_settings
        if app_settings.EMAIL_VERIFICATION == app_settings.EmailVerificationMethod.MANDATORY:
            email_address = user.emailaddress_set.get(email=user.email)
            if not email_address.verified:
                raise serializers.ValidationError(
                    _('E-mail is not verified.'))

    attrs['user'] = user
    return attrs

  def username_from_request(self, request, login_field):
    user_data = request._data
    return user_data[login_field]

इसे काम करने के लिए BasicAuthenticationDefender को अपने settings.py में REST_AUTH_SERIALIZERS डिक्शनरी में LOGIN_SERIALIZER कुंजी के अंतर्गत जोड़ें। उदाहरण के लिए, अपने settings.py में नीचे दी गई पंक्ति जोड़ें:

.. code-block:: python

REST_AUTH_SERIALIZERS = { 'LOGIN_SERIALIZER': '.BasicAuthenticationDefender', }

पासवर्ड रीसेट फॉर्म के लिए अनुकूल होना

defender को Django के PasswordResetView के लिए अनुकूलित किया जा सकता है ताकि बहुत अधिक सबमिशन को रोका जा सके।

हमें कुछ नए व्यू बनाने की आवश्यकता है जो Django के अंतर्निहित LoginView, PasswordResetView और PasswordResetConfirmView को उपवर्गित करते हैं — फिर इन व्यू का उपयोग अपने urls.py में Django के अंतर्निहित व्यू के प्रतिस्थापन के रूप में करें।

ये व्यू पासवर्ड रीसेट व्यू पर सबमिट किए गए ईमेल पते के आधार पर ब्लॉक करते हैं। यह डिफ़ॉल्ट कार्यान्वयन (जो उपयोगकर्ता नाम का उपयोग करता है) से भिन्न है, इसलिए हमें साइन-इन और पूर्ण पासवर्ड रीसेट के बाद अपने पीछे सफाई करने में सावधानी बरतनी होगी।

.. code-block:: python

root@kitploit:~
from defender import utils as def_utils
from django.contrib.auth import views as auth_views

class UserSignIn(auth_views.LoginView):
    def form_valid(self, form):
        """Force clear all the cached Defender statues for the authenticated user’s email address."""
        super_valid = super().form_valid(form)
        def_utils.check_request(self.request, False, username=form.get_user().email)
        return super_valid

class PasswordResetBruteForceProtectedView(auth_views.PasswordResetView):
    def get(self, request, *args, **kwargs):
        """Confirm the user isn’t already blocked by IP before showing the password reset view."""
        if def_utils.is_already_locked(request):
            return def_utils.lockout_response(request)
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        """
        Confirm the user isn’t already blocked by IP before allowing form POST.

        Also, force log this form POST as a single entry in the Defender cache, against the submitted email address.
        """
        if def_utils.is_already_locked(request):
            return def_utils.lockout_response(request)
        def_utils.check_request(
            request, login_unsuccessful=True, username=request.POST.get("email")
        )
        return super().post(request, *args, **kwargs)


class PasswordResetConfirmBruceForceProtectedView(auth_views.PasswordResetConfirmView):
    def get(self, request, *args, **kwargs):
        """Confirm the user isn’t already blocked by IP before showing the password confirm view."""
        if def_utils.is_already_locked(request):
            return def_utils.lockout_response(request)
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        """Confirm the user isn’t already blocked by IP before allowing form POST for the password change confirmation."""
        if def_utils.is_already_locked(request):
            return def_utils.lockout_response(request)
        return super().post(request, *args, **kwargs)

    def form_valid(self, form):
        """Force clear all the cached Defender statues for the user’s email address after successfully changing their password."""
        super_valid = super().form_valid(form)
        def_utils.check_request(
            self.request, login_unsuccessful=False, username=self.user.email
        )
        return super_valid

Django सिग्नल

django-defender उपयोगकर्ता नाम या IP पते को ब्लॉक करते समय सिग्नल भेजेगा। सिग्नल रिसीवर फ़ंक्शन सेट करने के लिए:

.. code-block:: python

from django.dispatch import receiver

from defender import signals

@receiver(signals.username_block) def username_blocked(username, **kwargs): print("%s was blocked!" % username)

@receiver(signals.ip_block) def ip_blocked(ip_address, **kwargs): print("%s was blocked!" % ip_address)

टेस्ट चलाना

रिपॉजिटरी क्लोन करने और Django इंस्टॉल होने के बाद, टेस्ट इस प्रकार चलाए जा सकते हैं:

.. code-block:: bash

PYTHONPATH=$PYTHONPATH:$PWD django-admin test defender --settings=defender.test_settings

कोड कवरेज के साथ:

.. code-block:: bash

PYTHONPATH=$PYTHONPATH:$PWD coverage run --source=defender $(which django-admin) test defender --settings=defender.test_settings

रिलीज़ करना

#. python setup.py sdist #. twine upload dist/*

टूल डाउनलोड करें
False
  • DEFENDER_DISABLE_IP_LOCKOUT\ : Boolean: यदि यह True है, तो यह उपयोगकर्ताओं के IP पते को लॉक आउट नहीं करेगा, केवल उपयोगकर्ता नाम को लॉक आउट करेगा। [डिफ़ॉल्ट: False]

  • DEFENDER_DISABLE_USERNAME_LOCKOUT\ : Boolean: यदि यह True है, तो यह उपयोगकर्ता नाम को लॉक आउट नहीं करेगा, केवल IP पतों को लॉक आउट करेगा। [डिफ़ॉल्ट: False]

  • DEFENDER_COOLOFF_TIME\ : Int: यदि सेट किया गया है, तो एक निष्क्रियता अवधि को परिभाषित करता है जिसके बाद पुराने असफल लॉगिन प्रयासों और उपयोगकर्ता नाम/IP लॉकआउट को भुला दिया जाएगा। एक पूर्णांक, सेकंड की संख्या के रूप में व्याख्या किया जाएगा। यदि 0 है, तो न तो असफल लॉगिन प्रयास और न ही उपयोगकर्ता नाम/IP लॉक समाप्त होंगे। [डिफ़ॉल्ट: 300\ ]

  • DEFENDER_ATTEMPT_COOLOFF_TIME\ : Int: यदि सेट किया गया है, तो DEFENDER_COOLOFF_TIME द्वारा निर्धारित पुराने असफल लॉगिन प्रयासों को भुलाए जाने की अवधि को ओवरराइड करता है। एक पूर्णांक, सेकंड की संख्या के रूप में व्याख्या किया जाएगा। यदि 0 है, तो असफल लॉगिन प्रयास समाप्त नहीं होंगे। [डिफ़ॉल्ट: DEFENDER_COOLOFF_TIME\ ]

  • DEFENDER_LOCKOUT_COOLOFF_TIME\ : Int or List: यदि सेट किया गया है, तो DEFENDER_COOLOFF_TIME द्वारा निर्धारित उपयोगकर्ता नाम/IP लॉकआउट को भुलाए जाने की अवधि को ओवरराइड करता है। एक पूर्णांक, सेकंड की संख्या के रूप में व्याख्या किया जाएगा। पूर्णांकों की एक सूची, उपयोगकर्ताओं के लिए सेकंड की संख्या के रूप में व्याख्या की जाएगी, जहाँ पूर्णांक का सूचकांक पिछले DEFENDER_ACCESS_ATTEMPT_EXPIRATION घंटों में हुए पिछले लॉकआउट की संख्या (कुछ अधिकतम तक) है। यदि संपत्ति 0 या [] पर सेट है, तो उपयोगकर्ता नाम/IP लॉकआउट समाप्त नहीं होगा। [डिफ़ॉल्ट: DEFENDER_COOLOFF_TIME\ ]

  • DEFENDER_LOCKOUT_TEMPLATE\ : String: [डिफ़ॉल्ट: None\ ] यदि सेट किया गया है, तो एक टेम्पलेट निर्दिष्ट करता है जो उपयोगकर्ता के लॉक आउट होने पर रेंडर किया जाएगा। टेम्पलेट को निम्नलिखित संदर्भ चर प्राप्त होते हैं:

    • cooloff_time_seconds\ : सेकंड में कूल-ऑफ़ समय
    • cooloff_time_minutes\ : मिनटों में कूल-ऑफ़ समय
    • failure_limit\ : ब्लॉक होने से पहले असफलताओं की संख्या।
  • DEFENDER_USERNAME_FORM_FIELD\ : String: फॉर्म फ़ील्ड का नाम जिसमें आपके उपयोगकर्ताओं के उपयोगकर्ता नाम हैं। [डिफ़ॉल्ट: username\ ]

  • DEFENDER_CACHE_PREFIX\ : String: आपकी defender कुंजियों के लिए कैश उपसर्ग। [डिफ़ॉल्ट: defender\ ]

  • DEFENDER_LOCKOUT_URL\ : String: वह URL जिस पर आप रीडायरेक्ट करना चाहते हैं यदि कोई लॉक आउट है।

  • DEFENDER_REDIS_URL\ : String: defender के लिए redis URL। [डिफ़ॉल्ट: redis://localhost:6379/0\ ] (पासवर्ड के साथ उदाहरण: redis://:mypassword@localhost:6379/0\ )

  • DEFENDER_REDIS_PASSWORD_QUOTE\ : Boolean: यदि redis पासवर्ड में विशेष वर्ण (जैसे '@') हैं, तो हम पासवर्ड को urllib.parse.quote("password!@#") के साथ कोट कर सकते हैं, और True पर सेट कर सकते हैं। [डिफ़ॉल्ट: False\ ]

  • DEFENDER_REDIS_NAME\ : String: आपकी Django सेटिंग्स में CACHES से कैश का नाम (जैसे "default")। यदि सेट किया गया है, तो DEFENDER_REDIS_URL को अनदेखा किया जाएगा। [डिफ़ॉल्ट: None\ ]

  • DEFENDER_STORE_ACCESS_ATTEMPTS\ : Boolean: यदि आप लॉगिन प्रयास को डेटाबेस में संग्रहीत करना चाहते हैं, तो True पर सेट करें। यदि False है, तो यह सहेजा नहीं जाता है [डिफ़ॉल्ट: True\ ]

  • DEFENDER_USE_CELERY\ : Boolean: यदि आप लॉगिन प्रयास को डेटाबेस में संग्रहीत करने के लिए Celery का उपयोग करना चाहते हैं, तो True पर सेट करें। यदि False है, तो यह इनलाइन सहेजा जाता है। [डिफ़ॉल्ट: False\ ]

  • DEFENDER_ACCESS_ATTEMPT_EXPIRATION\ : Int: घंटों में समय की अवधि कि प्रबंधन कमांड द्वारा साफ किए जाने से पहले डेटाबेस में एक्सेस अटेम्प्ट रिकॉर्ड को कितने समय तक रखा जाए। [डिफ़ॉल्ट: 24\ ]

  • DEFENDER_GET_USERNAME_FROM_REQUEST_PATH\ : String: फ़ंक्शन का आयात पथ जो अनुरोध से उपयोगकर्ता नाम तक पहुँचता है। यदि आप अनुरोध से उपयोगकर्ता नाम तक पहुँचने और संसाधित करने के लिए कस्टम फ़ंक्शन का उपयोग करना चाहते हैं, तो आप इसे यहाँ निर्दिष्ट कर सकते हैं। [डिफ़ॉल्ट: defender.utils.username_from_request\ ]