Files
Siro/docker/nginx/siro-sockets-tls.conf
T
Hamza-AyedandClaude Opus 5 afb5189515 إنهاء TLS أمام سوكيتات Workerman — إصلاح Socket Connect Error: timeout
السبب (مثبَّت على الإنتاج): التزام c35b350b بتاريخ 2026-07-23 — وهو التزام
تلقائي برسالة "Update: <time>" — أضاف المنفذ للروابط:
  -  'https://jordan-siro.intaleqapp.com'
  +  'https://jordan-siro.intaleqapp.com:2020'
وكانت القيمة العاملة قبل ذلك بلا منفذ (443) فيُنهي البروكسي TLS ويمرّر.

بإضافة :2020 صار التطبيق يضرب حاوية Workerman مباشرة، وهي تفتح المنفذ نصاً
صريحاً (new SocketIO(2020) بلا سياق SSL)، فمصافحة TLS تتجمّد حتى المهلة:
  ❌ Socket Connect Error: timeout
  ❌ Socket Connect Timeout: 20000
ونتيجته أن السائق لا يبعث update_location إطلاقاً ⇒ لا GPS في Redis ⇒ لا
موقع للراكب لا عبر السوكيت ولا عبر الـ polling (كلاهما يقرأ من نفس المصدر).

مثبَّت بالأدلة على السيرفر:
- ss: المنفذان 2020/3030 يملكهما docker-proxy (نص صريح)، و443 nginx.
- curl على 127.0.0.1:2020 يرد {"sid":...,"upgrades":["websocket"]} — أي أن
  الحاوية سليمة تماماً والناقص هو طبقة TLS وحدها.

الحل بلا أي بناء للتطبيقات (وبلا تنزيل مستوى الأمان — الـ JWT يُرسَل في
query string فلا يجوز إطلاقاً تحويله إلى http):
- الحاويتان تُنشران على 127.0.0.1:12020 و 127.0.0.1:13030 فقط.
- nginx على المضيف يستمع على 2020/3030 بشهادة الدومين ويمرّر إليهما مع
  ترقية WebSocket (nginx/siro-sockets-tls.conf).
- proxy_read/send_timeout 3600s: اتصال السائق يعيش ساعات، وبلا ذلك يقطعه
  nginx كل 60ث فتدخل الحاوية حلقة إعادة اتصال دائمة.
- proxy_buffering off و access_log off (نبضات GPS تُغرق القرص).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 01:01:42 +03:00

107 lines
4.9 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ══════════════════════════════════════════════════════════════════
# ‏إنهاء TLS أمام سوكيتات Workerman
# ══════════════════════════════════════════════════════════════════
# ‏يُنسَخ على **المضيف** لا داخل الحاويات:
# /etc/nginx/sites-enabled/siro-sockets-tls.conf
#
# ‏المشكلة التي يحلّها: حاويتا السوكيت تفتحان المنفذين نصاً صريحاً
# (‏new SocketIO(2020)‎ و ‎new SocketIO(3030)‎ بلا سياق SSL)، بينما
# ‏التطبيقان يطلبان ‎https://jordan-siro.intaleqapp.com:2020‎ و ‎:3030‎.
# ‏مصافحة TLS ضد منفذ لا يتكلم TLS تتجمّد حتى المهلة، فيظهر في اللوج:
# Socket Connect Error: timeout
#
# ‏الحل: الحاويتان تُنشران على 127.0.0.1 فقط (12020 / 13030 — انظر
# ‏docker-compose.yml)، و nginx هنا يستمع على 2020 / 3030 بشهادة الدومين
# ‏ويمرّر إليهما مع ترقية WebSocket. النتيجة: روابط التطبيقين تبقى كما هي
# ‏بلا أي بناء جديد، والـ JWT في الـ query string يبقى داخل نفق TLS.
# ══════════════════════════════════════════════════════════════════
# ‏اسم مميّز يتفادى التضارب مع أي map باسم ‎$connection_upgrade‎ قد يكون
# ‏CloudPanel معرِّفه أصلاً في سياق http.
map $http_upgrade $siro_connection_upgrade {
default upgrade;
'' close;
}
# ── سوكيت السائقين — GPS ─────────────────────────────────────────
server {
listen 2020 ssl;
listen [::]:2020 ssl;
http2 on;
server_name jordan-siro.intaleqapp.com;
# ‏عدّل المسارين إن كانت شهادتك في مكان آخر — تحقّق بالأمر:
# grep -rh ssl_certificate /etc/nginx/sites-enabled/ | sort -u
ssl_certificate /etc/nginx/ssl-certificates/jordan-siro.intaleqapp.com.crt;
ssl_certificate_key /etc/nginx/ssl-certificates/jordan-siro.intaleqapp.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SiroSock:10m;
ssl_session_timeout 1d;
# ‏لا سجلّ وصول: نبضات GPS تصل كل ثوانٍ وتُغرق القرص
access_log off;
error_log /var/log/nginx/siro-socket-driver-error.log warn;
location / {
proxy_pass http://127.0.0.1:12020;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $siro_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;
# ‏اتصال السائق يعيش ساعات وهو أونلاين — بلا هذه المهل يقطعه nginx
# ‏كل 60 ثانية فتدخل الحاوية في حلقة إعادة اتصال دائمة.
proxy_connect_timeout 10s;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
# ‏التخزين المؤقّت يُعطّل الدفع الفوري في WebSocket
proxy_buffering off;
}
}
# ── سوكيت الركاب — حالة الرحلة وموقع السائق ──────────────────────
server {
listen 3030 ssl;
listen [::]:3030 ssl;
http2 on;
server_name jordan-siro.intaleqapp.com;
ssl_certificate /etc/nginx/ssl-certificates/jordan-siro.intaleqapp.com.crt;
ssl_certificate_key /etc/nginx/ssl-certificates/jordan-siro.intaleqapp.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SiroSock:10m;
ssl_session_timeout 1d;
access_log off;
error_log /var/log/nginx/siro-socket-passenger-error.log warn;
location / {
proxy_pass http://127.0.0.1:13030;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $siro_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;
proxy_connect_timeout 10s;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
proxy_buffering off;
}
}