كيفية الحصول على عنوان IP للمستخدم بعد تحديث الالتزام b4a3389

بعد التحديث

أصبح عنوان آخر استخدام لجميع المستخدمين هو بوابة Docker مثل 172.17.0.1

البنية التي أستخدمها هي

Cloudflare → VPS Nginx → Discourse Docker Nginx → Discourse

لديّ إعداد مشابه لما تستخدمه، إليك ما أضفته إلى ملف إعدادات nginx الخاص بالخادم الرئيسي حتى يقوم بتحويل عنوان IP الخاص بالمستخدم:

location / {
  set_real_ip_from 103.21.244.0/22;
  set_real_ip_from 103.22.200.0/22;
  set_real_ip_from 103.31.4.0/22;
  set_real_ip_from 104.16.0.0/13;
  set_real_ip_from 104.24.0.0/14;
  set_real_ip_from 108.162.192.0/18;
  set_real_ip_from 131.0.72.0/22;
  set_real_ip_from 141.101.64.0/18;
  set_real_ip_from 162.158.0.0/15;
  set_real_ip_from 172.64.0.0/13;
  set_real_ip_from 173.245.48.0/20;
  set_real_ip_from 188.114.96.0/20;
  set_real_ip_from 190.93.240.0/20;
  set_real_ip_from 197.234.240.0/22;
  set_real_ip_from 198.41.128.0/17;
  set_real_ip_from 2400:cb00::/32;
  set_real_ip_from 2405:8100::/32;
  set_real_ip_from 2405:b500::/32;
  set_real_ip_from 2606:4700::/32;
  set_real_ip_from 2803:f800::/32;
  set_real_ip_from 2a06:98c0::/29;
  set_real_ip_from 2c0f:f248::/32;

  real_ip_header X-Forwarded-For;

  proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-Proto $scheme;

  proxy_http_version 1.1;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
}

مرحباً @CLOUD_PHT - أهلاً بك في Meta :slight_smile:

أفترض أنك تشغل أكثر من موقع واحد على نفس إعدادات الخادم؟ (مثل موقع ووردبريس + ديسكورس)

المشكلة هي أنك توجه حركة المرور عبر الشبكة الداخلية لـ Docker (من خلال تعيين المنافذ)، مما يخفي جميع الطلبات الواردة على عنوان IP الخاص بـ Docker Gateway (172.17.0.1). وبما أن Nginx الداخلي لا يتعرف على 172.17.0.1 كعنوان IP لـ Cloudflare، فإنه يلقي برأس CF-Connecting-IP لأسباب أمنية.

لحل هذه المشكلة، تحتاج إلى تغيير إعداداتك لاستخدام Unix Socket - هذا يسمح لـ Nginx الخارجي بنقل حركة المرور (والرؤوس) مباشرة إلى Discourse دون أن يعطل Docker عناوين IP.

اتبع هذا الدليل الرسمي، وتأكد من الاحتفاظ بـ cloudflare.template.yml في ملف app.yml الخاص بك عند إعادة البناء.

لقد أصلح هذا الالتزام (commit) خطأً في التكوين كنت تعتمد عليه، ولكنه أيضاً قد يكون سمح لأي مستخدم نهائي بتزوير عنوان الـ IP الخاص به عن طريق تعيين هذا الرأس (header).

إذا كنت واثقاً من أن لا شيء آخر يمكنه التواصل مع حاويتك، فهناك في الواقع طريقة أسهل لا تتطلب استخدام مقبس - لقد كتبت للتو دليلاً حول كيفية القيام بذلك.

بالنسبة لإعدادك @CLOUD_PHT، يجب أن تضيف هذا إلى تعريف الحاوية (إذا كانت هناك قسم run موجود بالفعل، أضف هذه التوجيهات إليه، وإلا أضف قسم run):

run:
  - file:
      path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
      chmod: 644
      contents: |
        real_ip_header x-forwarded-for;
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-host.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.17.0.1;

قد تحتاج أيضاً إلى ما يلي:

  - file:
      # نحتاج إلى تفعيل التكرار (recursive) لأننا سنكون لدينا على الأقل إدخالين؛ واحد من المضيف، وواحد من CloudFlare
      path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
      chmod: 644
      contents: |
        real_ip_recursive on;

اعتماداً على ما إذا كان nginx الذي يعمل على خادمك يقوم بمعالجة رأس Cloudflare لتحديد عنوان IP الحقيقي للمستخدم النهائي (وهو ما يُقترح) أم يضيف فقط رأسه الخاص فوقه. راجع https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372#p-2001772-more-than-one-proxy-7 لمزيد من التفاصيل.


قراء آخرون: انتبهوا إلى أن هذا التوجيه

run:
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-host.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.17.0.1;

غير مناسب لجميع الإعدادات. لا تفعل هذا إلا إذا كانت جميع الاتصالات إلى حاوية Discourse من هذا العنوان موثوقة.

على وجه التحديد، مشكلة معروفة مع إعدادات IPv6 هي أن اتصالات IPv6 إلى الخادم يتم إعادة توجيهها بواسطة docker عبر IPv4 - الطريقة التي يتم بها ذلك تجعل جميع الاتصالات تبدو وكأنها قادمة من عنوان IP docker0 للمضيف. إذا طبقت التوجيه المذكور أعلاه على إعدادك، فسيسمح لجميع المستخدمين المتصلين عبر IPv6 بتزوير عنوان الـ IP الخاص بهم بكل سهولة.