
एक ओपन-सोर्स, सेल्फ-होस्टेड AI-संचालित SIEM, EDR और SOAR प्लेटफ़ॉर्म, जो आधुनिक सुरक्षा संचालन के लिए डिज़ाइन किया गया है।
छोटी/मध्यम टीमों के लिए सेल्फ-होस्टेड सुरक्षा स्टैक जिनके पास समर्पित
SOC नहीं है। हर एंडपॉइंट पर एक एजेंट ड्रॉप करें, उन्हें सर्वर की ओर इंगित करें, और आपको
SIEM लॉग, फ़ाइल अखंडता, पैकेज भेद्यताएँ, एक OpenSearch-संचालित
लॉग एक्सप्लोरर, स्वायत्त AI ट्राइएज और एक SOAR प्लेबुक इंजन मिलता है, सब कुछ एक ही
docker compose up में।
"AI" भाग एक स्थानीय रूप से चलने वाला Ollama मॉडल है (डिफ़ॉल्ट llama3.2:3b)।
लॉग कभी भी बॉक्स से बाहर नहीं जाते; कोई OpenAI कुंजी नहीं, कोई Anthropic कुंजी नहीं, कोई
फ़ोन-होम नहीं। यदि आप एक स्मार्ट मॉडल चाहते हैं और आपके पास RAM है, तो इसे .env में बदलें।

Windows और Linux एजेंटों से एकल TCP चैनल पर टेलीमेट्री एकत्र करता है। SIEM इवेंट, अलर्ट, FIM, पैकेज, नेटवर्क कनेक्शन, खुले पोर्ट, Docker गतिविधि, स्क्रीन फ़्रेम।
एंडपॉइंट पर Sigma नियमों के साथ पता लगाता है। 23 MITRE
ATT&CK तकनीकों को कवर करने वाले 23 नियम conf/sigma/builtin/ में शामिल हैं; उनके बगल में
समुदाय नियमसेट ड्रॉप करें। Sigma नामित फ़ील्ड से मेल खाता है न कि टेक्स्ट से, इसलिए
Image|endswith: '\vssadmin.exe' को किसी असंबंधित संदेश में "vssadmin" शब्द दिखने से
पराजित नहीं किया जा सकता — और
CommandLine|utf16le|base64offset|contains एक base64
-EncodedCommand पेलोड के अंदर पढ़ता है, जहाँ सादा टेक्स्ट कमांड लाइन केवल रैपर दिखाती है।
मूल्यांकन कॉर्पस पर मापा गया: 10 में से 9 हमले अकेले Sigma द्वारा पकड़े गए,
9 में से 0 कठिन नकारात्मक झूठे रूप से फ़्लैग किए गए। यह परत नियतात्मक है और
मॉडल अनुपलब्ध होने पर भी काम करती रहती है।
इवेंट्स के बीच सहसंबंध बनाता है, जो कोई भी प्रति-इवेंट नियम नहीं कर सकता। एक एकल
विफल लॉगऑन नियमित है; चालीस सेकंड में एक स्रोत से पाँच खाते विफल होना एक
पासवर्ड स्प्रे है, और उन पाँच इवेंट्स में से किसी एक को देखने से आपको वह कभी नहीं पता चलेगा।
स्प्रे, ब्रूट फोर्स, बार-बार विफलताओं के बाद आने वाली सफलता, और खाता निर्माण या सेवा
इंस्टॉल के विस्फोट को कवर करता है — दोनों प्लेटफार्मों पर,
Windows इवेंट ID से या पार्स किए गए auth.log लाइनों से।
दो दृष्टिकोण बिंदुओं पर चलता है, क्योंकि वे अलग-अलग हमले देखते हैं। एजेंट पर प्रति होस्ट, जहाँ एक मशीन के खिलाफ हमला पूर्ण रूप से दिखाई देता है। और इन्जेस्ट पथ में होस्ट के पार, जहाँ एक स्प्रे जो पचास मशीनों पर एक-एक करके विफलता चला गया दिखाई देता है — कोई भी एकल एजेंट एक से अधिक इवेंट नहीं देखता, और यह अधिक सक्षम हमला है, क्योंकि चौड़ा और उथला स्प्रे करना प्रति-खाता लॉकआउट और प्रति-होस्ट थ्रेशोल्ड दोनों के नीचे रहता है।
Sigma के साथ कुल कवरेज: 27 तकनीकें। हर विंडो प्रति इवेंट के बजाय एक बार फायर करती है, और हर काउंटर सीमित है — हमलावर-आपूर्ति उपयोगकर्ता नाम पर कुंजीबद्ध काउंटर एक मेमोरी थकावट प्रिमिटिव है, पता लगाना नहीं।
नियमों से ही MITRE ATT&CK के लिए डिटेक्शन मैप करता है। नियम
tags: attack.t1490 ले जाते हैं, इसलिए कोई हाथ से रखा मैपिंग टेबल नहीं है जो पुराना हो जाए। कवरेज
पेज तीन स्थितियों को अलग करता है जिन्हें एक एकल "कवरेज %" छिपा देगा:
कवर और देखा गया, कवर और शांत, और बिल्कुल कवर नहीं — अंतिम
केवल वही है जहाँ कंसोल की चुप्पी का कोई मतलब नहीं है।
हर इवेंट को स्थानीय LLM के साथ ट्राइएज करता है। तीन वर्कर समानांतर में चलते हैं:
एक हर आने वाले इवेंट को वास्तविक समय में देखता है, एक ऑपरेटर-संचालित गहरे
स्कैन चलाता है, और एक तय करता है कि रक्षात्मक कार्रवाई करनी है या नहीं
(BLOCK_IP, ISOLATE_HOST, KILL_PROCESS, आदि)।
रक्षात्मक वर्कर के लिए शैडो मोड। AI_SHADOW_MODE=1 फ्लिप करें और
हर स्वायत्त निर्णय SOAR हब में मानव अनुमोदन के लिए चरणबद्ध किया जाता है
भेजे जाने के बजाय। वास्तविक ट्रैफ़िक पर मॉडल को ट्यून करने के लिए उपयोगी
इसे अपने दम पर कार्य करने देने से पहले।
सब कुछ OpenSearch में इंडेक्स करता है ताकि आप अपने फ्लीट को फ़ज़ी / सटीक / स्टार्ट्स-विथ क्वेरी के साथ एक जगह से grep कर सकें।
SOAR प्लेबुक चलाता है जो एक छोटे विज़ुअल एडिटर में बनाई गई हैं, जिसमें मल्टी-स्टेप, प्रति-नोड परिणाम ट्रैकिंग है, मैन्युअल रूप से या AI निर्णय द्वारा ट्रिगर की जा सकती हैं।
भेद्यता स्कैन हर एजेंट के इंस्टॉल किए गए पैकेजों को OSV के खिलाफ स्कैन करता है (ऑनलाइन या आंतरिक मिरर के माध्यम से)।
थ्रेट-इंटेल फ़ीड खींचता है abuse.ch (Feodo, ThreatFox, URLhaus) से एक स्थानीय संकेतक तालिका में, स्टेलनेस प्रूनिंग और एयर-गैप स्विच के साथ।
पुश करने से पहले एजेंट कॉन्फ़िगरेशन को मान्य करता है। YAML पार्स, संरचनात्मक आकार और regex संकलन — एक अमान्य regex मान्य YAML है और चुपचाप उस नियम को अक्षम कर देता है जिसमें वह है।
अंतर्निहित रिमोट डेस्कटॉप WebSocket JPEG स्ट्रीमिंग के माध्यम से, एंडपॉइंट पर अलग VNC इंस्टॉल की आवश्यकता नहीं है।
साइडबार सब कुछ तीन खंडों में समूहित करता है: टेलीमेट्री (डैशबोर्ड, एजेंट, अलर्ट, एसेट, FIM, लॉग, AI), स्वचालन प्रतिक्रिया (रक्षात्मक कार्रवाइयाँ, प्लेबुक, स्वचालन नियम), और प्रशासन।
प्रत्येक नामांकित एजेंट का अपना पृष्ठ बारह टैब के साथ होता है। अवलोकन लाइव संसाधन मीटर, सबसे हाल के SIEM लॉग, एजेंट मेटाडेटा और एक खतरा सारांश दिखाता है:

अलर्ट वह सब कुछ हैं जो एजेंट के अपने सहसंबंध नियम पहले ही फ़्लैग कर चुके हैं। गंभीरता-रंगीन, फ़िल्टर करने योग्य, खोजने योग्य:

AI Analysis टैब स्थानीय LLM का ऑपरेटर-सामना वाला पक्ष है। मैनुअल और स्वचालित स्कैन दोनों यहाँ आते हैं। प्रत्येक अंतर्दृष्टि एक निर्णय चिप ले जाती है, आत्मविश्वास, MITRE संकेतक (जब मॉडल उन्हें लौटाता है), IOC, अगले चरण, और एक View Source बटन जो सटीक लॉग पंक्ति खोलता है जिसे AI ने देखा:

प्रति एजेंट हार्डवेयर, सॉफ़्टवेयर और नेटवर्क सॉकेट। हार्डवेयर टैब सूचीबद्ध करता है हर PnP डिवाइस, सॉफ़्टवेयर इंस्टॉल किए गए पैकेज सूचीबद्ध करता है, नेटवर्क हर TCP/UDP सॉकेट को उसके स्वामित्व वाली प्रक्रिया के साथ सूचीबद्ध करता है:


OpenSearch द्वारा समर्थित क्रॉस-एजेंट खोज। एक एजेंट चुनें, एक डेटासेट चुनें (SIEM इवेंट, सुरक्षा अलर्ट, प्रक्रिया इवेंट, नेटवर्क, FIM, ऑडिट लॉग), और खोजें। पावर उपयोगकर्ताओं के लिए OpenSearch Dashboards (Kibana फोर्क) खोलने के लिए एक बटन भी है:

प्लेटफ़ॉर्म के खिलाफ हर लॉगिन प्रयास, स्थानीय और LDAP दोनों, परिणाम, स्रोत IP और टाइमस्टैम्प के साथ। उपयोगी जब कोई "किसने-कब-लॉगिन-किया" मूड में हो:

आपको होस्ट पर Docker 24+ Compose v2 और Python 3.10+ की आवश्यकता होगी (केवल एक बार के एजेंट बिल्ड चरण के लिए)। पूर्ण स्टैक ~16 GB RAM चाहता है, नीचे सिस्टम आवश्यकताएँ देखें।```bash git clone https://github.com/d3vhex/Sentora.git cd Sentora
cp .env.example .env
python scripts/init_secrets.py
cd Sentora ./build_agent.sh # on Linux/macOS/WSL
cd ..
docker compose up --build -d
Open <http://localhost:8000>। डिफ़ॉल्ट लॉगिन `admin` / `admin123` है।
इसे तुरंत **Users & Roles** के अंतर्गत बदलें।
Ollama पहले बूट पर `llama3.2:3b` को स्वतः पुल करता है। इससे सत्यापित करें:```bash
docker exec sentora-ollama ollama list
एजेंट तैनात करना: Deploy Agent पेज से, उस OS के लिए one-liner कॉपी करें जिसे आप चाहते हैं। लक्ष्य मशीन (admin shell) पर इसे पेस्ट करें। इंस्टॉलर बाइनरी डाउनलोड करता है, एक config डालता है, सर्वर के साथ enrol करता है, और खुद को एक scheduled task / systemd unit के रूप में पंजीकृत करता है।
| Service | Port | Reachable from | Purpose |
|---|---|---|---|
app | :8000 | anywhere | REST API + React UI |
ingest | :5001 | anywhere | TCP log collector (एजेंट यहाँ भेजता है) |
db | :3307 | localhost | MySQL 8.0 (नेटवर्क के अंदर 3306) |
rabbitmq | :5672 / :15672 | localhost | Job queue + management UI |
ollama | :11434 | localhost | Local LLM runtime |
opensearch | :9200 | localhost | Full-text log search |
opensearch-dashboards | :5601 | localhost | Optional Kibana-style explorer |
ai-worker-{automation,manual,defensive} | — | LLM analysis workers |
केवल app और ingest सभी interfaces पर listen करते हैं। बाकी BIND_ADDR
(डिफ़ॉल्ट 127.0.0.1) से बंधे होते हैं, क्योंकि डिफ़ॉल्ट कॉन्फ़िगरेशन में उनमें से कोई भी
authenticate नहीं करता — OpenSearch अपने security plugin को अक्षम करके चलता है और
Dashboards हर एकत्रित log का unauthenticated दृश्य है। किसी को expose करने के लिए
उसे app की तरह उसी reverse proxy और auth के पीछे रखें, न कि BIND_ADDR को
चौड़ा करके।
Log Explorer में "Open Dashboards" बटन सर्वर के hostname पर पोर्ट 5601 से लिंक करता है, इसलिए यह host से ही काम करता है; दूरस्थ operators को उस reverse proxy की आवश्यकता होती है।
| Profile | CPU | RAM | Disk | Notes |
|---|---|---|---|---|
| Lab (≤ 5 agents) | 4 cores | 12 GB | 40 GB SSD | llama3.2:3b, OpenSearch heap 1 GB पर |
| Small team (10–50 agents) | 8 cores | 16 GB | 100 GB SSD | Compose defaults ठीक हैं |
| Production (50+ agents) | 16+ cores | 32 GB+ | 250 GB+ NVMe | OpenSearch और Ollama को अपने अलग hosts पर ले जाएँ |
Idle footprint:
llama3.2:3b): ~3 GB, inference के दौरान अधिकअगर RAM कम है, तो qwen2.5:1.5b या कोई अन्य छोटा Ollama मॉडल अपनाएँ
और OpenSearch heap घटाएँ। GPU आवश्यक नहीं है, लेकिन Ollama
मौजूद होने पर इसे स्वचालित रूप से उपयोग करेगा।
जब defensive worker का verdict ACT होता है, जिसमें confidence ≥
AI_AUTO_ACT_CONF (डिफ़ॉल्ट 0.75) होता है, और अनुशंसित कार्रवाई नीचे दी गई
safe-list पर होती है, तो worker उस कार्रवाई को सीधे एजेंट की
automations तालिका में queue करता है:```
BLOCK_IP KILL_PROCESS RESTART_SERVICE ISOLATE_HOST
DISABLE_USER QUARANTINE_FILE SUSPEND_PROCESS LOGOFF_USER
CONTAINER_ISOLATE CONTAINER_STOP CONTAINER_KILL
### छाया मोड
`.env` में `AI_SHADOW_MODE=1` सेट करें और डिफेंसिव वर्कर वास्तविक कार्रवाइयाँ फायर करना बंद कर देता है। जो निर्णय स्वायत्त प्रतिक्रिया ट्रिगर करते, उन्हें इसके बजाय **प्रस्तावों** के रूप में सहेजा जाता है, जिनमें `source_file = AI_DEFENSIVE_SHADOW` और `shadow_status = pending` होता है। ऑपरेटर **SOAR Hub > Shadow Queue** से प्रत्येक की समीक्षा करता है और या तो:
- **अनुमोदन** > वास्तविक SOAR कार्रवाई (`call_agent_soar`) फायर होती है और प्रस्ताव `approved` (टाइमस्टैम्प + ऑपरेटर नाम के साथ) चिह्नित होता है।
- **अस्वीकृति** > प्रस्ताव वैकल्पिक नोट के साथ `rejected` चिह्नित होता है। कोई कार्रवाई नहीं की जाती।
प्रस्ताव कभी समाप्त नहीं होते; आपके लिए कोई निर्णय नहीं लिया जाता। यह मॉडल को प्रोडक्शन टेलीमेट्री पर चलाने के लिए उपयोगी है, जबकि आप वास्तविक `BLOCK_IP` / `ISOLATE_HOST` आदि जारी करने से पहले उसके निर्णयों पर भरोसा बनाते हैं।
---
## सुरक्षा नोट्स
### प्रमाणीकरण
UI सर्वर-साइड सत्र के साथ प्रमाणित होता है: लॉगिन एक अपारदर्शी टोकन जारी करता है जो `HttpOnly` कुकी में होता है, और `userdb.sessions` प्राधिकरण है। टोकन का केवल SHA-256 संग्रहीत होता है, इसलिए डेटाबेस डंप से कुछ भी प्रस्तुत करने योग्य नहीं मिलता।
दो घड़ियाँ लागू होती हैं, दोनों `.env` में कॉन्फ़िगर करने योग्य हैं:
| सेटिंग | डिफ़ॉल्ट | अर्थ |
| :--- | :--- | :--- |
| `SESSION_IDLE_MINUTES` | `60` | अंतिम अनुरोध के इतने समय बाद सत्र समाप्त हो जाता है |
| `SESSION_ABSOLUTE_HOURS` | `12` | गतिविधि की परवाह किए बिना कठोर सीमा |
| `SESSION_COOKIE_SECURE` | `0` | ऐप के सामने TLS समाप्त होने पर `1` सेट करें |
| `SESSION_COOKIE_SAMESITE` | `Lax` | `Lax` क्रॉस-साइट POST/XHR को ब्लॉक करता है जिसकी CSRF को आवश्यकता होती है |
पासवर्ड बदलने, एडमिन पासवर्ड रीसेट, भूमिका परिवर्तन और खाता विलोपन पर सत्र तुरंत रद्द हो जाते हैं — एक एडमिन किसी की पहुँच हटाता है तो उनका खुला टैब काम करना बंद कर देता है।
हर रूट **डिफ़ॉल्ट रूप से अस्वीकृत** है: वैध सत्र के बिना अनुरोध हैंडलर चलने से पहले ही अस्वीकार कर दिया जाता है। अपवाद हैं लॉगिन एंडपॉइंट, SPA शेल, स्टैटिक एसेट्स, और एजेंट-मुखी एंडपॉइंट, जो इसके बजाय `X-Agent-Key` या एनरोलमेंट टोकन से प्रमाणित होते हैं।
`X-User-ID` अभी भी फ्रंटएंड द्वारा भेजा जाता है, लेकिन यह अब पहचान नहीं है — सर्वर इसे सत्र के विरुद्ध मान्य करता है और बेमेल को अस्वीकार करता है। चूँकि ब्राउज़र CORS प्रीफ़्लाइट के बिना क्रॉस-साइट अनुरोधों में कस्टम हेडर नहीं जोड़ सकते, स्टेट-बदलने वाले अनुरोधों पर इसे आवश्यक बनाना `SameSite` को दूसरे CSRF नियंत्रण के रूप में समर्थन देता है।
रूट सुरक्षा `@require_permission(...)` के साथ घोषित की जाती है और मिडलवेयर द्वारा एक रजिस्ट्री के माध्यम से लागू की जाती है, इसलिए यह लागू होती है चाहे डेकोरेटर `@app.route` के किसी भी ओर हो। बूट लॉग गिनती प्रिंट करता है:```
[Auth] Routes: <n> permission-gated, <n> session-only, <n> public.
यदि वह पंक्ति 0 permission-gated रिपोर्ट करती है, तो RBAC लागू नहीं हो रहा है — इसे
आउटेज मानें।
हर रूट तीन चीजों में से एक होना चाहिए: permission-gated, _PUBLIC_HANDLERS में
सूचीबद्ध, या tests/test_auth_wiring.py में SESSION_ONLY_HANDLERS में नामित,
साथ ही एक टिप्पणी के साथ कि अकेले सत्र पर्याप्त क्यों है। एक टेस्ट इसकी पुष्टि करता है,
इसलिए कोई नया रूट चुपचाप अनियंत्रित नहीं आ सकता — यही कारण है कि run_playbook,
delete_soar_action और test_ldap_connection किसी भी खाते के लिए सुलभ हो गए थे
जो लॉग इन कर सकता था।
एक खाते के लिए पाँच असफल प्रयास, या एक पते से बीस, पंद्रह मिनट के भीतर,
और आगे के प्रयास 429 के साथ अस्वीकार कर दिए जाते हैं जब तक कि विंडो
समाप्त न हो जाए। login_logs से गिना जाता है, जो पहले से ही हर विफलता दर्ज कर रहा था
और जिसे कोई नहीं पढ़ता था — bcrypt ही ऑनलाइन अनुमान लगाने पर एकमात्र ब्रेक था।
| सेटिंग | डिफ़ॉल्ट | अर्थ |
|---|---|---|
LOGIN_MAX_FAILURES_USER | 5 | विंडो में अनुमत प्रति-खाता विफलताएँ |
LOGIN_MAX_FAILURES_IP | 20 | प्रति-पता विफलताएँ; अधिक, क्योंकि एक कार्यालय एक NAT पता साझा करता है |
LOGIN_LOCKOUT_WINDOW_MIN | 15 | विफलताएँ कितनी पीछे तक गिनी जाती हैं |
जाँच पासवर्ड तुलना से पहले चलती है, इसलिए यह ज्ञात और अज्ञात उपयोगकर्ता नाम के बीच
समय का अंतर भी हटा देती है। यदि login_logs अप्राप्य है तो यह खुला विफल होता है:
एक लॉगिन पृष्ठ जो ऑडिट तालिका के डाउन होने के कारण नहीं पहुँचा जा सकता, वह अपने आप में
एक आउटेज है।
X-Forwarded-For केवल TRUSTED_PROXIES में सूचीबद्ध पीयर से स्वीकार किया जाता है
(अल्पविराम से अलग किए गए पते या CIDR, डिफ़ॉल्ट रूप से खाली)। ऐप के सामने कुछ भी न होने पर
हेडर हमलावर-आपूर्ति किया हुआ होता है, इसलिए इसे बिना शर्त मानना — जो यह प्रतिस्थापित
कर रहा था — किसी कॉलर को ऑडिट ट्रेल में कोई भी पता लिखने और उसी अनुरोध में अपनी
रेट सीमा रीसेट करने देता था।```
TRUSTED_PROXIES=10.0.0.0/8,192.168.1.5
जब ऐप सीधे एक्सेस किया जाता है तो इसे खाली छोड़ दें।
### एजेंट का अपना API
एजेंट `0.0.0.0:9099` पर सुनता है और SYSTEM या root के रूप में चलता है। हर रूट के लिए `X-Agent-Key` आवश्यक है; `/self_destruct` के लिए विशेष रूप से इस एजेंट की अपनी एनरोलमेंट कुंजी चाहिए, ताकि लीक हुआ फ्लीट-व्यापी रहस्य एक साथ हर एंडपॉइंट को अनइंस्टॉल न कर सके। `/health` बिना कुंजी के लाइवनेस का उत्तर देता है और बिना कुंजी के और कुछ भी प्रकट नहीं करता।
कोई अनुमेय फ़ॉलबैक नहीं है। एक पुराना बिल्ड किसी भी गैर-खाली कुंजी को स्वीकार करता था जब भी होस्ट पर `AGENT_MASTER_SECRET` सेट नहीं था — जिसे कभी किसी ने सेट नहीं किया, इसलिए यह हर जगह डिफ़ॉल्ट था। एक EDR जो फेल-ओपन होता है वह बिना EDR के भी बदतर है, क्योंकि कंसोल एंडपॉइंट को सुरक्षित के रूप में रिपोर्ट करता है।
`AGENT_BIND` लिसनर को स्थानांतरित करता है। यह अभी भी डिफ़ॉल्ट रूप से `0.0.0.0` है क्योंकि सर्वर इस पोर्ट पर HTTP के माध्यम से एजेंटों तक पहुंचता है; लूपबैक से बाइंडिंग के लिए एक प्रतिस्थापन ट्रांसपोर्ट चाहिए, न कि कॉन्फ़िगरेशन बदलाव।
### CORS
`CORS_ORIGINS` डिफ़ॉल्ट रूप से खाली है। सामान्य डिप्लॉयमेंट में यह ऐप SPA को स्वयं सेवा देता है, इसलिए अनुरोध समान-मूल (same-origin) होते हैं और किसी प्रविष्टि की आवश्यकता नहीं होती। वाइल्डकार्ड को सीधे अस्वीकार कर दिया जाता है: ब्राउज़र कुकीज़ ले जाने वाले किसी भी अनुरोध पर `Access-Control-Allow-Origin: *` को मना कर देते हैं। स्प्लिट-ओरिजिन डिप्लॉयमेंट्स को स्पष्ट ओरिजिन सूचीबद्ध करनी चाहिए और `SESSION_COOKIE_SAMESITE=None` को `SESSION_COOKIE_SECURE=1` के साथ सेट करना चाहिए।
### डिफ़ॉल्ट रहस्य
`.env.example` प्लेसहोल्डर्स के साथ आता है। असली `.env` git-अनदेखा है। प्लेटफ़ॉर्म को `localhost` से परे किसी भी चीज़ के लिए उजागर करने से पहले इन्हें घुमाएँ:
- `DB_PASSWORD`
- `AGENT_SHARED_SECRET` (एजेंट प्रमाणीकरण फ़ॉलबैक)। पहले बूट पर स्वतः-जनरेट होता है यदि सेट नहीं है।
`admin / admin123` लॉगिन को अब याद रखने की आवश्यकता नहीं है: सीडेड खाता `must_change_password` के साथ बनाया गया है, और जब तक वह सेट है, सत्र `/change-password` के अलावा कुछ भी नहीं पहुंच सकता। मिडलवेयर में लागू किया गया है, UI में नहीं, क्योंकि एक फ़्लैग जिसे फ्रंट एंड सम्मान देने के लिए भरोसा किया जाता है वह एक सुझाव है और API curl का भी उत्तर देता है।
### TLS प्रमाणपत्र
कुछ भी एक निजी कुंजी नहीं भेजता। एक काम करने वाला `certs/server.key` और `certs/rootCA.key` पहले कमिट किया गया था, जिसने हर डिप्लॉयमेंट को समान TLS पहचान दी और इसे प्रकाशित किया: जिस किसी ने भी कभी रिपॉजिटरी क्लोन की थी उसके पास कुंजी थी, इसलिए प्रमाणपत्र ने कुछ भी साबित नहीं किया कि दूसरे छोर पर कौन था।
`TLS_ENABLED=1` के साथ और कोई प्रमाणपत्र मौजूद नहीं होने पर, ऐप पहले बूट पर एक उत्पन्न करता है। प्रत्येक इंस्टॉल को अपनी कुंजी मिलती है और कुंजी उस मशीन को कभी नहीं छोड़ती जिसने इसे बनाया। `certs/*.key` और `certs/*.crt` git-अनदेखा हैं।
CA स्व-हस्ताक्षरित है, इसलिए ब्राउज़र चेतावनी देते हैं जब तक आप इसे स्पष्ट रूप से भरोसा नहीं करते। वह चेतावनी ईमानदार है — इसे एक साझा रहस्य से प्राथमिकता दें जो कोई चेतावनी नहीं उत्पन्न करता। किसी भी सार्वजनिक चीज़ के लिए, `TLS_CERT` / `TLS_KEY` को एक वास्तविक प्रमाणपत्र पर इंगित करें; जब वे सेट और अनुपलब्ध हों, तो ऐप स्व-हस्ताक्षरित एक को प्रतिस्थापित करने के बजाय ऐसा कहता है।
हाथ से पुनर्जनरेट करने के लिए:```bash
python certs/generate_certs.py --force
पुरानी कुंजियाँ अभी भी git इतिहास में हैं। इस बदलाव से पहले भेजी गई जोड़ी को जला हुआ मानें; नए इंस्टॉल अब इसका उपयोग नहीं करते।
सर्वर दो Fernet कुंजियों का उपयोग करता है, दोनों पहले बूट पर स्वतः उत्पन्न होती हैं:
| कुंजी | स्थान | सुरक्षा |
|---|---|---|
| Agent कुंजी | data/fernet.key (या FERNET_KEY_PATH) | Agent टेलीमेट्री; /api/agents/bootstrap के माध्यम से वितरित |
| Server कुंजी | .env FERNET_KEY | सर्वर-आंतरिक at-rest फ़ील्ड (जैसे पासवर्ड कॉलम) |
दोनों पर chmod 600 लगाएँ। उनका बैकअप लें। किसी एक को खोने से संबंधित एन्क्रिप्टेड डेटा अपठनीय हो जाता है। अभी तक कोई in-place रोटेशन नहीं है।
दो स्वतंत्र तंत्र, दोनों वैकल्पिक:
प्रति-निर्णय संवर्धन (ai/intel.py)। AI वर्कर लॉग में पाए गए संकेतकों को AlienVault OTX और VirusTotal के विरुद्ध क्रॉस-चेक करता है। OTX_API_KEY / VT_API_KEY की आवश्यकता होती है; अनसेट होने का मतलब कोई बाहरी कॉल नहीं।
संकेतक फ़ीड (core/threat_feeds.py)। threat_intel तालिका को abuse.ch से प्रति घंटे भरता है — Feodo Tracker (बॉटनेट C2 पते), ThreatFox (कॉन्फिडेंस स्कोर के साथ मिश्रित IoCs) और URLhaus (मैलवेयर वितरित करने वाले URL)।
संकेतक last_seen रखते हैं और THREAT_INTEL_STALE_DAYS (डिफ़ॉल्ट 30) के बाद हटा दिए जाते हैं: एक पता जिसने पिछली तिमाही में C2 होस्ट किया था, आमतौर पर अब किसी और का होता है, और इसे रखने से अनिश्चित काल तक गलत सकारात्मक परिणाम मिलते हैं। प्रत्येक फ़ीड THREAT_INTEL_MAX_PER_FEED पंक्तियों पर सीमित है क्योंकि तालिका अलर्ट पथ पर पढ़ी जाती है।
abuse.ch डाउनलोड को मुफ्त खाता कुंजी के पीछे ले जा रहा है। 401/403 लौटाने वाली फ़ीड सर्वर लॉग में ऐसा कहती है; THREAT_INTEL_AUTH_KEY सेट करें।
जाँचें कि वास्तव में क्या आया:```bash docker logs sentora-server | grep ThreatIntel
### एयर-गैप मोड```ini
OSV_MODE=mirror
OSV_MIRROR_URL=http://osv.internal
THREAT_INTEL_MODE=off
# or serve the feeds internally:
# THREAT_INTEL_FEODO_URL=http://mirror.internal/feodo.json
इन्हें सेट करने के साथ, साथ ही OTX_API_KEY / VT_API_KEY अनसेट होने पर, नेटवर्क से कुछ भी बाहर नहीं जाता। फ़ॉन्ट्स बंडल किए गए हैं, Ollama लोकल है, कोई CDN संपर्क नहीं किया जाता।
/api/exposure/report पूरे fleet में, प्रति agent, सबसे खराब पहले, अनपैच्ड पैकेजों और file-integrity घटनाओं की गिनती करता है। यह अपनी खुद की कवरेज रिपोर्ट करता है: complete: false जब किसी agent को पढ़ा नहीं जा सका, क्योंकि आधे fleet से अधिक का योग fleet का कुल योग नहीं है।
जानबूझकर कोई score नहीं है। एंडपॉइंट पहले 100 - vulns*2 - fim*5 को "compliance score" के रूप में लौटाता था — यह किसी framework से मेल नहीं खाता, fleet आकार के साथ स्केल नहीं होता, और किसी भी वास्तविक fleet पर शून्य पर पिन हो जाता है। Severity grading भी इसी कारण से अनुपस्थित है: vulnerabilities_report में कोई severity column नहीं है और इसके fields आराम से encrypted हैं, इसलिए कोई भी grade आविष्कार करना होगा।
POST /<agent>/config/<type> किसी भी चीज़ को sensor तक पहुंचने से पहले validate करता है: YAML parse, structural shape, और — वह परत जो मायने रखती है — regex compilation। एक अमान्य regex पूरी तरह से मान्य YAML है और उस category को चुपचाप अक्षम कर देता है जिसमें वह शामिल है, इसलिए केवल syntax-आधारित जांच इसे सीधे एंडपॉइंट पर धकेल देगी। एडिटर आपके टाइप करते समय उसी एंडपॉइंट के खिलाफ lint करता है और क्लिक करने योग्य line numbers के साथ issues रिपोर्ट करता है।
Agent (Win / Linux) │ TCP frames + REST polling ▼ ingest (:5001) ──► RabbitMQ ──► AI worker fleet (3 modes) │ │ ▼ ▼ MySQL (per-agent _db) ai_analysis_results │ ▼ app (Sanic :8000) ──► React UI + REST + WebSocket screen proxy
The deeper version (per-module layout, schema, AI pipeline, SOAR
autonomy, air-gap surfaces) lives in
[docs/Sentora_Architecture.md](https://github.com/d3vhex/sentora/blob/HEAD/docs/Sentora_Architecture.md).
Operational docs:
| Document | Covers |
| :--- | :--- |
| [Architecture](https://github.com/d3vhex/sentora/blob/HEAD/docs/Sentora_Architecture.md) | Module layout, data flow, auth model, AI pipeline |
| [Production deployment](https://github.com/d3vhex/sentora/blob/HEAD/docs/production-deployment.md) | Sizing, network topology, TLS, backup, monitoring, air-gap |
| [Update runbook](https://github.com/d3vhex/sentora/blob/HEAD/docs/update-runbook.md) | Upgrades, agent rollout, DB migrations, rollback |
| [Progress report](https://github.com/d3vhex/sentora/blob/HEAD/docs/PROGRESS_REPORT.md) | What has changed and why |
---
## Development setup```bash
# 1. Database. Only init_userdb.sql — it creates and selects `userdb`.
#
# db/init.sql is NOT a server-init script. It is the per-agent schema
# template, applied by server.create_tables_if_not_exist() after
# connecting to that agent's own database, which is why it contains no
# CREATE DATABASE or USE. Running it standalone fails at line 5 with
# "No database selected" — the same way it broke every first-time
# `docker compose up` while it was mounted into the MySQL init directory.
mysql -u root -p < db/init_userdb.sql
# 2. Backend. requirements.lock pins every version the image is built
# from; requirements.txt is the loose list it was resolved from.
pip install -r requirements.lock
python app.py
# 3. Ingest (separate terminal)
python server.py
# 4. Frontend dev server
cd frontend
npm install
npm run dev
एक ही स्क्रिप्ट, तीन भूमिकाएँ:```bash WORKER_TYPE=automation python ai_worker.py WORKER_TYPE=manual python ai_worker.py WORKER_TYPE=defensive python ai_worker.py
उत्पादन: `docker-compose.yaml` को यह काम करने दें।
---
## योगदान
PR स्वागत योग्य हैं। खोलने से पहले:
1. Fork → branch → `main` के विरुद्ध PR।
2. जाँचें चलाएँ:```bash
pytest -ra # no MySQL or RabbitMQ needed
python -m compileall -q app.py core security
cd frontend && npx tsc --noEmit && npm run build && cd ..
# With the stack up — enumerates every route and calls it twice
python scripts/api_smoke_test.py
@require_permission(...) में लपेटा जाना चाहिए। बूट लॉग
गिनती प्रिंट करता है; यदि यह 0 permission-gated रिपोर्ट करता है, तो
वायरिंग में कुछ गड़बड़ है, आपके रूट में नहीं।किसी भी फिक्स से बड़ी चीज़ के लिए, पहले एक issue खोलें ताकि हम दृष्टिकोण पर सहमत हो सकें।
. ├── app.py # Sanic API + React SPA host ├── server.py # TCP ingest ├── ai_worker.py # AI worker fleet (3 modes) ├── ai/ │ ├── utils.py # LLM helpers, AI cache, SOAR queueing │ └── intel.py # OTX / VT per-verdict enrichment (opt-in) ├── core/ │ ├── mq.py # RabbitMQ publisher │ ├── opensearch.py # OpenSearch index/search │ ├── config_validation.py # Agent YAML validation (parse, shape, regex) │ └── threat_feeds.py # abuse.ch indicator feeds ├── security/ │ ├── session.py # Server-side session store │ └── ssrf.py # Proxy destination rules ├── scanners/ │ └── vuln.py # Server-side OSV scanner ├── scripts/ │ ├── init_secrets.py # Generate the secrets .env needs │ ├── rotate_db_password.py # Rotate the MySQL root password safely │ └── api_smoke_test.py # Exercise every route against a live server ├── tests/ # pytest; no MySQL or RabbitMQ required ├── frontend/ # React 18 + TS SPA │ └── src/lib/ # Shared logic (playbook action catalogue) ├── Sentora/ # Cross-platform agent ├── certs/ # Self-signed dev certs ├── docs/ # Architecture + screenshots └── docker-compose.yaml
---
## लाइसेंस
AGPL-3.0। देखें [LICENSE](https://github.com/d3vhex/sentora/blob/HEAD/LICENSE)।
उपयोग करें, संशोधित करें, पुनर्वितरित करें। AGPL नियमित GPL के ऊपर जो जोड़ता है:
यदि आप किसी नेटवर्क सर्वर पर संशोधित संस्करण चलाते हैं जहाँ अन्य उपयोगकर्ता
इसके साथ इंटरैक्ट करते हैं, तो आपको संशोधन भी AGPL के तहत प्रकाशित करने होंगे।
- आंतरिक उपयोग के लिए सेल्फ-होस्टिंग → स्रोत-प्रकटीकरण का कोई दायित्व नहीं।
- संशोधित Sentora के ऊपर सार्वजनिक-सामना करने वाला SaaS → आपको संशोधन
प्रकाशित करने होंगे।
- बंद-स्रोत व्युत्पन्न शिप करना चाहते हैं या नेटवर्क-कॉपीलेफ्ट
खंड को छोड़ना चाहते हैं? एक वाणिज्यिक लाइसेंस छूट उपलब्ध है। लेखक से संपर्क करें।
"Sentora" नाम और लोगो परियोजना लेखकों के ट्रेडमार्क हैं और
AGPL द्वारा कवर नहीं हैं। स्वतंत्र रूप से फोर्क करें, लेकिन यदि आप इसे अपने
उत्पाद के रूप में पुनर्वितरित करते हैं तो नाम बदलें।
---
## कम्युनिटी एडिशन में क्या नहीं है
कम्युनिटी एडिशन में शून्य कृत्रिम सीमाएँ हैं: कोई एजेंट सीमा नहीं, कोई
अवधारण सीमा नहीं, कोर पर कोई फीचर गेटिंग नहीं। इसे उतना व्यापक चलाएँ जितना आपका
हार्डवेयर अनुमति देता है।
सशुल्क Pro / Enterprise वितरण एंटरप्राइज़-ग्लू सुविधाएँ जोड़ता है
(SAML/SCIM SSO, मल्टी-टेनेंसी, अनुपालन रिपोर्ट, HA, WORM ऑडिट,
हस्ताक्षरित एयर-गैप अपडेट बंडल, 4-आँखों वाली SOAR स्वीकृतियाँ, प्रीमियम
टिकटिंग/SIEM फ़ॉरवर्डर)। कोर डिटेक्शन क्षमता कभी भी उस दीवार के पीछे
नहीं ले जाई जाती।
यदि इनमें से कोई भी आपकी तैनाती के लिए मायने रखता है,
[संपर्क करें](mailto:[email protected])।