النطاق: tripz-api.intaleqapp.com (قرار المالك) — مملوك وجاهز، ومحايد عن اسم العلامة الذي لم يُحسم فلا يحتاج تغييراً لاحقاً. ثغرتان كانتا ستُبطلان TLS من أصله: - API كان منشوراً على 0.0.0.0:4010 → صار 127.0.0.1. بلا هذا يبقى http://IP:4010 مفتوحاً فيتجاوز TLS كلياً وتصير الشهادة زينة - **Postgres كان مكشوفاً على 0.0.0.0:55432** — القاعدة على الإنترنت مباشرة → صار 127.0.0.1. المنفذ غير القياسي إخفاء لا أمان. الوصول من الماك عبر نفق SSH (docs/20 §4) trust proxy = 1: خلف Nginx كان req.ip يصير 127.0.0.1 للجميع فيمتلئ سجل التدقيق المالي (I7) بعنوان البروكسي بدل السائق — أثرٌ بلا قيمة عند النزاع. قفزة واحدة فقط: الثقة المفتوحة تسمح للعميل بتزوير X-Forwarded-For. docs/20: DNS → موقع reverse proxy → شهادة → **إعداد ترقية WebSocket** (بدونه يسقط التتبّع الحيّ) + مهلة 3600s للنبضات طويلة العمر + فحص تحقّق أهمّه أن http://IP:4010 يجب أن **يفشل**. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.3 KiB
20 — TLS: إنهاء الطبقة المشفّرة أمام الـAPI
النطاق المعتمد:
tripz-api.intaleqapp.com(قرار المالك 2026-07-17). السبب في اختيار نطاق فرعي علىintaleqapp.com: مملوك وجاهز بلا انتظار DNS، ومحايد عن اسم العلامة التجارية الذي لم يُحسم — فلا يحتاج تغييراً لاحقاً.
1. لماذا هذا يسبق كل عمل مدفوعات
الـAPI كان يعمل على http://194.163.173.157:4010. من يلتقط الشبكة (واي-فاي عام) يقرأ توكن أي سائق ويسحب أرباحه. لا OTP ولا HMAC ولا سجل تدقيق يمنع ذلك — كلها تُبنى فوق قناة مكشوفة. TLS هو الأساس، لا طبقة إضافية.
2. ثغرتان أُصلحتا في نفس الشغل (بلا هذا يصير TLS زينة)
| كان | صار | لماذا |
|---|---|---|
4010:4010 أي 0.0.0.0 |
127.0.0.1:4010 |
بلا هذا يبقى http://IP:4010 مفتوحاً فيتجاوز TLS كلياً. الشهادة على النطاق لا تُغلق المنفذ. |
55432:5432 أي 0.0.0.0 |
127.0.0.1:55432 |
Postgres كان على الإنترنت مباشرة. المنفذ غير القياسي إخفاء لا أمان. |
بعد هذا لا يصل للـAPI إلا Nginx المحلي، ولا تصل القاعدة إلا من داخل السيرفر.
3. الخطوات على السيرفر
3.1 DNS
سجل A لـtripz-api.intaleqapp.com → 194.163.173.157. تحقّق قبل المتابعة:
dig +short tripz-api.intaleqapp.com # يجب أن يطبع 194.163.173.157
Let's Encrypt يفشل إن لم ينتشر الـDNS بعد. لا تُصدر الشهادة قبل أن يطبع الأمر العنوان الصحيح.
3.2 موقع Reverse Proxy في CloudPanel
CloudPanel → Add Site → Create Reverse Proxy:
- Domain:
tripz-api.intaleqapp.com - Reverse Proxy URL:
http://127.0.0.1:4010
3.3 الشهادة
CloudPanel → الموقع → SSL/TLS → Actions → New Let's Encrypt Certificate. CloudPanel يجدّدها تلقائياً.
3.4 دعم WebSocket (إلزامي — بدونه يسقط التتبّع الحيّ)
Socket.IO يحتاج ترقية الاتصال. في Vhost Editor للموقع، تأكّد أن كتلة location / تحوي:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# نبضات المواقع والسوكت طويلة العمر — الافتراضي 60s يقطعها
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
X-Forwarded-For ضروري: بدونه يسجّل التدقيق المالي (docs/17 — I7) عنوان البروكسي لكل سائق، فيصير الأثر بلا قيمة. الباك إند يثق بقفزة واحدة فقط (trust proxy = 1) — الثقة المفتوحة تسمح للعميل بتزوير العنوان.
3.5 النشر
cd /home/tripz-llc && git pull origin main
cd backend && docker compose up -d --build
docker image prune -f
3.6 التحقق
curl -I https://tripz-api.intaleqapp.com/api/health # 200 عبر TLS
curl -I http://194.163.173.157:4010/api/health # يجب أن **يفشل** الآن
docker compose exec api printenv | grep -c PLATFORM_SECRET # 1
الفحص الثاني هو الأهم: نجاحه يعني أن المنفذ ما زال مكشوفاً وأن TLS يُتجاوَز.
4. الوصول للقاعدة بعد الإغلاق
لم تعد 55432 مفتوحة. من الماك:
ssh -L 55432:127.0.0.1:55432 root@194.163.173.157
# ثم اتصل بـ localhost:55432 كالمعتاد
سكربتات التحقق لا تتأثر — تعمل داخل شبكة tripz-net وتنادي http://tripz-api:4010 مباشرة.
5. بعد نجاح TLS — خطوات تابعة
| البند | التفصيل |
|---|---|
| فلاتر: BASE_URL | --dart-define BASE_URL=https://tripz-api.intaleqapp.com/api |
| فلاتر: إغلاق النصّ الصريح | usesCleartextTraffic=false في AndroidManifest — يمنع أي رجوع صامت لـhttp |
| تفعيل التوقيع | PAYMENTS_REQUIRE_SIGNATURE=true بعد أن يوقّع فلاتر (docs/17 — I6) |
| HSTS | بعد التأكد من استقرار TLS — يمنع الرجوع لـhttp |
بقية intaleqapp.com |
map-saas وnabeh على https أصلاً ✅ |
6. ما لا يحلّه TLS
- لا يحمي من تطبيق مُفكَّك: TLS يحمي القناة لا الطرف. الحماية من الطرف هي الاستحقاقات على السيرفر (19-entitlements-licensing).
- لا يمنع pinning bypass: من يملك الجهاز يرى حركته. لذلك تبقى القاعدة: السيرفر لا يثق بالعميل أبداً.
← ذو صلة: 15-deploy-flow · 14-server-conventions · 17-backend-backlog