Asciinema: طلب سيء لتحميل> تسجيلات 4Kb ضمن CentOS (Python 3.4)

تم إنشاؤها على ٧ يونيو ٢٠١٧  ·  58تعليقات  ·  مصدر: asciinema/asciinema

تقرير الشوائب

معلومات النظام:

  • الإصدار المستخدم: 1.4.0 (1.1.1 له نفس المشكلة أيضًا)
  • نظام التشغيل: إصدار CentOS Linux 7.3.1611
  • إصدار Python: Python 3.4.5
  • أدوات التثبيت: yum (من مستودع EPEL)

خطوات التكاثر:

  1. asciinema upload asciicast.json

سلوك متوقع:

تم تحميل الملف إلى asciinema.org

السلوك الفعلي:

رسالة خطأ طباعة العميل:

Error: Invalid request: <html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>

معلومات اضافية:

يقوم العميل بإنشاء تسجيل معطل إذا تم استخدام zsh ( 4.3.11 (x86_64-redhat-linux-gnu) في حالتي) وتم تثبيت oh-my-zsh. إذا تم تعطيل oh-my-zsh أو استخدام bash كقذيفة ، يقوم العميل بإنشاء وتحميل التسجيل دون أي مشاكل.

تسجيل JSON: https://gist.github.com/andyone/b2a883e8c3795a6ad393a715ff7a41df

compatibility help wanted hosting

التعليق الأكثر فائدة

لقد عدت للتو إلى التكوين السابق (إنهاء SSL في Nginx). اسمحوا لي أن أعرف إذا كان يعمل للكم الآنandyoneThiefMasterbenaryorgpeterbrittainThomasWaldmann

ال 58 كومينتر

يحدث لي أيضا. باستخدام ZSH وليس OMZ.

$ zsh --version
zsh 5.3.1 (x86_64-pc-linux-gnu)
$ asciinema --version
asciinema 1.4.0

tmpw6byrbv8-asciinema.json

لقد اكتشفت أنه إذا قمت بتغيير عنوان url الخاص بواجهة برمجة التطبيقات من HTTPS إلى HTTP ، فسيكون ذلك جيدًا.

لقد قمت بتغيير تكوين موازن التحميل أمس لذا قد يكون هذا مرتبطًا.

تمكنت من إعادة إنتاج هذا في Centos 7 Vagrant VM. أعتقد أن هذا له علاقة بموازنة تحميل Brightbox (مع إنهاء SSL ، وشهادة Let's Encrypt التلقائية) التي نستخدمها منذ الأمس.

andyoneThiefMaster هل يمكنك المحاولة الآن؟ ربما كنت قد حللت ذلك.

لا يزال يحصل على 400

أعتقد أنها قضية ذات صلة بـ OpenSSL. يعد إرسال البيانات باستخدام curl أمرًا جيدًا لأن curl يستخدم NSS (خدمات أمان الشبكة) للعمل مع SSL / TLS.

مع موازن تحميل Brightbox

هو الحل القائم على nginx؟

andyone أعتقد أن موازن تحميل Brightbox يستخدم Haproxy.

يمكنني إعادة إنتاج هذا باستمرار. لقد أنشأت Vagrantfile والإرشادات: https://github.com/sickill/bb-lb-400

andyone ، لا يبدو أن المشكلة

لقد قمت بإنشاء وكيل https://ascii.kaos.io استنادًا إلى webkaos (تم تحسين nginx باستخدام BoringSSL) باستخدام هذا التكوين . تم تحميل تسجيلاتي وتسجيلات

إليكم ما أعرفه حتى الآن:

تسير طلبات HTTP بشكل جيد من خلال موازن تحميل Brightbox ، ولكن طلبات HTTPS تعطي 400 طلب سيء
للطلب حيث نص طلب أكبر من حول 4KB.

الشيء المثير للاهتمام هو أننا نحصل على 400 مقابل HTTPS ضمن CentOS. يعمل HTTPS ضمن macOS بشكل جيد. (HTTP يعمل بشكل جيد في كل مكان).

نظرت أعمق ، وحاولت اكتشاف الفرق. لقد استخدمت tcpdump لمشاهدة الطلبات على كل من CentOS و macOS (HTTP ، بافتراض أن الطلب نفسه منسق بنفس تنسيق HTTPS).

يبدو أن الاختلاف الوحيد هو سطرين فارغين قبل الجسم على macOS ، وسطر واحد فارغ على CentOS (ربما يرجع ذلك إلى إصدار مختلف قليلاً من urllib الذي يأتي مع Python 3 على أنظمة تشغيل هذه):

CentOS:

POST /api/asciicasts HTTP/1.1
Accept-Encoding: identity
User-Agent: asciinema/1.4.0 CPython/3.4.5 Linux/3.10.0-514.16.1.el7.x86_64-x86_64-with-centos-7.3.1611-Core
Authorization: Basic <61 bytes of base64 encoded credentials>
Content-Length: 13582
Content-Type: multipart/form-data; boundary=c3f4e35afa4a4ce6b65b6420da09b46e
Connection: close
Host: asciinema.org

--c3f4e35afa4a4ce6b65b6420da09b46e
Content-Disposition: form-data; name="asciicast"; filename="asciicast.json"
Content-Type: application/json

<about 13 kb of json>

macOS:

POST /api/asciicasts HTTP/1.1
Accept-Encoding: identity
Content-Length: 13582
Host: asciinema.org
User-Agent: asciinema/1.4.0 CPython/3.6.1 Darwin/16.5.0-x86_64-i386-64bit
Content-Type: multipart/form-data; boundary=71d5b757e9d1451b9540dc286f74207d
Authorization: Basic <61 bytes of base64 encoded credentials>
Connection: close


--71d5b757e9d1451b9540dc286f74207d
Content-Disposition: form-data; name="asciicast"; filename="asciicast.json"
Content-Type: application/json

<about 13 kb of json>

لمعرفة كيف يؤثر ذلك على الأشياء ، قمت بتغيير "طلب حجم المخزن المؤقت" مؤقتًا على LB من 4096 (افتراضي) إلى 8192 (كحد أقصى) وبدأ فجأة يعمل بشكل جيد في كل مكان (جميع أنظمة التشغيل ، HTTPS) ، رائع!

لست واثقًا تمامًا من أن هذا هو الحل النهائي لأنه مع حجم المخزن المؤقت 4096 هذا صحيح:

  • أنا قادر على تقديم طلب POST بجسم 3 ميغا بايت دون أي مشكلة
    HTTPS على macOS
  • وبالتالي أفترض أن حجم المخزن المؤقت هذا مخصص للرؤوس وليس نص الطلب (تم تأكيد ذلك بواسطة John من Brightbox)
  • أنا قادر على تقديم طلب POST مع جسم <4KB دون أي مشكلة
    HTTPS على CentOS
  • لا يمكنني تقديم طلب POST باستخدام> 4KB body عبر HTTPS على CentOS
  • أعلاه يتناقض مع افتراضاتي حول تطبيق المخزن المؤقت فقط على الرؤوس ...
  • رؤوس الطلبات صغيرة (~ 330 بايت) في جميع الحالات

عندما أرتفع "طلب حجم المخزن المؤقت" إلى 8192 حجم الجسم والبروتوكول
لا يهم وكل شيء يعمل بشكل جيد. أتساءل عما إذا كان عن طريق الاهتزاز
إلى 8192 أنا فقط أشتري الوقت (اجعل الناس يتأثرون أقل) أو هذا
يحل المشكلة تمامًا (إذا كان الأمر كذلك ، فلماذا؟).

لقد اتصلت بـ Brightbox حول هذا الأمر ، آمل أن يتمكنوا من شرح ما يحدث.

تحديث حجم المخزن المؤقت re 8192 على جانب Brightbox: باستخدام هذا الرقم يعمل معي ضمن CentOS ولكنه لا يعمل مع ThiefMaster .

عذرًا.

قبل أن أضع حركة المرور عبر Brightbox LB ، أنهيت SSL في Nginx وكان كل شيء يعمل بشكل جيد لسنوات. إذا كان يعمل مع وكيل andyone استنادًا إلى Nginx ، فقد يشير إلى أن Nginx أكثر "تسامحًا" بشأن تنسيق الطلب ، في حين أن Haproxy أكثر صرامة ، وينسق عميل asciinema الطلب بشكل غير صحيح (لمعايير Haproxy) في Python 3.4 (وله urllib ، الأقدم من الإصدار 3.6.1 الذي أستخدمه على أجهزة Mac).

يمكنني التحقق من ذلك لاحقًا باستخدام Haproxy ، لكن إصداري مصمم باستخدام LibreSSL بدلاً من OpenSSL.

نظريتي الحالية هي:

هذا السطر الجديد قبل الرؤوس والجسم لا يكفي لـ LB لإنهاء قراءة الرؤوس (يتوقع سطرين جديدين) ، ويستمر في قراءة جميع البيانات الموجودة أسفله كرؤوس ، عد البايت ، والتي تتجاوز في النهاية الحد الأقصى لحجم الرؤوس. إذا كان LB يحتوي على متغير مثل bytes_read (بايت يُقرأ من المقبس) ، فإنه يتحقق من قيمته بعد الانتهاء من قراءة الرؤوس ، ثم مرة أخرى لاحقًا بعد قراءة النص. إذا قمت بتحميل ملف <4kb ، فلن يتخطى أبدًا حد 4Kb للرؤوس ، وإذا قمت بتحميل> 4kb فإنه يتجاوزه.
(وهذا يحدث فقط مع HTTPS)

لا توجد فكرة عما إذا كان هذا هو الحال ، مجرد التفكير بصوت عالٍ 😀

تم تحديث كود المصدر بحيث يضيف سطرًا جديدًا إضافيًا ، ويتم فحصه ضمن CentOS ولا يزال يفشل. لذا فإن النظرية المذكورة أعلاه خاطئة.

يعمل هذا ضمن CentOS مع HTTPS:

curl -v -X POST -u $USER:api-token https://asciinema.org/api/asciicasts -F [email protected]

* About to connect() to asciinema.org port 443 (#0)
*   Trying 109.107.38.233...
* Connected to asciinema.org (109.107.38.233) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*   subject: CN=asciinema.org
*   start date: Jun 07 09:12:00 2017 GMT
*   expire date: Sep 05 09:12:00 2017 GMT
*   common name: asciinema.org
*   issuer: CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US
* Server auth using Basic with user 'vagrant'
> POST /api/asciicasts HTTP/1.1
> Authorization: Basic <...hidden...>
> User-Agent: curl/7.29.0
> Host: asciinema.org
> Accept: */*
> Content-Length: 5658
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=----------------------------6ca3f3de6469

إذن ربما يكون SSL lib المستخدم بواسطة Python مختلفًا عن curl وتكمن المشكلة في مكان ما في SSL-land؟

أعتقد ذلك. يستخدم Python OpenSSL ، ويستخدم curl NSS.

andyone الشهادة الخاصة بـ ascii.kaos.io ليست Let's Encrypt؟

RapidSSL SHA256 مع RSA

عادةً ما أقول إن CentOS تفتقد إلى شهادة الجذر لـ Let's Encrypt (أو شيء من هذا القبيل 😊) ، ولكن يتم إجراء اتصال SSL والخطأ على مستوى بروتوكول HTTP (400 طلب سيء) لذا ... 👐

إذا كانت شهادة الجذر لـ Let's Encrypt مفقودة ، فلن تعمل حتى مع curl.

يستخدم موازن التحميل (Brightbox) الخاص بنا بالفعل haproxy. تنص مستندات HTTP RFC و haproxy على أن CRLF واحد مطلوب لفصل الرؤوس عن النص الأساسي:

https://github.com/haproxy/haproxy/blob/master/doc/internals/http-parsing.txt

هل من الممكن أنك ترسل فقط CR أو LF هنا ، بدلاً من CRLF كامل؟

sickill هذا وكيل على HA-Proxy 1.7.5 مع LibreSSL 2.5.0 - https://ascii-ha.kaos.io. تم تحميل تسجيلاتي وتسجيلاتي over-4k.json من المستودع الخاص بك بنجاح عبر هذا الوكيل.

andyone طيب. لذا ، هل يمكنك تغيير tune.bufsize (https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#3.2-tune.bufsize) إلى 4096؟

johnl لقد راجعت CRLF وكل شيء على ما يرام هنا.

لقد قمت بتفريغ الطلب على كل من CentOS و macOS مرة أخرى (عبر HTTP ، مرة أخرى ، بافتراض أن حمولة HTTP هي نفسها بالنسبة لـ HTTPS).

يحتوي dump-centos.pcap.txt و dump-mac.pcap.txt على التقاط tcpdump ( tcpdump -s 0 dst port 80 -w dump-centos.pcap.txt ).
يحتوي dump-centos-hex.txt و dump-mac-hex.txt على تفريغ بتنسيق سداسي عشرية (عبر hexdump -C ).

تفريغ سنتوس hex.txt
تفريغ centos.pcap.txt
تفريغ ماك- hex.txt
تفريغ mac.pcap.txt

يبدو أنه في كلا نظامي التشغيل ، يتم استخدام CRLF للأسطر الجديدة ، وهناك سطر فارغ واحد بين الرؤوس والجسم.

على اليسار CentOS ، على نظام macOS الأيمن:

centos-mac-comparison

تم تحديث تهيئةsickill . over-4k.json أيضًا.

andyone شكرا على التحديث. يبدو أنه لا يضيف رأس X-Forwarded-Proto (لأن عنوان URL الذي تم إرجاعه هو http:// ). هل يمكنك إضافة http-request set-header X-Forwarded-Proto https if { ssl_fc } ؟

هذا هو التكوين الخاص بي:

frontend www-https
    bind 207.154.241.251:443 ssl crt /etc/ssl/private/kaos.pem
    reqadd X-Forwarded-Proto:\ https
    default_backend www-backend

backend www-backend
    server asciinema-backend asciinema.org:80

أين يجب أن أضيف هذا الخط؟

andyone أعتقد أنه يحتاج إلى الدخول إلى قسم backend (على الرغم من أنني لست خبيرًا في haproxy).

andyone راجع للشغل ، أقدر حقًا مساعدتك في تصحيح هذا الخطأ 😍 شكرًا!

لا تنس إعادة التوجيه أيضًا. يجب أن يكرر هذا الإعداد بشكل وثيق جدًا ، مع شفرات SSL أيضًا:

    tune.bufsize 4096
    tune.ssl.default-dh-param 2048
    tune.maxrewrite 40

frontend www-https
    bind 207.154.241.251:443 ssl no-sslv3 crt /etc/ssl/private/kaos.pem ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
    reqadd X-Forwarded-Proto:\ https
    default_backend www-backend

backend www-backend
    server asciinema-backend asciinema.org:80
    mode http
    option forwardfor
    option httplog

لقد قمت بتعديل التكوين على هذا ، ولكن بدون حظ:

    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option                  http-server-close
    option                  forwardfor
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend www-https
    bind 207.154.241.251:443 ssl crt /etc/ssl/private/kaos.pem
    reqadd X-Forwarded-Proto:\ https
    default_backend www-backend

backend www-backend
    http-request set-header X-Forwarded-Proto https
    server asciinema-backend asciinema.org:80

لا يزال العميل يعرض الروابط بـ http:// .

يسعدني دائمًا المساعدة في تحسين الخدمات المفيدة 😉.

johnl هذا هو التكوين الكامل ، تم تعيين جميع الخيارات المطلوبة في أقسام defaults و global :

    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    tune.bufsize 4096

    # SSL configuration
    tune.ssl.default-dh-param 2048
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
    ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option                  http-server-close
    option                  forwardfor
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend www-https
    bind 207.154.241.251:443 ssl crt /etc/ssl/private/kaos.pem
    reqadd X-Forwarded-Proto:\ https
    default_backend www-backend

backend www-backend
    http-request set-header X-Forwarded-Proto https
    server asciinema-backend asciinema.org:80

إذاandyone الصورة التكوين haproxy الآن قريبة جدا من BB ونحن لا تزال لا يمكن إعادة إنشاء المشكلة، لا يعقل أن تحاول مع سيرت تشفير دعونا؟ هذا أحد الاختلافات بين https://ascii-ha.kaos.io و https://asciinema.org.

هذا أحد الاختلافات بين https://ascii-ha.kaos.io و https://asciinema.org.

لا ، يمكن إنشاء BB LB باستخدام OpenSSL (أستخدم LibreSSL).

سأحاول إضافة شهادة Let's Encrypt لـ https://ascii-ha.kaos.io.

تم - https://ascii.kaos.re
HA-Proxy 1.7.5 (w / LibreSSL 2.5.0) + شهادة Let's Encrypt (التي أنشأتها Certbot)
التكوين:

    tune.bufsize 4096
    tune.ssl.default-dh-param 2048
    tune.maxrewrite 40

frontend www-https
    bind 207.154.241.251:443 ssl no-sslv3 crt /etc/ssl/private/ascii.kaos.re.pem ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
    reqadd X-Forwarded-Proto:\ https
    default_backend www-backend

backend www-backend
    server asciinema-backend asciinema.org:80
    mode http
    option forwardfor
    option httplog

يبدو أن كل شيء يعمل بشكل جيد. over-4k.json بنجاح.

ليس لدي المزيد من الأفكار لهذا. أفكر في العودة إلى مثيل Nginx الخاص بي لموازنة التحميل وإنهاء SSL 🤕

أحاول تقليل هذا الأمر إلى أمر curl واحد يمكنه إعادة إنتاج المشكلة ، لكن لم تتم إدارتها بعد ، فهل يمكن لأي شخص المساعدة؟

أقوم بنشر نص بحجم 5k ، باستخدام اسم مستخدم / كلمة مرور للمصادقة باستخدام curl. أقوم بضرب موازن تحميل Brightbox مع خلفية خادم ويب netcat ، حتى أتمكن من رؤية نص الطلب الأولي. يمر دائمًا - لا يمكن أن يؤدي إلى استجابة سيئة للطلب.

إذا تم رفض هذا من قبل موازن التحميل ، فلن أحتاج إلى مثيل حقيقي للتطبيق على الواجهة الخلفية ، لأنه لا يجب أن يصل إلى هذا الحد أبدًا - لذلك يجب أن نكون قادرين على إعادة إنتاج هذا باستخدام curl وبدون تطبيق.

لقد جربت curl على ubuntu و centos7 ، وباستخدام openssl على وجه التحديد (لاحظ أنه يمكنك تحديد الأمر --engine ليتم تجعيده لاختيار sslib lib المراد استخدامه. تم إنشاء ثنائيات centos7 curl مقابل معظم الخيارات)

@ johnl شكرا للنظر في هذا.

من المنطقي استخدام netcat كخلفية للاختبار 👍

curl ما يعادل asciinema upload over-4k.json أكثر أو أقل من هذا:

curl -v -X POST -u test:uuid4 https://asciinema.org/api/asciicasts -F [email protected]

(استبدل uuid4 بنتيجة python3 -c 'import uuid; print(uuid.uuid4())' )

وهو يعمل مع حليقة بالفعل ...

لقد قارنت tcpdump asciinema upload و curl أعلاه ولا يوجد أي شيء على مستوى بروتوكول HTTP يبدو مريبًا بالنسبة لي. ومع ذلك ، تظهر بعض إطارات tcp في مواقع مختلفة (ربما يتم إرسال بيانات أكثر / أقل / تناسبها في كل حزمة tcp).

لقد التقطت طلب HTTP (إلى http://asciinema.org) باستخدام tcpflow في CentOS 7 VM:

sudo tcpflow -p -C -i eth0 port 80 >tcpflow-req.txt

ثم في قذيفة أخرى (في نفس VM) ركض:

ASCIINEMA_API_URL=http://asciinema.org asciinema upload /vagrant/over-4k.json

قطعت الرد منه ، ولم أترك سوى الطلب. إليك ما يتم إرساله ، بايت بايت: tcpflow-req.txt

لقد أعدت طلب HTTP الذي تم التقاطه ضد Asciinema. org: 80 مع nc :

bash-4.4$ (cat tcpflow-req.txt; cat) | nc asciinema.org 80
HTTP/1.1 201 Created
Server: nginx
Date: Mon, 12 Jun 2017 13:30:03 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 48
Connection: close
Status: 201 Created
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Location: http://asciinema.org/a/4lgbbik7li4ywzqrfak0e7eku
ETag: "9beb7ac6bb5981f06fdc71df3947d8b0"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 2a8a8c75-ed06-4741-9adb-e5d276032ded
X-Runtime: 0.360858
Vary: Accept-Encoding
Strict-Transport-Security: max-age=15768000

http://asciinema.org/a/4lgbbik7li4ywzqrfak0e7eku

الامور جيدة.

الآن ، لقد أرسلت SSL إلى asciinema. غزاله: 443 :

(cat tcpflow-req.txt; cat) | openssl s_client -connect asciinema.org:443

ها هي النتيجة:

CONNECTED(00000003)
depth=1 /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/CN=asciinema.org
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFFDCCA/ygAwIBAgISBDhrp0YwV5NtleFOG+Zj61lQMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzA2MDcwOTEyMDBaFw0x
NzA5MDUwOTEyMDBaMBgxFjAUBgNVBAMTDWFzY2lpbmVtYS5vcmcwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+/g237mVels4G9blsZlaeeiURbSp22eGO
T5OZ5As9NyuxSvRVEJrs4xk/RBEkCVgeZspSOmkRLwXG+FSMtjhbqIUt73AUKMdm
4DG+OwkVxjZatskL0wUWRcU7DmyW/Ls/OFJpPPcZ+pqu/v/ek99EiVNoAHJzXMXJ
ZsWy5KLE3fhkrlyMvdIkOkCK5zHOT95t0i8OmdaPIekPBa57VhvnDlUJsYyCF9GN
mP8Qg6OygexyULJGqBwiZ0BN2J6cYwChUlSvqFnkL4OzfixZ+mItuhl1b1vx/N5K
XMtPiM+nc/S+/liIWgtt7HIy9NmrOtSKbPTh3Bv/rfNdaiYx5CUHAgMBAAGjggIk
MIICIDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
BwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFNAMhQNNwl+/bJjml9hrrHYzBxbf
MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUFBwEBBGMw
YTAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9y
ZzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0Lm9y
Zy8wLwYDVR0RBCgwJoINYXNjaWluZW1hLm9yZ4IVc3RhZ2luZy5hc2NpaW5lbWEu
b3JnMIH+BgNVHSAEgfYwgfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAm
BggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUF
BwICMIGeDIGbVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBv
biBieSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRo
IHRoZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5j
cnlwdC5vcmcvcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBABxmJxdQQCcy
FpCkiDrB+vonBUCLYSJtrFkmRdmj9W8/ADpC6M/EhYFOCgrO2cmhYfy1SxDAP5Hd
KIhd3p1F931MMXVcxYt2n6FiDJHN531qp6eBzjZsVIgHXS27PAV466IIMTydNQSe
reyDc9fi+q+ji1Gz89nI8lHIOlRt3dzVGT2J3oQidsm4ZuPNJFj4y8MUrbUAOOH6
YY4n395OKV7vWzl7VPKiCWx+zsv4bzr6IGUPlwqCN2e6cppPWE47ugnYsarINCHO
ie5lU4E2N0k2qVWe/+uYbwSUQ0nrEx8R078m6+6EjDkR4VLboLjuV5tGBgHsJLQB
CmLH6CmNCRE=
-----END CERTIFICATE-----
subject=/CN=asciinema.org
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
---
SSL handshake has read 3436 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES128-SHA
    Session-ID: AC26CBF8D3719B1DE709A9A8AEAB43D20B14C62085A74604338C512CEA4472C5
    Session-ID-ctx:
    Master-Key: 0C59B1A2B6802D35FAD26DEE139043A853F3E62787E9AA743A8CAFDA95744DB73AB42B511F37EA7D6BB398A352938551
    Key-Arg   : None
    Start Time: 1497273777
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
HTTP/1.0 400 Bad request
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>

/ cc johnl

sickill هل يمكنك التحقق من نفس الطلب باستخدام https://ascii.kaos.re؟

andyone فحص فقط. تم تحميل هذا (cat tcpflow-req.txt; cat) | openssl s_client -connect ascii.kaos.re:443 - بنجاح.

لقد بذلت المزيد من الحفر هنا. يستخدم curl on centos7 nss لكن wget يستخدم openssl. يمكنني إرسال الطلب بنجاح باستخدام curl أو wget. يمكنني حتى الإرسال باستخدام أداة python httpie (ضمن python 3).

لكنه فشل في إرسالها إلى opensl s_client عبر stdin

لكنه ينجح في إرساله إلى opensl s_client عن طريق لصق الطلب فيه ، بدلاً من استخدام stdin!

أنا الآن متأكد من أن هذا يرجع إلى أن هناك شيئًا ما يرسل طلبات بنهايات سطر LF بدلاً من نهايات سطر CRLF المطلوبة ، لكنني لست متأكدًا تمامًا من ذلك. أعتقد أن "openssl s_client" أداة اختبار سيئة وتجعل من الصعب التأكد مما يحدث.

لكني لم أعد إنتاج هذا بعد مع عميل http مناسب ، سواء باستخدام nss أو openssl (يستخدم curl on ubuntu openssl ويعمل بشكل جيد أيضًا ، لذا أكد ذلك مرتين). أي شخص آخر يدير ذلك؟

لقد أجريت للتو بعض الاختبارات بمفردي ويمكنني أن أؤكد استمرار هذه المشكلة بطول محتوى يبلغ 4520 ، ولكن ليس بنفس الطلب الذي تم تجريده بمقدار 1000 حرف ( Content-Length تعديله وفقًا للتغييرات التي تم إجراؤها).

يوجد CRLF في جميع اختباراتي ويؤكد xxd أنه تم إرسالها عبر الأنبوب.
يمكنني أيضًا الاختبار باستخدام OpenBSD nc (والذي يدعم TLS).

من الوثائق :

لحن
يضبط حجم المخزن المؤقت على هذا الحجم (بالبايت). القيم المنخفضة تسمح بالمزيد
جلسات للتعايش في نفس مقدار ذاكرة الوصول العشوائي ، والقيم الأعلى تسمح ببعض
التطبيقات ذات ملفات تعريف الارتباط الكبيرة جدًا للعمل. القيمة الافتراضية هي 16384 و
يمكن تغييرها في وقت البناء. يوصى بشدة بعدم تغيير هذا
من القيمة الافتراضية ، حيث إن القيم المنخفضة جدًا ستؤدي إلى تعطيل بعض الخدمات مثل
الإحصائيات ، والقيم الأكبر من الحجم الافتراضي ستزيد من استخدام الذاكرة ،
ربما يتسبب في نفاد ذاكرة النظام. على الأقل الحد الأقصى العالمي
يجب تقليل المعلمة بنفس العامل حيث يتم زيادة هذه المعلمة.
إذا كان طلب HTTP أكبر من (tune.bufsize - tune.maxrewrite) ، فإن haproxy سوف
إرجاع خطأ HTTP 400 (طلب غير صالح). وبالمثل إذا كانت استجابة HTTP أكبر
من هذا الحجم ، سيعيد haproxy HTTP 502 (بوابة سيئة).

على عكس nginx الذي لا يحتفظ بالطلب بأكمله في الذاكرة ولكنه يمرره سريعًا (AFAIK) أو على الأقل يحفظه مؤقتًا في ملف مؤقت.

يوجد الخيار no option http-buffer-request ، والذي إذا حصلت على هذا الحق يعطل هذا السلوك تمامًا (مكتوب لـ option http-buffer-request ، بدون no ):

من المستحسن أحيانًا انتظار نص طلب HTTP من قبل
اتخاذ قرار. هذا ما يتم عمله بواسطة "Balance url_param" لـ
مثال. حالة الاستخدام الأولى هي تخزين الطلبات من العملاء البطيئين من قبل
جاري التوصيل بالخادم. حالة استخدام أخرى تتمثل في أخذ التوجيه
القرار بناءً على محتويات جهة الطلب. تم وضع هذا الخيار في ملف
تفرض الواجهة الأمامية أو الخلفية على معالجة HTTP الانتظار حتى النهاية بأكملها
تم استلام الجسم ، أو امتلاء المخزن المؤقت للطلب ، أو أن الجزء الأول ممتلئ
كاملة في حالة الترميز المقسم. يمكن أن يكون لها آثار جانبية غير مرغوب فيها مع
بعض التطبيقات تسيء استخدام HTTP من خلال توقع عمليات إرسال غير متقطعة بين
الواجهة الأمامية والخلفية ، لذلك لا ينبغي بالتأكيد استخدام هذا بواسطة
إفتراضي.

لقد ضربت هذا أيضا. يبدو لي أنه من خلال اختبار نفس المحتوى الذي يعمل عبر HTTP ولكن ليس HTTPS ، فمن غير المحتمل أن تكون أحجام المخزن المؤقت على خطأ ، إلا إذا كان هناك شيء ما بين العميل والوكيل يضيف الكثير من الترويسات الإضافية.

ولكن ربما يكون هناك خطأ في أي شيء ينهي اتصالات SSL الخاصة بك بحيث يفسد الرؤوس قليلاً.

إذا كان الأمر كذلك ، فهناك خيار يقلل من أمان HAProxy ، ولكنه يسمح بمرور مرور HTTP أقل توافقًا. انظر https://stackoverflow.com/questions/39286346/extra-space-in-http-headers-gives-400-error-on-haproxy

على الرغم من أنني لا أدعو إلى تقليل الأمان كحل نهائي ، فقد يسمح لك ذلك بالحفاظ على الخدمة أثناء تصحيحها.

peterbrittain في الوقت الحالي ، يستخدم asciinema.org موازن تحميل Brightbox Cloud ، لذلك لا أتحكم في تكوين Haproxy الخاص بهم. اعتدنا على إنهاء SSL في Nginx الخاص بنا وكان ذلك يعمل بشكل جيد. منذ أن تحولت إلى BB LB ، تحدث هذه المشكلة (بالنسبة للبعض). هل تواجهه تحت CentOS أو أي نظام آخر؟

بصراحة ، لم أواجه أي مشكلة مع حل Nginx السابق. انتهت صلاحية شهادة SSL التي كانت لدينا ، لذا اعتقدت أنني سأختار Let's Encrypt. نظرًا لأن شهادات LE قصيرة الأجل ، فمن الأفضل إدارتها تلقائيًا ويقوم Brightbox LB بذلك من أجلي. أردت فقط أن أنقذ نفسي من العمل في إعداد LE ويبدو أن BB LB هو الحل الأبسط (حيث أن موقع asciinema.org برعاية Brightbox ويعمل على بنيتهم ​​التحتية الرائعة). الآن أعتقد أن إعداد LE بنفسي في Nginx قد يستغرق 1/10 من الوقت الذي قضيته بالفعل في حل هذه المشكلة 😞😞😞

آه. لم ألاحظ دقة من يمتلك أي أجزاء. هل كان لديك أي حظ في الحصول على diags من BB لهذه المشكلة؟

وردا على سؤالك: الصندوق الخاص بي هو CentOS 6 VM.

لقد واجهت أيضًا مشكلة الطلب السيئ ، باستخدام asciinema 1.2.0 (إصدار من ubuntu 16.04 lts).

لقد نجح الاختراق الموضح أعلاه ، شكرًا.

لقد اكتشفت للتو أن نفس الملف ينتج عنه طلبًا سيئًا في مربع Gentoo [1] الخاص بي ، ولكن ليس في مربع OpenBSD [2] الخاص بي.
يقوم OpenBSD بتحميله على ما يرام.
أعتقد أنه يجب إجراء مزيد من التحقيق في الاختلاف بين هؤلاء العملاء.
يدعم صندوق Gentoo أهداف Python التالية لكل ebuild:

PYTHON_TARGETS="python3_4 -python3_5"

لا يمكنني حاليًا اختبار python3.5 بسهولة ، لكن ربما هذا يساعد بالفعل.

تحرير : لقد أضفت إصدارات OpenSSL ، ونسيت ذلك تمامًا.

  • الوعاء الدموي 1.4.0

    • تم تنفيذه باستخدام python-exec 2.4.5

    • بدوره تنفيذ Python 3.4.6

  • OpenSSL 1.0.2l 25 مايو 2017

  • اسكينيما 1.3.0

    • تم تنفيذه باستخدام Python 3.6.0
  • LibreSSL 2.5.2

لقد عدت للتو إلى التكوين السابق (إنهاء SSL في Nginx). اسمحوا لي أن أعرف إذا كان يعمل للكم الآنandyoneThiefMasterbenaryorgpeterbrittainThomasWaldmann

sickill أنا متأكد بنسبة 85٪ فقط من أنه نفس الملف الذي فشل من قبل ، ولكن إذا كان كذلك ، فقد أصلحته.

sickill يعمل مثل السحر بالنسبة لي الآن. 👍

نعم ، يعمل معي (مع asciinema upload ) الآن أيضًا. شكرا!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات