الانتقال إلى المحتوى الرئيسي
ميزة حساسة أمنيًا. يفوض هذا الوضع المصادقة بالكامل إلى الوكيل العكسي لديك. قد يؤدي سوء التهيئة إلى تعريض Gateway لديك لوصول غير مصرح به. اقرأ هذه الصفحة بعناية قبل التفعيل.

متى تستخدمه

استخدم وضع مصادقة trusted-proxy عندما:
  • تشغّل OpenClaw خلف وكيل مدرك للهوية (Pomerium، Caddy + OAuth، nginx + oauth2-proxy، Traefik + forward auth).
  • يتولى الوكيل لديك كل المصادقة ويمرر هوية المستخدم عبر الترويسات.
  • تكون في بيئة Kubernetes أو حاويات حيث يكون الوكيل هو المسار الوحيد إلى Gateway.
  • تواجه أخطاء WebSocket ‏1008 unauthorized لأن المتصفحات لا يمكنها تمرير الرموز في حمولات WS.

متى لا تستخدمه

  • إذا كان الوكيل لديك لا يصادق المستخدمين (مجرد منهٍ لـ TLS أو موازن تحميل).
  • إذا كان هناك أي مسار إلى Gateway يتجاوز الوكيل (ثغرات في الجدار الناري، وصول عبر الشبكة الداخلية).
  • إذا لم تكن متأكدًا مما إذا كان الوكيل لديك يزيل/يستبدل الترويسات المعاد توجيهها بشكل صحيح.
  • إذا كنت تحتاج فقط إلى وصول شخصي لمستخدم واحد (فكر في Tailscale Serve + loopback لإعداد أبسط).

كيف يعمل

1

يصادق الوكيل المستخدم

يصادق الوكيل العكسي المستخدمين (OAuth، OIDC، SAML، وما إلى ذلك).
2

يضيف الوكيل ترويسة هوية

يضيف الوكيل ترويسة تحتوي على هوية المستخدم المصادق عليه (مثل x-forwarded-user: nick@example.com).
3

يتحقق Gateway من المصدر الموثوق

يتحقق OpenClaw من أن الطلب جاء من عنوان IP لوكيل موثوق (مهيأ في gateway.trustedProxies).
4

يستخرج Gateway الهوية

يستخرج OpenClaw هوية المستخدم من الترويسة المهيأة.
5

التفويض

إذا نجحت كل الفحوصات، يتم تفويض الطلب.

سلوك الاقتران في واجهة التحكم

عندما يكون gateway.auth.mode = "trusted-proxy" نشطًا ويمر الطلب فحوصات الوكيل الموثوق، يمكن لجلسات WebSocket في واجهة التحكم الاتصال من دون هوية اقتران جهاز. آثار النطاق:
  • تتصل جلسات WebSocket لواجهة التحكم من دون جهاز، لكنها لا تتلقى أي نطاقات مشغّل افتراضيًا. يفرغ OpenClaw قائمة النطاقات المطلوبة إلى [] حتى لا تتمكن جلسة غير مرتبطة بجهاز/رمز مقترن وموافق عليه من إعلان الأذونات ذاتيًا.
  • إذا فشلت الطرق مع missing scope بعد اتصال WebSocket ناجح، فاستخدم HTTPS حتى يتمكن المتصفح من إنشاء هوية جهاز وإكمال الاقتران. راجع HTTP غير الآمن لواجهة التحكم.
  • لكسر الزجاج فقط: يحافظ gateway.controlUi.dangerouslyDisableDeviceAuth=true على النطاقات المطلوبة حتى من دون هوية جهاز. هذا خفض أمني شديد؛ تراجع عنه سريعًا. راجع HTTP غير الآمن لواجهة التحكم.
تحديد نطاقات الوكيل العكسي:
  • إذا أرسل الوكيل لديك x-openclaw-scopes في طلب ترقية WebSocket لواجهة التحكم، فإن OpenClaw يحد نطاقات الجلسة إلى تقاطع النطاقات المطلوبة والنطاقات المعلنة. لا تمنح هذه الترويسة نطاقات؛ إنها تضيق فقط ما يمكن للجلسة امتلاكه.
الآثار:
  • لم يعد الاقتران البوابة الأساسية للوصول إلى واجهة التحكم في هذا الوضع.
  • تصبح سياسة مصادقة الوكيل العكسي وallowUsers لديك هي التحكم الفعلي في الوصول.
  • أبقِ دخول Gateway مقصورًا على عناوين IP الخاصة بالوكلاء الموثوقين فقط (gateway.trustedProxies + الجدار الناري).
عملاء WebSocket المخصصون ليسوا جلسات واجهة التحكم. لا يمنح gateway.controlUi.dangerouslyDisableDeviceAuth نطاقات لعملاء عشوائيين بشكل client.mode: "backend" أو عملاء مشابهين لـ CLI. يجب أن تستخدم الأتمتة المخصصة هوية الجهاز/الاقتران، أو مسار مساعد backend المحلي المباشر المحجوز client.id: "gateway-client"، أو Plugin ‏admin HTTP RPC عندما يكون سطح طلب/استجابة HTTP أكثر ملاءمة.

التهيئة

{
  gateway: {
    // Trusted-proxy auth expects requests from a non-loopback trusted proxy source by default
    bind: "lan",

    // CRITICAL: Only add your proxy's IP(s) here
    trustedProxies: ["10.0.0.1", "172.17.0.1"],

    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        // Header containing authenticated user identity (required)
        userHeader: "x-forwarded-user",

        // Optional: headers that MUST be present (proxy verification)
        requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],

        // Optional: restrict to specific users (empty = allow all)
        allowUsers: ["nick@example.com", "admin@company.org"],

        // Optional: allow a same-host loopback proxy after explicit opt-in
        allowLoopback: false,
      },
    },
  },
}
قواعد مهمة وقت التشغيل
  • ترفض مصادقة الوكيل الموثوق الطلبات ذات مصدر loopback ‏(127.0.0.1، ::1، ونطاقات CIDR الخاصة بـ loopback) افتراضيًا.
  • الوكلاء العكسيون عبر loopback على المضيف نفسه لا يستوفون مصادقة الوكيل الموثوق إلا إذا ضبطت صراحة gateway.auth.trustedProxy.allowLoopback = true وأدرجت عنوان loopback في gateway.trustedProxies.
  • يثق allowLoopback بالعمليات المحلية على مضيف Gateway بالدرجة نفسها التي يثق بها بالوكيل العكسي. فعّله فقط عندما يظل Gateway محميًا بجدار ناري من الوصول البعيد المباشر، ويزيل الوكيل المحلي أو يستبدل ترويسات الهوية التي يزودها العميل.
  • يجب على عملاء Gateway الداخليين الذين لا يمرون عبر الوكيل العكسي استخدام gateway.auth.password / OPENCLAW_GATEWAY_PASSWORD، وليس ترويسات هوية الوكيل الموثوق.
  • لا تزال عمليات نشر واجهة التحكم غير loopback تحتاج إلى gateway.controlUi.allowedOrigins صريح.
  • دليل الترويسات المعاد توجيهها يتجاوز محلية loopback للتراجع المحلي المباشر. إذا وصل طلب عبر loopback لكنه حمل دليل ترويسة Forwarded، أو أي X-Forwarded-*، أو X-Real-IP، فإن ذلك الدليل يستبعد تراجع كلمة المرور المحلي المباشر وبوابة هوية الجهاز. مع allowLoopback: true، يمكن لمصادقة الوكيل الموثوق أن تقبل الطلب رغم ذلك كطلب وكيل على المضيف نفسه، بينما يستمر تطبيق requiredHeaders وallowUsers.

مرجع التهيئة

gateway.trustedProxies
string[]
مطلوب
مصفوفة عناوين IP للوكلاء المطلوب الوثوق بها. تُرفض الطلبات من عناوين IP الأخرى.
gateway.auth.mode
string
مطلوب
يجب أن تكون "trusted-proxy".
gateway.auth.trustedProxy.userHeader
string
مطلوب
اسم الترويسة التي تحتوي على هوية المستخدم المصادق عليه.
gateway.auth.trustedProxy.requiredHeaders
string[]
ترويسات إضافية يجب أن تكون موجودة حتى يكون الطلب موثوقًا.
gateway.auth.trustedProxy.allowUsers
string[]
قائمة سماح لهويات المستخدمين. الفراغ يعني السماح لكل المستخدمين المصادق عليهم.
gateway.auth.trustedProxy.allowLoopback
boolean
دعم اختياري صريح للوكلاء العكسيين عبر loopback على المضيف نفسه. القيمة الافتراضية هي false.
فعّل allowLoopback فقط عندما يكون الوكيل العكسي المحلي هو حد الثقة المقصود. يمكن لأي عملية محلية قادرة على الاتصال بـ Gateway محاولة إرسال ترويسات هوية الوكيل، لذلك أبقِ الوصول المباشر إلى Gateway خاصًا بالمضيف واطلب ترويسات يملكها الوكيل مثل x-forwarded-proto أو ترويسة تأكيد موقعة حيث يدعم الوكيل لديك ذلك.

إنهاء TLS وHSTS

استخدم نقطة إنهاء TLS واحدة وطبق HSTS هناك.
عندما يتولى الوكيل العكسي لديك HTTPS لـ https://control.example.com، اضبط Strict-Transport-Security عند الوكيل لذلك النطاق.
  • مناسب لعمليات النشر المواجهة للإنترنت.
  • يبقي سياسة الشهادة وتقوية HTTP في مكان واحد.
  • يمكن أن يبقى OpenClaw على HTTP عبر loopback خلف الوكيل.
مثال لقيمة الترويسة:
Strict-Transport-Security: max-age=31536000; includeSubDomains

إرشادات الطرح

  • ابدأ أولًا بعمر أقصى قصير (مثل max-age=300) أثناء التحقق من حركة المرور.
  • ارفع إلى قيم طويلة الأمد (مثل max-age=31536000) فقط بعد ارتفاع الثقة.
  • أضف includeSubDomains فقط إذا كان كل نطاق فرعي جاهزًا لـ HTTPS.
  • استخدم التحميل المسبق فقط إذا كنت تستوفي عمدًا متطلبات التحميل المسبق لمجموعة نطاقاتك الكاملة.
  • لا تستفيد بيئة التطوير المحلية عبر loopback فقط من HSTS.

أمثلة إعداد الوكيل

يمرر Pomerium الهوية في x-pomerium-claim-email (أو ترويسات مطالبة أخرى) وJWT في x-pomerium-jwt-assertion.
{
  gateway: {
    bind: "lan",
    trustedProxies: ["10.0.0.1"], // Pomerium's IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-pomerium-claim-email",
        requiredHeaders: ["x-pomerium-jwt-assertion"],
      },
    },
  },
}
مقتطف تهيئة Pomerium:
routes:
  - from: https://openclaw.example.com
    to: http://openclaw-gateway:18789
    policy:
      - allow:
          or:
            - email:
                is: nick@example.com
    pass_identity_headers: true
يمكن لـ Caddy مع Plugin ‏caddy-security مصادقة المستخدمين وتمرير ترويسات الهوية.
{
  gateway: {
    bind: "lan",
    trustedProxies: ["10.0.0.1"], // Caddy/sidecar proxy IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-forwarded-user",
      },
    },
  },
}
مقتطف Caddyfile:
openclaw.example.com {
    authenticate with oauth2_provider
    authorize with policy1

    reverse_proxy openclaw:18789 {
        header_up X-Forwarded-User {http.auth.user.email}
    }
}
يصادق oauth2-proxy المستخدمين ويمرر الهوية في x-auth-request-email.
{
  gateway: {
    bind: "lan",
    trustedProxies: ["10.0.0.1"], // nginx/oauth2-proxy IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-auth-request-email",
      },
    },
  },
}
مقتطف تهيئة nginx:
location / {
    auth_request /oauth2/auth;
    auth_request_set $user $upstream_http_x_auth_request_email;

    proxy_pass http://openclaw:18789;
    proxy_set_header X-Auth-Request-Email $user;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}
{
  gateway: {
    bind: "lan",
    trustedProxies: ["172.17.0.1"], // Traefik container IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-forwarded-user",
      },
    },
  },
}

تهيئة الرموز المختلطة

يرفض OpenClaw التهيئات الملتبسة حيث يكون كل من gateway.auth.token (أو OPENCLAW_GATEWAY_TOKEN) ووضع trusted-proxy نشطين في الوقت نفسه. يمكن أن تتسبب تهيئات الرموز المختلطة في مصادقة طلبات loopback بصمت عبر مسار المصادقة الخاطئ. إذا رأيت خطأ mixed_trusted_proxy_token عند بدء التشغيل:
  • أزل الرمز المشترك عند استخدام وضع الوكيل الموثوق، أو
  • بدّل gateway.auth.mode إلى "token" إذا كنت تقصد المصادقة القائمة على الرموز.
تظل ترويسات هوية الوكيل الموثوق عبر loopback تفشل مغلقة: لا تتم مصادقة المستدعين من المضيف نفسه بصمت كمستخدمي وكيل. يمكن لمستدعي OpenClaw الداخليين الذين يتجاوزون الوكيل المصادقة باستخدام gateway.auth.password / OPENCLAW_GATEWAY_PASSWORD بدلا من ذلك. يظل الرجوع إلى الرمز غير مدعوم عمدا في وضع الوكيل الموثوق.

ترويسة نطاقات المشغل

مصادقة الوكيل الموثوق هي وضع HTTP حامل للهوية، لذلك يمكن للمستدعين اختياريا إعلان نطاقات المشغل باستخدام x-openclaw-scopes في طلبات HTTP API. ملاحظة: تحدد نطاقات WebSocket بواسطة مصافحة بروتوكول Gateway وربط هوية الجهاز. في طلبات ترقية WebSocket الخاصة بـ Control UI، يكون x-openclaw-scopes حدا أقصى لنطاقات الجلسة المتفاوض عليها فقط، وليس منحة. لمعرفة سلوك نطاق WebSocket مع الوكيل الموثوق، راجع سلوك اقتران Control UI. أمثلة:
  • x-openclaw-scopes: operator.read
  • x-openclaw-scopes: operator.read,operator.write
  • x-openclaw-scopes: operator.admin,operator.write
السلوك:
  • عند وجود الترويسة، يحترم OpenClaw مجموعة النطاقات المعلنة.
  • عند وجود الترويسة لكنها فارغة، يعلن الطلب عدم وجود نطاقات مشغل.
  • عند غياب الترويسة، ترجع واجهات HTTP API العادية الحاملة للهوية إلى مجموعة نطاقات المشغل الافتراضية القياسية.
  • تكون مسارات HTTP الخاصة بالـ Plugin لمصادقة Gateway أضيق افتراضيا: عند غياب x-openclaw-scopes، يرجع نطاق التشغيل لديها إلى operator.write.
  • لا تزال طلبات HTTP من أصل المتصفح مطالبة باجتياز gateway.controlUi.allowedOrigins (أو وضع الرجوع المتعمد لترويسة Host) حتى بعد نجاح مصادقة الوكيل الموثوق.
  • بالنسبة إلى جلسات WebSocket الخاصة بـ Control UI، يكون x-openclaw-scopes حدا أقصى للنطاق عند وجوده في طلب الترقية. تؤدي القيمة الفارغة إلى عدم وجود نطاقات.
قاعدة عملية: أرسل x-openclaw-scopes صراحة عندما تريد أن يكون طلب الوكيل الموثوق أضيق من الافتراضيات، أو عندما يحتاج مسار Plugin لمصادقة Gateway إلى شيء أقوى من نطاق الكتابة.

قائمة تدقيق الأمان

قبل تفعيل مصادقة الوكيل الموثوق، تحقق مما يلي:
  • الوكيل هو المسار الوحيد: منفذ Gateway محمي بجدار ناري من كل شيء باستثناء وكيلك.
  • trustedProxies في الحد الأدنى: عناوين IP الخاصة بوكيلك الفعلي فقط، وليس شبكات فرعية كاملة.
  • مصدر وكيل loopback متعمد: تفشل مصادقة الوكيل الموثوق مغلقة لطلبات مصدر loopback ما لم يتم تفعيل gateway.auth.trustedProxy.allowLoopback صراحة لوكيل على المضيف نفسه.
  • الوكيل يزيل الترويسات: يكتب وكيلك فوق ترويسات x-forwarded-* الواردة من العملاء (ولا يضيف إليها).
  • إنهاء TLS: يتولى وكيلك TLS؛ ويتصل المستخدمون عبر HTTPS.
  • allowedOrigins صريح: يستخدم Control UI غير loopback قيمة gateway.controlUi.allowedOrigins صريحة.
  • allowUsers مضبوط (مستحسن): قيد الوصول على المستخدمين المعروفين بدلا من السماح لأي شخص تمت مصادقته.
  • لا يوجد إعداد مختلط للرموز: لا تضبط كلا من gateway.auth.token و gateway.auth.mode: "trusted-proxy".
  • رجوع كلمة المرور المحلية خاص: إذا هيأت gateway.auth.password للمستدعين الداخليين المباشرين، فأبق منفذ Gateway محميا بجدار ناري حتى لا يتمكن العملاء البعيدون غير المارين عبر الوكيل من الوصول إليه مباشرة.

تدقيق الأمان

سيبلغ openclaw security audit عن مصادقة الوكيل الموثوق بنتيجة شدة حرجة. هذا مقصود، فهو تذكير بأنك تفوض الأمان إلى إعداد وكيلك. يتحقق التدقيق من:
  • تذكير/تحذير حرج أساسي gateway.trusted_proxy_auth
  • إعداد trustedProxies مفقود
  • إعداد userHeader مفقود
  • allowUsers فارغ (يسمح لأي مستخدم تمت مصادقته)
  • تفعيل allowLoopback لمصادر الوكيل على المضيف نفسه
  • سياسة أصل المتصفح ذات بدل شامل أو مفقودة على أسطح Control UI المكشوفة

استكشاف الأخطاء وإصلاحها

لم يأت الطلب من عنوان IP موجود في gateway.trustedProxies. تحقق مما يلي:
  • هل عنوان IP الخاص بالوكيل صحيح؟ (يمكن أن تتغير عناوين IP لحاويات Docker.)
  • هل يوجد موزع حمل أمام وكيلك؟
  • استخدم docker inspect أو kubectl get pods -o wide للعثور على عناوين IP الفعلية.
رفض OpenClaw طلب وكيل موثوق مصدره loopback.تحقق مما يلي:
  • هل يتصل الوكيل من 127.0.0.1 / ::1؟
  • هل تحاول استخدام مصادقة الوكيل الموثوق مع وكيل عكسي loopback على المضيف نفسه؟
الإصلاح:
  • فضل مصادقة الرمز/كلمة المرور للعملاء الداخليين على المضيف نفسه الذين لا يمرون عبر الوكيل، أو
  • وجه عبر عنوان وكيل موثوق غير loopback وأبق ذلك العنوان في gateway.trustedProxies، أو
  • بالنسبة إلى وكيل عكسي متعمد على المضيف نفسه، اضبط gateway.auth.trustedProxy.allowLoopback = true، وأبق عنوان loopback في gateway.trustedProxies، وتأكد من أن الوكيل يزيل ترويسات الهوية أو يكتب فوقها.
كانت ترويسة المستخدم فارغة أو مفقودة. تحقق مما يلي:
  • هل وكيلك مهيأ لتمرير ترويسات الهوية؟
  • هل اسم الترويسة صحيح؟ (غير حساس لحالة الأحرف، لكن التهجئة مهمة)
  • هل تمت مصادقة المستخدم فعلا عند الوكيل؟
لم تكن ترويسة مطلوبة موجودة. تحقق مما يلي:
  • إعداد وكيلك لتلك الترويسات المحددة.
  • ما إذا كانت الترويسات تزال في مكان ما ضمن السلسلة.
تمت مصادقة المستخدم لكنه غير موجود في allowUsers. إما أن تضيفه أو تزيل قائمة السماح.
نجحت مصادقة الوكيل الموثوق، لكن ترويسة Origin الخاصة بالمتصفح لم تجتز فحوصات أصل Control UI.تحقق مما يلي:
  • يتضمن gateway.controlUi.allowedOrigins أصل المتصفح الدقيق.
  • لا تعتمد على أصول بدل شامل إلا إذا كنت تريد عمدا سلوك السماح للجميع.
  • إذا كنت تستخدم عمدا وضع الرجوع إلى ترويسة Host، فتم ضبط gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true عن قصد.
يتصل WebSocket، لكن تفشل chat.history أو sessions.list أو models.list مع missing scope: operator.read.الأسباب الشائعة:
  • جلسة Control UI بلا جهاز: يمكن لمصادقة الوكيل الموثوق إدخال اتصال WebSocket بدون هوية جهاز، لكن OpenClaw يمسح النطاقات في الجلسات بلا جهاز حسب التصميم.
  • عميل خلفية مخصص: gateway.controlUi.dangerouslyDisableDeviceAuth محصور في Control UI ولا يمنح نطاقات لعملاء WebSocket عشوائيين من الخلفية أو بشكل شبيه بالـ CLI.
  • x-openclaw-scopes ضيق أكثر من اللازم: إذا كان وكيلك يحقن هذه الترويسة في طلب ترقية WebSocket الخاص بـ Control UI، فستكون نطاقات الجلسة محددة بتلك المجموعة. تؤدي قيمة الترويسة الفارغة إلى عدم وجود نطاقات.
الإصلاح:
  • بالنسبة إلى Control UI، استخدم HTTPS حتى يتمكن المتصفح من إنشاء هوية جهاز وإكمال الاقتران.
  • بالنسبة إلى الأتمتة المخصصة، استخدم هوية الجهاز/الاقتران، أو مسار مساعد الخلفية gateway-client المباشر المحلي المحجوز، أو HTTP RPC للمسؤول.
  • استخدم gateway.controlUi.dangerouslyDisableDeviceAuth: true فقط كمسار مؤقت لكسر الزجاج في Control UI.
تأكد من أن وكيلك:
  • يدعم ترقيات WebSocket (Upgrade: websocket, Connection: upgrade).
  • يمرر ترويسات الهوية في طلبات ترقية WebSocket (وليس HTTP فقط).
  • لا يملك مسارا منفصلا للمصادقة لاتصالات WebSocket.

الترحيل من مصادقة الرمز

إذا كنت تنتقل من مصادقة الرمز إلى الوكيل الموثوق:
1

Configure the proxy

هيئ وكيلك لمصادقة المستخدمين وتمرير الترويسات.
2

Test the proxy independently

اختبر إعداد الوكيل بشكل مستقل (curl مع الترويسات).
3

Update OpenClaw config

حدث إعداد OpenClaw باستخدام مصادقة الوكيل الموثوق.
4

Restart the Gateway

أعد تشغيل Gateway.
5

Test WebSocket

اختبر اتصالات WebSocket من Control UI.
6

Audit

شغل openclaw security audit وراجع النتائج.

ذات صلة