شغّل Zedmos من أي مكان.
كل قدرة في Zedmos تعرضها واجهة وحدة التحكم هي نقطة نهاية REST. يغطي هذا الدليل الطريقتين الآمنتين اللتين يصل بهما نظام بعيد إليها — مفتاح API مباشر، أو وكيل WebSocket في zedmos-console — إضافة إلى مرجع كامل ومصنَّف لنقاط النهاية.
واجهة مباشرة، أو وكيل WebSocket
يصل المساران في النهاية إلى متحكمات /api/zedmos/* نفسها — يختلف النقل وبيانات الاعتماد فقط. اختر واحدًا لكل تكامل.
- يعرض
- جدار حماية OPNsense نفسه (خادم الويب الخاص به). وعلى pfSense يقتصر الحارس المكافئ على الحلقة المحلية — استخدم وكيل WebSocket بدلاً من ذلك.
- النقل
- HTTPS مباشرة إلى واجهة إدارة جدار الحماية.
- بيانات الاعتماد
- مفتاح API لـ OPNsense + سر (مصادقة HTTP Basic). ويستخدم pfSense مفتاحًا وسرًا مولَّدين محليًا، يُقبلان على الحلقة المحلية فقط.
- تحديد النطاق
- قائمة ACL واحدة في OPNsense — page-services-zedmos — تحرس كل نقطة نهاية (قراءة وكتابة). لا نطاق مدمج للقراءة فقط. وعلى pfSense الحارس المكافئ هو صلاحية Zedmos ACL.
- الأنسب لـ
- شريك على قطاع موثوق / VPN بين المواقع، أو شريك يمكنك تقييده بعنوان IP.
- يعرض
- محور Zedmos السحابي (zedmos-backend). يتصل جدار الحماية خارجًا به.
- النقل
- يفتح جدار الحماية نفق wss:// صادرًا إلى المحور؛ ويستدعي الشريك واجهة REST في المحور.
- بيانات الاعتماد
- رمز جلسة وحدة تحكم المحور (Bearer). ويُسجَّل جدار الحماية بـ tenant_id + node_id + agent_secret (HMAC).
- تحديد النطاق
- إعداد مسبق لقائمة سماح لكل مسار على العميل، إضافةً إلى ACL مفتاح API المحلي، إضافةً إلى عزل المستأجرين في المحور.
- الأنسب لـ
- إدارة SaaS / متعددة المستأجرين، أو جدران حماية خلف NAT، أو أي شيء يجب ألا تعرضه للوارد.
بداية سريعة
على OPNsense تستخدم الواجهة المباشرة مفتاح API لـ OPNsense + سرًا عبر HTTP Basic. وتتلقى الاستدعاءات غير المصادَقة HTTP 302 (إعادة توجيه إلى تسجيل الدخول)، لا 401. واستدعاءات مفتاح API معفاة من CSRF. وعلى pfSense يقتصر حارس الواجهة المحلية على الحلقة المحلية، فتمرّ التكاملات البعيدة عبر وكيل WebSocket.
# OPNsense only - on pfSense use the WebSocket-proxy example below
# 1) Create an API key in OPNsense: System > Access > Users > API keys
# The user must hold the "Services: Zedmos" privilege (page-services-zedmos).
KEY='....' # OPNsense API key
SECRET='....' # OPNsense API secret
# Read — list policy groups
curl -s -u "$KEY:$SECRET" \
https://fw.example.com/api/zedmos/policies/groups
# -> {"groups":[{"name":"Default","status":true}, ...]}
# Write — block a domain globally (POST, JSON body)
curl -s -u "$KEY:$SECRET" -H 'Content-Type: application/json' \
-d '{"type":"host","value":"badsite.com","global":true}' \
https://fw.example.com/api/zedmos/policies/block
# -> {"status":"ok"}const base = "https://fw.example.com";
const auth =
"Basic " + Buffer.from(`${process.env.ZED_KEY}:${process.env.ZED_SECRET}`).toString("base64");
async function zed(path, { method = "GET", body } = {}) {
const r = await fetch(`${base}/api/zedmos${path}`, {
method,
headers: { Authorization: auth, ...(body ? { "Content-Type": "application/json" } : {}) },
body: body ? JSON.stringify(body) : undefined,
});
if (r.status === 302) throw new Error("auth failed (redirect to login)");
return r.json();
}
const groups = await zed("/policies/groups");
await zed("/policies/block", {
method: "POST",
body: { type: "category", value: "AdultContent", group: "Strict" },
});# The partner never talks to the firewall directly — it calls the hub,
# which routes the call down the firewall's outbound socket.
curl -s -X POST https://www.zedmos.com/api/agent/proxy/http \
-H "Authorization: Bearer $CONSOLE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": "69fb...",
"node_id": "6a0d...",
"method": "GET",
"url": "/api/zedmos/policies/groups"
}'
# -> {"status":"ok","response":{"status":200,"body":"{\"groups\":[...]}","error":null}}الطريقة الأكثر أمانًا لعرض هذا
لشركة خارجية لا تتحكم فيها بالكامل، فضّل وكيل WebSocket: دون منفذ وارد، وقائمة سماح لكل مسار، وعزل للمستأجرين، وإلغاء مركزي. واستخدم الواجهة المباشرة فقط على قطاع موثوق / VPN، ومحصَّنة دائمًا.
قائمة ACL واحدة تحرس كل شيء
تغطي page-services-zedmos كل نقطة نهاية /api/zedmos/*، قراءةً وكتابةً. لا توجد صلاحية Zedmos لكل نقطة نهاية أو للقراءة فقط. قيّد نطاق الشريك بقواعد الشبكة أو قائمة سماح وكيل WS بدلاً من ذلك.
مفاتيح API تتجاوز CSRF
استدعاءات مفتاح API معفاة من رمز مكافحة CSRF (تحتاجه جلسات المتصفح فقط في غير GET). وتعدّل بعض نقاط النهاية أيضًا عند GET دون حارس طريقة — لا بأس بذلك للمفاتيح، لكن قيّد الطرق عند وكيل عكسي إذا عرضتها.
HTTPS دائمًا، ومقيَّد بعنوان IP دائمًا
ترتبط الواجهة بكل الواجهات (*:80 في المختبر). للاستخدام عن بُعد، حوّل WebGUI إلى HTTPS بشهادة صالحة وقيّد منفذ الإدارة بقاعدة جدار حماية إلى عناوين IP المصدرية للشريك.
فضّل وكيل WS للأطراف الثالثة
لا يفتح منفذًا واردًا، ويقيّد بالضبط المسارات التي يجوز للشريك استدعاؤها (قائمة سماح)، ويعزل المستأجرين، وقابل للإلغاء مركزيًا (شاهد قبر موقّع). القناة الموصى بها للمكاملين غير الموثوقين.
التوصية
وكيل WS للأطراف الثالثة غير الموثوقة. والواجهة المباشرة فقط خلف HTTPS + قاعدة جدار حماية لمنفذ الإدارة مقصورة على عناوين IP المصدرية للشريك، مع مستخدم خدمة مخصص لا يحمل سوى page-services-zedmos.
The policies.json schema
Every key the partner can read via /policies/get and write via /policies/groupsave or /policies/save. Schema 1.1.0. Allowed values and defaults are taken from the document's own built-in docs.
بنية الوثيقة
eval — ترتيب التقييم
evalgroups[] — كائن مجموعة السياسات
Identity
groups[]Selectors — who the group applies to
groups[].selectorsA flow joins this group when its selectors match. Empty arrays = no constraint on that axis.
Overrides
groups[].overridesExclusions
groups[].exclusionsAllow-list overrides that exempt matching traffic from this group's blocks.
Security catalogs (threat categories)
groups[].securityEach boolean enables blocking of one threat-intel catalog. basic_mode/advanced_mode are convenience presets; the `essential{}` and `advanced{}` objects mirror the flat booleans.
Application control (L7 app-ID)
groups[].appsEncrypted-transport control
groups[].transportFirst-install default: all 'allow'. Switch to 'block' to enforce.
TLS inspection (MITM)
groups[].tlsNetwork (L3/L4) blocks
groups[].networkHard early-drops via fast-reject before rules[] runs. Use a rule with is_exception+action:allow to punch a hole.
Web filtering
groups[].webAI Security & DLP
groups[].web.dlpPer-group only — globals.web.dlp is a TEMPLATE the engine ignores. First-install default: OFF.
File / AV scanning
groups[].file.scanDNS control
groups[].dnsETA · Identity · Geo · Risk · TI · IDS
groups[].{eta,identity,geo,risk,ti,ids}Action handlers
groups[].actionsConfigured at group level; a rule references them via its `action`. Most fire only on a DROP-class decision (pair with action:drop). Placeholders $src, $dst, $rule_id.
App Routing
groups[].routingRules (ordered, fine-grained)
groups[].rules[]Optional per-group ordered rule list evaluated after early-drops. Each rule matches on fields and fires one action.
// POST /api/zedmos/policies/groupsave — Content-Type: application/json
// Upsert one group (only the keys you send are changed; rest is preserved).
{
"name": "Strict",
"status": true,
"description": "Locked-down VLAN",
"selectors": { "vlans": [30], "direction": "any" },
"overrides": { "block_all": false, "block_untrusted": true, "schedule": "work-hours" },
"security": { "basic_mode": "high", "malware_virus": true, "phishing": true },
"apps": { "categories_block": ["adultcontent", "gaming"] },
"transport":{ "quic_strategy": "block", "doh_strategy": "block" },
"tls": { "enable_inspection": true, "bump_mode": "force", "min_version": "1.2" },
"dns": { "block_domains": ["coin-hive.com"], "dga": "block", "tunnel": "block" },
"web": { "dlp": { "enable": true, "mode": "regex_only", "action": "block",
"presets": ["cc_luhn","iban","email_pii"] } },
"file": { "scan": { "mode": "block", "action": "block", "engines": ["clamav"] } },
"ids": { "mode": "prevent", "block_max_priority": 2 },
"rules": [
{ "is_exception": true, "action": "allow", "mode": "any",
"dst_domain": ["intranet.corp"], "comment": "always allow intranet" }
]
}globals — الإعدادات الافتراضية والكتالوجات ومقابض المحرك
Engine knob registry
globals.engineOperator-tunable hot-path knobs. Precedence: value here > env DG_* > hardcoded default. Atomic publish on policy reload.
Global catalogs & defaults
globals.{security,ti,quarantine,schedules,exclusions}// POST /api/zedmos/policies/globals — set global blacklists / actions
{
"exclusions": { "domains": ["windowsupdate.com"], "src_cidrs": ["10.0.0.0/8"] },
"ti": { "domain_block": ["evil.example"], "ip_block": ["203.0.113.7"] },
"schedules": [
{ "name": "work-hours", "start": "08:00", "end": "18:00",
"days": ["Mon","Tue","Wed","Thu","Fri"] }
]
}كل فئة
مجمَّعة تمامًا كما في وحدة التحكم: السياسات أولاً، ثم الإعدادات والإشعارات والتقارير والمباشر والبقية. المسارات نسبية إلى أساس كل فئة.
/api/zedmos/policiesالسطح الرئيسي. يقود policies.json — المجموعات والإعدادات العامة وكتالوج الأمن وفئات التطبيقات وإعدادات DLP المسبقة والاستخبارات التهديدية.
/api/zedmos/settingsأكبر سطح (~62 إجراءً): TLS/CA، والواجهات والعمّال، وIDS/ETA/TI، وwriterd والتخزين، وAD/الهوية، ووحدة التحكم السحابية، والتعرف على الأجهزة، والتحكم في الحركة.
/api/zedmos/notificationsتغذية التنبيهات + الموزّع. المتحكم الوحيد ببوابة تفويض خاصة به (canModify: مستخدم الجلسة، أو الحلقة المحلية/المضيف نفسه). التكوين في notifications.json.
/api/zedmos/reportsنقاط نهاية رسوم بيانية للقراءة فقط فوق قاعدة بيانات التدفقات. تفرض كلها POST في dispatch() كي تستطيع الواجهة استدعاءها بـ XHR GET؛ ومع مفتاح API استدعِ أي الطريقتين. المعاملات الشائعة: hours (1–168)، وsince/until (ms)، وmode (session/packet/volume). يعيد معظمها {labels, values}.
/api/zedmos/liveتغذيات شبه فورية. استعلم بمؤشر since (تستخدم الواجهة الاستعلام الدوري — لا WebSocket/SSE على الصندوق). المعاملات الشائعة: hours (6)، وsince (ms)، وlimit (1000، 10–2000)، إضافة إلى المرشّحات الذكية (filters_<ep>، sf_*).
/api/zedmos/dashboardمؤشرات أداء مجمَّعة، وقياس النظام عن بُعد (المعالج/الحرارة/القرص)، وحالة الميزات، والتحكم في الخدمات / التحديثات.
/api/zedmos/deviceجرد الأجهزة + دورة الحياة. يستخدم وسيطات مسار موضعية لإجراءات <id>، مثل /device/trust/42.
/api/zedmosمتحكمات إضافية، ملخَّصة. يتبع كلٌّ منها اصطلاح /api/zedmos/<slug>/<command> نفسه والمصادقة نفسها.
المسار B، بالتفصيل
يتصل جدار الحماية خارجًا بالمحور؛ ويستدعي الشريك واجهة REST في المحور، التي تنقل الاستدعاء عبر المقبس. ويفرض العميل قائمة سماح لكل طلب قبل لمس الواجهة المحلية.
واجهة REST في المحور — ما يستدعيه الشريك
إعدادات قوائم السماح المسبقة (حدود كل طلب)
core-read-only~364 نقطة نهاية GET للقراءة فقط عبر 24 وحدة. افتراضي آمن.firewall-adminقراءة+كتابة كاملة لـ firewall/* + قراءة فقط لـ core/diag/interfaces.network-adminكامل interfaces/* وroutes/* وrouting/* + قراءة فقط لـ core/diag.vpn-adminكامل ipsec/* وopenvpn/* وwireguard/* (على القرص؛ اختره عبر custom).ids-monitorكامل ids/* + قراءة فقط لـ core/diag (على القرص؛ اختره عبر custom).full-adminكل شيء، كل وحدة. «يعادل التجاوز». لا تشحنه إلى الشركاء.لا تتضمن أي من الإعدادات المسبقة المشحونة /api/zedmos/*. لتكامل السياسات، استخدم قائمة سماح مخصصة:
# Custom allowlist for a policies integration (config.json patterns / preset=custom)
/api/zedmos/policies/*
/api/zedmos/settings/*
# optional read-only telemetry
/api/zedmos/dashboard/*
/api/zedmos/live/*
/api/zedmos/reports/*بروتوكول الرسائل (مرجع)
المحور ← العميل: {"type":"http","requestId","method","url","body","timeoutMs"}\nالعميل ← المحور: {"type":"httpResponse","requestId","status","body","error"}\nالمصافحة: يرسل المحور رقم تحدٍّ عشوائيًا؛ ويرد العميل بـ HMAC-SHA256(agent_secret, "tenant|node|ts|nonce")؛ ويرد المحور بـ hello_ack. الإلغاء عبر شاهد قبر موقّع.مرجع نثري كامل بكل نقطة نهاية ومعامل: docs/ZEDMOS_API_REFERENCE.md في المستودع.