
सर्वर तक बुरे बॉट्स की पहुँच को रोकने की प्रक्रिया को स्वचालित करें
एक TUI, एक वेब UI और एक CLI जो आपको अपने सर्वर को कॉन्फ़िगर करने में मदद करते हैं ताकि आप CDN के पीछे छिपे बिना खराब बॉट्स को रोक सकें।
यह NGINX और आपके मौजूदा फ़ायरवॉल (iptables या nftables) के साथ, दो अलग-अलग स्तरों पर काम करता है:
ऐप अपनी पूरी कोशिश करता है कि आप सर्वर से लॉक आउट न हों, लेकिन आप इसे अपने जोखिम पर उपयोग करते हैं। और ध्यान दें कि यह AGPL के अंतर्गत लाइसेंस प्राप्त है, इसलिए यदि आप इसे व्यावसायिक रूप से उपयोग कर रहे हैं, तो सुनिश्चित करें कि आप लाइसेंस के अक्षर का पालन करते हैं।
From crates.io:``` cargo install stop-bots
या चेकआउट से बनाएं:```
cargo install --path .
एक प्रीबिल्ट x86_64 Linux बाइनरी GitHub releases पर उपलब्ध है।
बिल्ड करने के लिए Rust 1.88 या नया संस्करण आवश्यक है। व्यवहार में केवल Linux: यह
systemctl, nginx -t और nft/iptables को शेल आउट करता है, इसलिए हालाँकि यह अन्यत्र
कंपाइल हो जाता है, वहाँ इसका कोई खास उपयोग नहीं होगा।
TUI लॉन्च करने के लिए बाइनरी को बिना किसी आर्ग्युमेंट के चलाएँ, ब्राउज़र में वही स्क्रीन
देखने के लिए stop-bots web (देखें वेब UI), या CLI सबकमांड की पूरी सूची के
लिए stop-bots --help देखें। TUI और CLI को एक साथ इस्तेमाल किया जा सकता है। TUI में सब
कुछ कॉन्फ़िगर करें और फिर नियमों को अपडेट रखने के लिए crontab में CLI का उपयोग करें।
आप 'q' या Escape के साथ ऐप से बाहर निकल सकते हैं, या किसी पॉपअप/सबमेनू से बाहर आ सकते हैं।
आप 't' के साथ डार्क और लाइट थीम के बीच स्विच कर सकते हैं। ऐप थीम को स्वतः पहचानने का प्रयास करेगा, लेकिन कुछ टर्मिनल और मल्टीप्लेक्सर संयोजनों के लिए सही चुनाव करने हेतु पर्याप्त जानकारी उपलब्ध नहीं होती।
1–4 (या d/b/s/p) सीधे किसी स्क्रीन पर जाते हैं; Left/Right, या उनके vim
h/l उपनाम, उनके बीच से गुज़रते हैं; ? किसी भी समय पूर्ण की-बाइंडिंग संदर्भ को
टॉगल करता है, और : एक कमांड पैलेट खोलता है जो हर क्रिया को नाम से सूचीबद्ध करता है।
Tab / Shift+Tab हमेशा वर्तमान स्क्रीन के पैनलों के बीच चलते हैं, स्क्रीनों के बीच कभी नहीं।
Dashboard वह सब कुछ रखता है जो firewall script में जाता है; Site settings वह सब कुछ रखता है जो NGINX config में जाता है। यह विभाजन तय करता है कि कोई दिया गया सेटिंग कहाँ रहती है।
Up/Down तीन सूचियों के बीच प्रवाहित होते हैं; m
जियो मोड स्विच करता है। वर्तमान फ़ायरवॉल नियमों को एक स्क्रिप्ट में रेंडर करने के लिए
F दबाएँ — पॉपअप में वास्तव में इसे तुरंत लागू करने के लिए "apply after writing" टॉगल
(Space) भी है, बजाय बाद में इसे हाथ से लागू करने के। तीन और कुंजियाँ पूरे होस्ट पर कार्य
करती हैं: u हर सूची डाउनलोड करता है, a दोनों प्लेन (NGINX, फिर फ़ायरवॉल) लागू करता
है, और w इस कंसोल को NGINX के पीछे रखता है — वही तीन जो ब्राउज़र में बटन और एक पैनल
के रूप में हैं।Tab से इसे फ़ोकस करें) जो जेनरेट किए गए
कॉन्फ़िग को आकार देने वाले होस्ट-व्यापी विकल्प रखता है — एक ब्लॉक किए गए अनुरोध को क्या
वापस मिलता है (नीचे देखें), क्या जेनरेट किया गया सर्व करना है, और रेट
लिमिटिंग — डिस्क पर खोजी गई हर NGINX साइट के ऊपर, प्रत्येक में एक लाइव "up to date /
stale / not found" स्टेटस और वर्तमान नीति को एक साइट या उन सभी पर लागू करने की क्रियाएँ।
उन सेटिंग्स में से कोई भी बदलने पर हर लागू की गई साइट हो जाती है, जो आपके
पुनः-लागू करने का संकेत है। किसी साइट को खोलने पर आप उसकी श्रेणी/बॉट नीति को ओवरराइड
कर सकते हैं, छह अनुरोध-आकार नियमों में से कोई भी चालू कर सकते हैं, और ब्लॉकिंग से मुक्त
पथों को सूचीबद्ध कर सकते हैं।Bot settings, जहाँ हर लिस्ट स्रोत और हर व्यक्तिगत बॉट रहता है:
Site settings, जहाँ होस्ट-व्यापी NGINX विकल्प डिस्क पर मिली हर साइट के ऊपर बैठते हैं:
Dynamic Protection, वर्तमान में सर्वर पर क्या हिट कर रहा है इसका लाइव दृश्य:
ज्ञात बॉट, श्रेणी के अनुसार (scanner / search engine / AI crawler), जो
ArcJet's Well-Known Bots,
ai.robots.txt और
NGINX Ultimate Bad Bot Blocker
सूची से लिए गए हैं। किसी श्रेणी को ब्लॉक करने पर प्रत्येक साइट के NGINX कॉन्फ़िग में एक
if ($http_user_agent ...) नियम इंजेक्ट होता है (apply-blocks / Site settings का a/A)।
बहुत अधिक अनुरोध, NGINX की अपनी रेट लिमिटिंग के माध्यम से। यहाँ बाकी सब कुछ के विपरीत यह अनुरोध के समय NGINX द्वारा लागू किया जाता है, न कि बाद में लॉग का विश्लेषण करके। डिफ़ॉल्ट रूप से बंद: गलत साइट के लिए ट्यून की गई सीमा असली आगंतुकों को दूर कर देती है।
पहले विनम्रता से — एक वैकल्पिक जेनरेट किया गया robots.txt जो आपके द्वारा ब्लॉक किए
जा रहे हर बॉट को सूचीबद्ध करता है, उन क्रॉलरों के लिए जो इसका पालन करते हैं, साथ ही नीचे
दिया गया honeypot पथ। डिफ़ॉल्ट रूप से बंद, क्योंकि यह आपकी साइट आज /robots.txt पर जो
भी सर्व करती है उसे बदल देता है।
सिवाय जहाँ आप अन्यथा कहें — प्रति-साइट पथ छूट, ताकि आप AI क्रॉलरों को हर जगह ब्लॉक
कर सकें सिवाय /blog के।
ऐसे अनुरोध जो ब्राउज़र जैसे नहीं दिखते, प्रति साइट। छह स्वतंत्र नियम, प्रत्येक का अपना टॉगल और प्रत्येक डिफ़ॉल्ट रूप से बंद — प्रति नियम एक स्विच ताकि यदि आपका कुछ काम करना बंद कर दे, तो आप बता सकें कि किस नियम ने ऐसा किया:
Site settings पर एक होस्ट-व्यापी विकल्प। ये विनिमेय स्टेटस कोड नहीं हैं — प्रत्येक कुछ अलग कहता है, और यह अंतर उन क्लाइंटों के लिए सबसे अधिक मायने रखता है जिन्हें आप नहीं पकड़ना चाहते थे:
Tarpit एक गलत पॉज़िटिव के लिए सबसे सौम्य विकल्प है — गलती से पकड़ा गया क्लाइंट धीमा किया
जाता है, मना नहीं — और एक बॉट के लिए लागत पर सबसे कठोर, जिसका कनेक्शन निष्क्रिय बैठा रहता
है। इसे चुनने से पहले दो बातें जान लें: यह अवधि के दौरान आपके एक worker connection को भी
रोके रखता है, इसलिए tarpit किए गए क्लाइंटों की बाढ़ असली आगंतुकों के साथ worker_connections
के लिए प्रतिस्पर्धा करती है; और यह वास्तव में कितनी देर चलता है यह इस पर निर्भर करता है कि
NGINX एक छोटी error बॉडी कैसे लिखना चुनता है, जिसे TODO.md में एक असली सर्वर के विरुद्ध
जाँच की आवश्यकता के रूप में नोट किया गया है।
इनमें से प्रत्येक Dashboard के "Automatic blocking" पैनल पर एक स्वतंत्र स्विच है, और प्रत्येक एक अस्थायी फ़ायरवॉल ब्लॉक जोड़ता है जो स्वयं समाप्त हो जाता है और यदि व्यवहार जारी रहता है तो पुनः जोड़ दिया जाता है।
वे एक आंतरिक टाइमर पर चलते हैं जो हर मिनट आपके SSH और NGINX एक्सेस लॉग को फिर से पढ़ता है — लेकिन केवल तब जब TUI या वेब UI चल रहा हो। कोई भी एक ही शेड्यूल, एक ही डेटाबेस में बनाए रखता है, इसलिए वेब UI को चालू छोड़ना पर्याप्त है; जब दोनों में से कोई नहीं चल रहा हो तो कुछ भी डिटेक्ट नहीं होता। ऐसे सर्वर के लिए जिस पर कोई stop-bots प्रोसेस बिल्कुल नहीं है, नीचे Unattended, from cron देखें।
/.env, /.git/config, /wp-config.php और इसी तरह के लिए एक
अकेला अनुरोध अपने आप में निर्णायक है, इसलिए इसे किसी थ्रेशोल्ड की आवश्यकता नहीं। अंतर्निहित
सूची जानबूझकर ऐसे पथ छोड़ देती है जो कहीं वैध हैं — /wp-login.php, /wp-admin/,
/xmlrpc.php, /phpmyadmin — क्योंकि अपने ही प्रशासक को लॉक आउट करना उस स्कैनर को चूकने
से बुरा होगा जिसे 404 डिटेक्टर वैसे भी पकड़ लेता है। set-probe-paths के साथ अपने स्वयं के
पथ जोड़ें।robots.txt में Disallow: के रूप में प्रकाशित
है और कहीं लिंक नहीं है। इस तक पहुँचने का अर्थ है robots.txt की अनदेखी करना, जो कोई भी
वैध चीज़ संयोग से नहीं करती — यहाँ सबसे मजबूत संकेत, और सबसे लंबा ब्लॉक। काम करने के लिए
robots.txt जेनरेशन चालू होना आवश्यक है।तीन और यह देखते हैं कि कोई क्लाइंट क्या माँगता है उसके बजाय कैसे व्यवहार करता है। तीनों डिफ़ॉल्ट रूप से बंद हैं, क्योंकि प्रत्येक में एक ऐसा गलत पॉज़िटिव है जिसे वह अपने आप नहीं रोक सकता — और तीनों सत्यापित सर्च-इंजन क्रॉलरों को छूट देते हैं, जो अन्यथा इनमें से हर एक से मेल खाते:
304 फ़ेच किए गए एसेट के रूप में गिना जाता है)। ऐसी साइट पर आपकी मदद
नहीं कर सकता जो कोई एसेट सर्व ही नहीं करती — एक शुद्ध JSON API।Referer नहीं।
Referrer-Policy: no-referrer और प्राइवेसी टूलिंग द्वारा कमज़ोर; भिन्न-पथ थ्रेशोल्ड ही
इसे उपयोगी बनाता है।/24 में कई पते एक ही पास में फ़्लैग होते
हैं, तो /24 को ब्लॉक करें। डिफ़ॉल्ट रूप से बंद — तीन के दुर्व्यवहार के कारण 256 पतों को
ब्लॉक करना डिज़ाइन से ही कोलैटरल है। (IPv6 अलग है और इसे किसी स्विच की आवश्यकता नहीं:
एक डिटेक्शन हमेशा /64 को ब्लॉक करता है, क्योंकि एक /64 एक LAN है, वही चीज़ जो एक
अकेला IPv4 पता दर्शाता है। IPv6 हमलावर ने संयोग से जो अकेला पता इस्तेमाल किया उसे ब्लॉक
करना कुछ भी नहीं रोकेगा — उनके पास 2^64 और हैं।)ऊपर का सब कुछ जेनरेट किया गया है। इसका कोई भी हिस्सा प्रभावी है या नहीं यह एक अलग
प्रश्न है, और stop-bots status वह है जो इसका उत्तर देता है:```
stop-bots status
सात जाँचें, और पहली वही है जो वाकई मायने रखती है: क्या जनरेट किए गए नियम वास्तव में kernel में हैं, या सिर्फ़ disk पर? एक असली host तीन हफ़्तों तक `/etc/stop-bots/firewall.nft` में 48,860 drop नियमों और एक खाली ruleset के साथ चला, क्योंकि script लिखना और उसे load करना दो अलग कदम हैं और किसी ने कभी दूसरे को नहीं देखा।
बाक़ी: क्या ruleset reboot के बाद भी बचा रहेगा (`nftables.service` enabled है?), क्या script अब भी नियमों से मेल खाता है, क्या NGINX blocks लागू हैं, क्या console service उसी binary को चला रही है जिसका वह नाम लेती है, क्या database के लिए जगह है, और क्या detectors अपने logs पढ़ पाते हैं।
अगर कुछ भी **CRITICAL** है तो यह non-zero के साथ exit करता है, इसलिए यह monitoring check की तरह काम करता है। `--quiet` सिर्फ़ वही छापता है जिस पर ध्यान देने की ज़रूरत है, जो cron के लिए उपयुक्त रूप है:```
0 * * * * /usr/local/bin/stop-bots status --quiet
जो check चल ही नहीं सका — nft list को root चाहिए — वह UNKNOWN रिपोर्ट करता है, कभी
OK नहीं। ऐसा health check जो कहता है कि सब ठीक है क्योंकि वह देख ही नहीं सका, बिना किसी check से
बदतर है, क्योंकि उस पर विश्वास किया जाता है।
वही रिपोर्ट console और TUI दोनों में Dashboard पर होती है, जिसे हर render पर नहीं बल्कि
internal cron द्वारा हर घंटे लिया जाता है: बड़े ruleset पर nft list कई megabytes का text होता है।
ऊपर दिया गया हर firewall निर्णय generate किया जाता है, कभी अपने आप लागू नहीं होता: render-firewall
(या Dashboard की f key) आपके समीक्षा और स्वयं लागू करने के लिए एक iptables या nftables script लिखता है,
और ऐसा script लिखने से मना कर देता है जो वर्तमान में जुड़े SSH session को lock out कर दे।
तीन चीज़ें इसे आपके लिए लागू कर सकती हैं, और तीनों के लिए आपको कहना पड़ता है: TUI का render popup
("apply after writing") या उसकी a key, web console का firewall panel ("run it after
writing") या उसका "Apply everything" button, और आपके द्वारा लिखे गए crontab से batch --apply — देखें
Unattended, from cron। इनमें से कोई भी किसी स्वचालित चीज़ का side effect नहीं है: internal cron script render करता है और उसे कभी चलाता नहीं।
यही NGINX पक्ष पर भी लागू होता है: किसी setting को बदलना केवल यह बदलता है कि क्या लिखा जाएगा।
Site settings हर site को STALE के रूप में दिखाता है जब तक आप apply नहीं करते।
किसी detector को बंद करना उसके पहले से जोड़े गए blocks को कभी नहीं हटाता — वे अपने आप expire हो जाते हैं।
"Stop detecting" और "undo what was detected" जानबूझकर अलग हैं; दूसरा Dynamic Protection screen या remove-firewall-rule है।
एक सादा access-log tally भी है, जो blocking से स्वतंत्र है: record-access-stats /
list-access-stats गिनते हैं कि प्रत्येक user agent कितनी बार सफल (non-error)
requests में दिखता है, ताकि आप देख सकें कि किसे block किया जा रहा है उसके अलावा वास्तव में कौन visit कर रहा है।
stop-bots batch उस सब पर एक pass है जो TUI हाथ से करता है: हर list refresh करना,
logs scan करना, NGINX blocking rules और firewall script लिखना।```
0 4 * * * root /usr/local/bin/stop-bots batch --apply --ssh-log /var/log/auth.log
*/10 * * * * root /usr/local/bin/stop-bots batch --apply --no-fetch --ssh-log /var/log/auth.log
जब सब कुछ ठीक से चलता है तो यह कुछ नहीं कहता, इसलिए एक स्वस्थ नाइटली रन आपको मेल नहीं करता। एक विफल
चरण stderr पर प्रिंट करता है और एक गैर-शून्य निकास स्थिति सेट करता है, जिसके कारण cron आपको
इसके बारे में बताता है। पहले इसे एक बार हाथ से `--verbose` के साथ चलाएँ — यह प्रति चरण एक पंक्ति प्रिंट करता है, और
यह देखने का सबसे आसान तरीका है कि यह वास्तव में क्या कर रहा है।
**`--apply` ही इसे कुछ भी लागू करवाता है।** इसके बिना, `batch` NGINX कॉन्फ़िग
और फ़ायरवॉल स्क्रिप्ट लिखता है और रुक जाता है: कॉन्फ़िग रीलोड तक कुछ नहीं करता, स्क्रिप्ट चलाए जाने तक कुछ नहीं करती। यह इस परियोजना का हर जगह डिफ़ॉल्ट है, और यहाँ भी डिफ़ॉल्ट बना रहता है।
`batch` और एक लंबे समय तक चलने वाला फ्रंट-एंड सुरक्षित रूप से सह-अस्तित्व में रहते हैं। TUI, वेब UI और `batch` सभी
एक ही डेटाबेस में एक ही कुंजियों के माध्यम से रिकॉर्ड करते हैं कि उन्होंने क्या किया, इसलिए जो भी पहले किसी कार्य तक पहुँचता है वह उसे करता है और बाकी पाते हैं कि यह अब देय नहीं है — आपको दो डिटेक्शन पास नहीं मिलते, और
Dashboard का "Scheduled tasks" पैनल दिखाता है कि वास्तव में क्या हुआ बजाय यह दावा करने के कि सब कुछ अतिदेय है। यदि आप पहले से ही वेब UI चलते हुए छोड़ देते हैं, तो नाइटली `batch` प्रविष्टि एक आवश्यकता के बजाय अतिरिक्त सुरक्षा है; यदि आप नहीं छोड़ते, तो यह डिटेक्शन को अद्यतित रखने वाली एकमात्र चीज़ है।
**`--apply` के साथ, SSH लॉकआउट गार्ड मना कर सकता है — और मना करने का मतलब है कि कुछ भी लागू नहीं होता।**
यह मना करता है यदि नियम किसी ऐसे क्लाइंट को ब्लॉक कर देंगे जो अभी कनेक्टेड है, *और* यदि कोई SSH लॉग
बिल्कुल पढ़ा नहीं जा सका, क्योंकि तब जाँच चल ही नहीं सकती। इंटरैक्टिव
`render-firewall` उस दूसरे मामले में केवल एक नोट प्रिंट करता है, इस तर्क पर कि एक इंसान टर्मिनल देख रहा है; cron से कोई नहीं देखता। **`--ssh-log` स्पष्ट रूप से पास करें**: cron root के रूप में चलता है इसलिए `/var/log/auth.log` आमतौर पर ठीक पढ़ा जाता है, लेकिन journald-only होस्ट पर cron के अधीन `journalctl` खाली वापस आ सकता है, जो वास्तव में वही मामला है जिस पर यह मना करता है। `--force` गार्ड को ओवरराइड करता है यदि आपका मतलब वही है।
एक चरण विफल होने पर कभी बाकी नहीं रुकते, और NGINX और फ़ायरवॉल के हिस्से स्वतंत्र हैं —
एक विफल NGINX रीलोड फिर भी फ़ायरवॉल लागू छोड़ देता है, और इसके विपरीत भी।
`batch` प्रत्येक चरण को उसी शेड्यूल के विरुद्ध रिकॉर्ड करता है जो TUI का आंतरिक cron उपयोग करता है, इसलिए दोनों
सहमत होते हैं कि क्या पहले ही चल चुका है बजाय दोनों के इसे करने के, और Dashboard का "Scheduled tasks" पैनल दिखाता है कि आपके वास्तविक cron ने क्या किया।
# वेब UI
`stop-bots web` ब्राउज़र में वही पाँच स्क्रीन प्रस्तुत करता है।```
stop-bots web
यह 127.0.0.1:8787 पर बाइंड होता है — केवल उसी मशीन से पहुँचा जा सकता है — और पहली बार चलाने पर एक बार जनरेट किया गया पासवर्ड प्रिंट करता है। अपने लैपटॉप से SSH टनल के माध्यम से इसे एक्सेस करें:``` ssh -L 8787:127.0.0.1:8787 your-server
फिर <http://127.0.0.1:8787/> खोलें।

कंसोल ऑपरेटिंग सिस्टम की लाइट या डार्क सेटिंग का पालन करता है, हेडर में एक टॉगल के साथ; ऊपर दिए गए TUI स्क्रीनशॉट डार्क थीम के हैं, ये लाइट वाले। TUI जिन कुंजियों का उपयोग करता है वे यहाँ भी काम करती हैं: `1`–`4` स्क्रीन बदलती हैं, `/` सर्च बॉक्स पर फ़ोकस करती है, `?` Help खोलती है।

हेडर में तीन होस्ट-वाइड क्रियाएँ होती हैं, ब्राउज़र में बटन के रूप में और TUI में सिंगल कुंजियों के रूप में:
- **Update everything** (`u`) हर बॉट लिस्ट, हर क्रॉलर IP रेंज, हर *सक्षम* रेपुटेशन फ़ीड और हर *चयनित* देश को डाउनलोड करता है — वही सेट जो `stop-bots batch` फ़ेच करता है, उसी प्लान से। एक स्रोत विफल होने पर बाकी नहीं रुकते, और जब तक कोई इसे लागू नहीं करता तब तक कुछ भी लागू नहीं होता।
- **Apply everything** (`a`) NGINX कॉन्फ़िग लिखता और रीलोड करता है, फिर फ़ायरवॉल स्क्रिप्ट लिखता और चलाता है। दोनों प्लेन स्वतंत्र हैं: जो भी विफल हो, दूसरे को फिर भी अपनी बारी मिलती है, क्योंकि आधा-लागू होस्ट उस होस्ट से बेहतर है जहाँ NGINX सिंटैक्स त्रुटि ने फ़ायरवॉल को भी पुराना छोड़ दिया हो।
- **Web Access** (`w`) NGINX को स्वयं कंसोल सर्व करने के लिए सेट करता है — देखें [Behind NGINX](#behind-nginx-a-subdomain-or-a-path-prefix)।
## एक सेवा के रूप में (Debian)```
sudo stop-bots install web
/etc/systemd/system/stop-bots-web.service लिखता है, /var/lib/stop-bots (0700 — यह
कंसोल का पासवर्ड हैश रखता है) और /etc/stop-bots बनाता है, यदि पासवर्ड नहीं है तो एक
उत्पन्न करता है, और यूनिट को सक्षम और प्रारंभ करता है।
--dry-run पूरी योजना प्रिंट करता है और कुछ भी नहीं बदलता। यह प्रोजेक्ट में एकमात्र
कमांड है जो एक डेमॉन शुरू करता है, इसलिए वहीं से शुरू करें। --prefix <dir> वही ट्री
कहीं और लिखता है जहाँ आप इसे रूट के बिना पढ़ सकते हैं। यदि यूनिट पहले से मौजूद है और आपने
इसे संपादित किया है, तो इंस्टॉलर रुक जाता है और आपके संपादन को बदलने के बजाय ऐसा कहता है;
यदि आपका मतलब था तो --force।
सेवा root के रूप में चलती है, क्योंकि कंसोल /etc/nginx को फिर से लिखता है, फ़ायरवॉल
स्क्रिप्ट लिखता है, और nginx -t और systemctl reload nginx चलाता है। कोई भी
अनप्रिविलेज्ड विभाजन नहीं है जो फीचर सेट को बरकरार रखता हो। यूनिट उस हार्डनिंग को
ले जाती है जो उस आवश्यकता के बाद भी टिकती है और एक टिप्पणी जो बताती है कि कौन सी
हार्डनिंग छोड़ी गई और क्यों।
बाइंड एड्रेस, होस्ट अनुमति सूची और पाथ प्रीफ़िक्स जानबूझकर यूनिट में नहीं हैं —
चल रहा सर्वर उन्हें डेटाबेस से फिर से पढ़ता है, इसलिए उन्हें ExecStart में डालने से
उनके सत्य के दो स्रोत हो जाएंगे। उन्हें stop-bots web --save ... से बदलें और
पुनः आरंभ करें।
एक चीज़ बदल जाती है जब यह रूट के रूप में चलता है: आंतरिक क्रॉन का दैनिक RenderFirewall
जॉब अब /etc/stop-bots/firewall.nft लिख सकता है, जो वह नहीं कर सकता था जब आपने
कंसोल को स्वयं के रूप में हाथ से चलाया था। उस स्क्रिप्ट को लागू करने वाला कोई नहीं है —
इसे चलाना अभी भी आपका काम है।
केवल Debian की जाँच की जाती है, क्योंकि वही परीक्षण किया गया है; यूनिट किसी भी systemd वितरण पर बहुत संभवतः सही है, लेकिन यह जिस SSH लॉग पाथ को मानती है वह Debian का है।
लूपबैक के अलावा कुछ भी बाइंड करने के लिए एक दूसरा, जानबूझकर फ़्लैग चाहिए, क्योंकि यह कंसोल उस होस्ट के फ़ायरवॉल और NGINX कॉन्फ़िग को फिर से लिख सकता है जिस पर यह चलता है:``` stop-bots web --bind 0.0.0.0:8787 --expose --allowed-hosts admin.example.com --save
`--allowed-hosts` व्यवहार में वैकल्पिक नहीं है: जिस अनुरोध में ऐसा होस्ट नाम होता है जो
सूचीबद्ध नहीं है, उसे अस्वीकार कर दिया जाता है। यही कारण है कि कंसोल के विरुद्ध DNS रीबाइंडिंग विफल हो जाती है, और यही कारण है
कि नाम से पहुँचे जाने वाले उजागर सर्वर के लिए नाम स्पष्ट रूप से लिखा जाना आवश्यक है।
इसे TLS के साथ NGINX के पीछे रखें — वही NGINX जिसकी यह टूल रक्षा कर रहा है। यदि आप ऐसा करते हैं, और
प्रॉक्सी `X-Forwarded-For` सेट करता है, तो कंसोल को बताएं कि वह उस हेडर पर विश्वास कर सकता है, अन्यथा वह यह नहीं बता सकता
कि कोई अनुरोध वास्तव में किस पते से आया है:```
stop-bots web --bind 127.0.0.1:8787 # and set web:trust_forwarded_for
TLS के पीछे, web:secure_cookie भी सेट करें। इसके बिना ब्राउज़र उसी होस्ट के http:// URL पर भी सेशन कुकी भेज देगा।
web:trust_forwarded_for जितना दिखता है उससे कहीं अधिक मायने रखता है। इसके बिना प्रॉक्सी के पीछे से आने वाली हर रिक्वेस्ट 127.0.0.1 से आती है, इसलिए कंसोल एक क्लाइंट को दूसरे से अलग नहीं बता पाता — जिसका मतलब है कि लॉगिन प्रयासों की बाढ़ आपके साथ ही थ्रॉटल बकेट साझा करती है, और वह गार्ड जो आपको अपना ही पता ब्लॉक करने से रोकता है, उसके पास तुलना करने के लिए कुछ नहीं होता। इसके साथ, दोनों प्रति-क्लाइंट काम करते हैं।
कंसोल आपके लिए यह सेट कर सकता है, और TUI भी कर सकता है (Dashboard पर w)। दोनों NGINX कॉन्फ़िग लिखते हैं, पाथ प्रीफ़िक्स रिकॉर्ड करते हैं और होस्ट नाम को allowlist में जोड़ते हैं — ये तीन चीज़ें जिनका मेल खाना ज़रूरी है, क्योंकि गायब प्रीफ़िक्स हर लिंक को location ब्लॉक से बाहर निकाल देता है और गायब होस्ट नाम हर रिक्वेस्ट को 403 बना देता है। दोनों कॉन्फ़िग प्रभावी होने से पहले nginx -t से वैलिडेट करते हैं, अगर वह विफल हो तो इसे रोल बैक करते हैं, और नया पता तभी रिकॉर्ड करते हैं जब वह वैलिडेट हो जाए।
दो मोड हैं, और path डिफ़ॉल्ट होना एक कारण से है: यह आपकी पहले से मौजूद साइट में एक location ब्लॉक जोड़ता है, इसलिए कंसोल उस साइट का सर्टिफिकेट विरासत में ले लेता है। एक सबडोमेन को अपना अलग सर्टिफिकेट चाहिए, और जब तक certbot --nginx -d <host> नहीं चल जाता, इस कंसोल का पासवर्ड फ़ॉर्म और सेशन कुकी नेटवर्क पर साफ़-साफ़ (unencrypted) यात्रा करते हैं।
इस सेक्शन का बाकी हिस्सा वही चीज़ हाथ से करने के बारे में है, जिसे एक बार पढ़ना फ़ायदेमंद है भले ही आप पैनल का उपयोग करें — नीचे दिया गया trailing-slash जाल वह गलती है जिसे रोकने के लिए यह मौजूद है।
एक सबडोमेन सरल डिप्लॉयमेंट है, और अगर आप कर सकते हैं तो यही अपनाएँ:```nginx server { server_name stopbots.example.com; location / { proxy_pass http://127.0.0.1:8787; proxy_set_header Host $host; } }
| `-s` | `--server` | Server URL (default: `http://localhost:8080`) |
| `-t` | `--token` | API token for authentication |
| `-o` | `--output` | Output file path |
| `-f` | `--format` | Output format: `json`, `yaml`, `table` |
| `-v` | `--verbose` | Enable verbose logging |
| `-q` | `--quiet` | Suppress non-error output |
| `-h` | `--help` | Show help message |
| `-V` | `--version` | Show version information |
### उदाहरण
```bash
# Scan a single target
scanner scan --target example.com
# Scan multiple targets from a file
scanner scan --input targets.txt --output results.json
# Use a custom configuration file
scanner scan --config /path/to/config.yaml
# Run with verbose output
scanner scan --target example.com --verbose
The scanner supports a YAML configuration file for advanced settings:
server:
url: "http://localhost:8080"
token: "your-api-token"
timeout: 30
scan:
threads: 10
depth: 3
follow_redirects: true
output:
format: "json"
directory: "./results"
verbose: false
All API requests require a valid token in the Authorization header:
Authorization: Bearer <token>
curl -X POST http://localhost:8080/api/v1/scans \
-H "Authorization: Bearer your-api-token" \
-H "Content-Type: application/json" \
-d '{"target": "example.com", "depth": 3}'
{
"id": "scan-12345",
"target": "example.com",
"status": "completed",
"started_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:35:00Z",
"findings": [
{
"type": "vulnerability",
"severity": "high",
"description": "SQL injection detected"
}
]
}
stop-bots web --allowed-hosts stopbots.example.com --save
**एक पथ उपसर्ग भी काम करता है**, लेकिन कंसोल को इसके बारे में बताना पड़ता है — इसे हर लिंक, फ़ॉर्म क्रिया, रीडायरेक्ट और कुकी पथ को उपसर्ग के साथ पहले से ही उत्पन्न करना होता है, और यह अनुमान नहीं लगा सकता:```
stop-bots web --base-path /stop-bots --allowed-hosts example.com --save
| -s | --server | Server URL (default: http://localhost:8080) |
| -t | --token | API token for authentication |
| -o | --output | Output format: json, yaml, table |
| -v | --verbose | Enable verbose logging |
| -q | --quiet | Suppress non-essential output |
| -h | | Show help message and exit |
# सर्वर स्थिति जाँचें
kitploit-cli status
# सभी उपकरणों को JSON प्रारूप में सूचीबद्ध करें
kitploit-cli tools list --output json
# विशिष्ट उपकरण खोजें
kitploit-cli tools search "network scanner"
# कस्टम सर्वर के विरुद्ध चलाएँ
kitploit-cli --server https://api.example.com --token YOUR_TOKEN tools list
CLI निम्नलिखित स्थानों पर कॉन्फ़िगरेशन फ़ाइल की खोज करता है:
./.kitploit.yaml~/.config/kitploit/config.yaml/etc/kitploit/config.yamlकॉन्फ़िगरेशन फ़ाइल उदाहरण:
server: http://localhost:8080
token: your-api-token
output: table
verbose: false
| चर | विवरण |
|---|---|
KITPLOIT_SERVER | सर्वर URL को ओवरराइड करें |
KITPLOIT_TOKEN | API टोकन सेट करें |
सभी API अनुरोधों के लिए Authorization हेडर में API टोकन की आवश्यकता होती है:
Authorization: Bearer YOUR_API_TOKEN
GET /api/v1/toolsसभी उपलब्ध उपकरणों की सूची लौटाता है।
क्वेरी पैरामीटर:
प्रतिक्रिया उदाहरण:
{
"data": [
{
"id": "tool-001",
"name": "Example Scanner",
"description": "A network scanning tool",
"category": "network",
"version": "1.2.3",
"url": "https://github.com/example/scanner"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150
}
}
GET /api/v1/tools/{id}ID द्वारा एक विशिष्ट उपकरण लौटाता है।
पथ पैरामीटर:
| पैरामीटर | प्रकार | विवरण |
|---|---|---|
id | string | उपकरण पहचानकर्ता |
प्रतिक्रिया उदाहरण:
{
"id": "tool-001",
"name": "Example Scanner",
"description": "A network scanning tool",
"category": "network",
"version": "1.2.3",
"url": "https://github.com/example/scanner",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-03-20T14:45:00Z"
}
POST /api/v1/toolsएक नया उपकरण बनाता है।
अनुरोध निकाय:
{
"name": "New Tool",
"description": "Tool description",
"category": "web",
"url": "https://github.com/example/new-tool"
}
प्रतिक्रिया: 201 Created
PUT /api/v1/tools/{id}मौजूदा उपकरण को अपडेट करता है।
अनुरोध निकाय:
{
"name": "Updated Tool Name",
"description": "Updated description"
}
प्रतिक्रिया: 200 OK
DELETE /api/v1/tools/{id}एक उपकरण हटाता है।
प्रतिक्रिया: 204 No Content
सभी त्रुटियाँ एक सुसंगत JSON प्रारूप का पालन करती हैं:
{
"error": {
"code": "NOT_FOUND",
"message": "The requested resource was not found",
"status": 404
}
}
proxy_pass http://127.0.0.1:8787; # NO trailing slash
proxy_set_header Host $host;
}
**`proxy_pass` पर ट्रेलिंग स्लैश मायने रखता है, और उसका न होना ही पूरी तरकीब है।**
इसके बिना, NGINX पूरा पाथ पास कर देता है और `stop-bots` को
`/stop-bots/whatever` दिखता है, जो अब यह सर्व करता है और जनरेट करता है। ट्रेलिंग
स्लैश *के साथ*, NGINX प्रीफ़िक्स को हटा देता है — और फिर ब्राउज़र पेज के लिंक को
डोमेन रूट के सापेक्ष रिज़ॉल्व करता है, `location` ब्लॉक के बाहर पहुँच जाता है, और सब कुछ 404 हो जाता है। सर्वर की ओर से कितनी भी सावधानी इसे ठीक नहीं कर सकती, इसलिए प्रीफ़िक्स को प्रॉक्सी से पार जाना ही होगा।
बाहर से इसे लागू करने वाला कोई नहीं है, लेकिन विफलता सूक्ष्म नहीं बल्कि ज़ोरदार है: प्रीफ़िक्स कॉन्फ़िगर होने पर, बिना प्रीफ़िक्स वाला अनुरोध आधा-अधूरा काम करने वाले पेज के बजाय एक सादा 404 होता है।
## यह क्या नहीं करेगा
दो चीज़ें जानबूझकर गायब हैं, और Help स्क्रीन कारणों के साथ ऐसा कहती है:
- **यह किसी डाउनलोड की गई सूची द्वारा ब्लॉक की गई चीज़ को अनब्लॉक नहीं करेगा** — उस सूची का अगला रीफ़्रेश चुपचाप इसे पूर्ववत कर देगा।
- **यह अपना पासवर्ड नहीं बदलेगा।** होस्ट पर `stop-bots web --set-password` का उपयोग करें।
यह उस पते को ब्लॉक करने से भी इनकार करता है जिससे आप कनेक्टेड हैं, जो उस कंसोल को छीन लेगा जिसका उपयोग आप इसे पूर्ववत करने के लिए करेंगे।
**पहले ये तीन थीं।** फ़ायरवॉल स्क्रिप्ट लागू करना तीसरी थी, इस आधार पर कि इसे चलाना ही एकमात्र ऐसा ऑपरेशन है जो होस्ट को नेटवर्क से हटा सकता है। अब यह उपलब्ध है — Dashboard पर "Apply everything" (`TUI` में `a`), या फ़ायरवॉल पैनल में "run it after writing" बॉक्स — क्योंकि जो गार्ड इसे cron से सुरक्षित बनाता है वही इसे एक बटन से भी सुरक्षित बनाता है: नियमों की जाँच वर्तमान में SSH पर लॉग-इन क्लाइंट्स के विरुद्ध की जाती है, उसी क्रम में जिस क्रम में स्क्रिप्ट स्वयं उनका मूल्यांकन करेगी, और जो नियम उनमें से किसी एक को ब्लॉक करेगा वह चेतावनी के बजाय इनकार है। पुराना write-only व्यवहार वापस पाने के लिए कंसोल को `--no-apply` के साथ शुरू करें।
लॉगिन प्रयास थ्रॉटल किए जाते हैं। इसलिए नहीं कि पासवर्ड अनुमान लगाने योग्य है — यह जनरेट किया गया है, 144 बिट्स — बल्कि इसलिए कि एक को सत्यापित करना Argon2id चलाता है, और एक अनऑथेंटिकेटेड कॉलर को जितनी तेज़ी से वह पोस्ट कर सकता है उतनी तेज़ी से उसे चलाने देने से उस होस्ट के विरुद्ध denial of service होता है जिसकी रक्षा यह टूल करने वाला है। दस गलत प्रयास मुफ़्त हैं; उसके बाद एक क्लाइंट घातीय रूप से पीछे हटता है, और एक वैश्विक कैप CPU को सीमित करता है चाहे प्रयास कितने भी पतों से आएँ।
## कंटेनर में NGINX चलाना
यदि NGINX Docker में है और उसका कॉन्फ़िग बाइंड माउंट पर है, तो `systemctl reload nginx` कुछ भी रीलोड नहीं करता। इसके बजाय दोनों कमांड को कंटेनर पर लक्षित करें — यह CLI और TUI पर भी लागू होता है:```
stop-bots set-nginx-commands \
--test "docker exec web nginx -t" \
--reload "docker exec web nginx -s reload"
कमांड को शब्दों में विभाजित किया जाता है और सीधे चलाया जाता है। यह कभी भी शेल से नहीं गुजरता, इसलिए ;,
| और $VAR सामान्य अक्षर हैं, सिंटैक्स नहीं।
कोड कैसे व्यवस्थित है, इसका परीक्षण कैसे किया जाता है, और इसे किन नियमों के अनुसार लिखा गया है, यह CONTRIBUTING.md में है। रिलीज़ प्रक्रिया RELEASING.md में है।
आप मुझसे [email protected] पर संपर्क कर सकते हैं।
Copyright (C) 2026 Marko Ivankovic
यह प्रोग्राम मुक्त सॉफ़्टवेयर है: आप इसे GNU Affero General Public License के अनुसार, जैसा कि Free Software Foundation द्वारा प्रकाशित है, या तो लाइसेंस के संस्करण 3, या (आपके विकल्प पर) किसी भी बाद के संस्करण के अंतर्गत, पुनर्वितरित और/या संशोधित कर सकते हैं।
लाइसेंस का पूरा पाठ LICENSE फ़ाइल में देखें।
वैकल्पिक लाइसेंसिंग उपलब्ध नहीं है।
robots.txtSTALENOT BLOCKED/BLOCKED (लाल रंग में दिखाया गया) टैग के साथ।
Tab/Shift+Tab स्विच करते हैं कि Up/Down दो पैनलों में से किस पर लागू हों; f एक
साझा फ़िल्टर चक्रित करता है (all / not blocked only / blocked only); Enter चयनित
NOT BLOCKED पंक्ति को ब्लॉक करता है, या यदि यह पहले से BLOCKED है तो अनब्लॉक करता है।
i चयनित पते का निरीक्षण करता है: प्रतिष्ठा फ़ीड्स में से कौन इसे सूचीबद्ध करता है, क्या
यह किसी प्रकाशित क्रॉलर रेंज के भीतर है (जो एक असली Googlebot को केवल ऐसा कहने वाले
user agent से अलग करता है), यह किस देश का है, और इसने किन खातों के रूप में लॉग इन करने
का प्रयास किया। यह सब उन सूचियों से है जो इस होस्ट ने पहले ही डाउनलोड कर ली हैं — यहाँ
कोई reverse DNS या whois लुकअप नहीं है, क्योंकि PTR रिकॉर्ड वह लिखता है जो पते का धारक
होता है और वह हमलावर-आपूर्ति किया गया टेक्स्ट होगा जो आधिकारिक पढ़ा जाता है।| नियम | बॉट्स के अलावा इन्हें दूर करता है |
|---|---|
| HTTP/1.0 और HTTP/1.1 | क्रॉलर और API क्लाइंट जो HTTP/2 नहीं बोलते |
कोई Accept हेडर नहीं | कुछ API क्लाइंट कोई नहीं भेजते |
कोई Accept-Language नहीं | प्राइवेसी टूलिंग इसे हटा देती है |
खाली/अनुपस्थित User-Agent | स्क्रिप्ट और हेल्थ चेक अक्सर इसे छोड़ देते हैं |
Host एक बेयर IP है | IP से साइट तक पहुँचना टूट जाता है |
| TLS 1.0 / 1.1 | केवल बहुत पुराने क्लाइंट |
इन सभी पर दो सुरक्षा उपाय लागू होते हैं, और इन्हें आप पर छोड़ने के बजाय लागू किया जाता है:
server ब्लॉकों में लिखे जाते हैं। ब्राउज़र TLS के
बिना HTTP/2 नहीं करते, इसलिए एक सादे listen 80 ब्लॉक पर हर अनुरोध HTTP/1.1 होता है —
जिसमें वह रीडायरेक्ट भी शामिल है जो ब्राउज़र HTTPS की ओर जाते समय करता है। आपके port-80
और port-443 ब्लॉक आमतौर पर एक ही server_name साझा करते हैं, इसलिए सेटिंग दोनों तक
पहुँचती है; केवल TLS वाले को ये नियम मिलते हैं। हेडर-आकार नियम सादे HTTP पर काम करते हैं
और दोनों में लिखे जाते हैं।/.well-known/ हमेशा मुक्त रहता है। यहीं Let's Encrypt अपना
HTTP-01 चैलेंज लाता है, HTTP/1.1 पर बिना Accept और अक्सर बिना User-Agent के —
छूट के बिना आपका प्रमाणपत्र हफ्तों बाद नवीनीकरण करना बंद कर देता है।| विकल्प | यह किसके लिए है |
|---|
403 Forbidden (डिफ़ॉल्ट) | कहता है कि ब्लॉक जानबूझकर था; केवल यही वह है जिस पर गलती से पकड़ा गया मानव कार्रवाई कर सकता है |
404 Not Found | छिपाता है कि कुछ ब्लॉक किया गया था ही |
410 Gone | सुव्यवहार वाले क्रॉलरों से URL को हमेशा के लिए छोड़ने का अनुरोध करता है — जब आप हमलावरों के बजाय क्रॉलरों को दूर कर रहे हों तो 403 की तुलना में इसे प्राथमिकता दें |
429 Too Many Requests | एक विनम्र क्लाइंट से पीछे हटने और पुनः प्रयास करने को कहता है |
418 I'm a teapot | RFC 2324 का मज़ाक। यह काम करता है; यह बस IANA-पंजीकृत नहीं है, और NGINX इसे खाली बॉडी के साथ भेजता है |
444 close connection | कोई उत्तर नहीं; सबसे सस्ता, लेकिन सर्वर के डाउन होने से अप्रभेद्य |
Tarpit | 403 का उत्तर देता है लेकिन बॉडी को एक बाइट प्रति सेकंड की दर से टपकाता है, ताकि क्लाइंट आगे बढ़ने के बजाय प्रतीक्षा करे |
| Method | Endpoint | Description |
|---|
GET | /api/v1/scans | List all scans |
POST | /api/v1/scans | Create a new scan |
GET | /api/v1/scans/{id} | Get scan details |
DELETE | /api/v1/scans/{id} | Delete a scan |
GET | /api/v1/results/{id} | Get scan results |
--helpKITPLOIT_OUTPUT| डिफ़ॉल्ट आउटपुट प्रारूप सेट करें |
KITPLOIT_CONFIG | कस्टम कॉन्फ़िगरेशन फ़ाइल पथ |
| पैरामीटर | प्रकार | विवरण |
|---|
page | integer | पृष्ठ संख्या (डिफ़ॉल्ट: 1) |
limit | integer | प्रति पृष्ठ आइटम (डिफ़ॉल्ट: 20, अधिकतम: 100) |
category | string | श्रेणी के अनुसार फ़िल्टर करें |
search | string | नाम या विवरण से खोजें |
| स्थिति कोड | विवरण |
|---|
400 | खराब अनुरोध |
401 | अनधिकृत |
403 | निषिद्ध |
404 | नहीं मिला |
429 | बहुत अधिक अनुरोध |
500 | आंतरिक सर्वर त्रुटि |
| location /stop-bots/ { |