Asciinema: Fehlerhafte Anforderung für das Hochladen von> 4 KB-Aufnahmen unter CentOS (Python 3.4)

Erstellt am 7. Juni 2017  ·  58Kommentare  ·  Quelle: asciinema/asciinema

Fehlerbericht

Systeminformationen:

  • Verwendete Version: 1.4.0 (1.1.1 haben ebenfalls das gleiche Problem)
  • Betriebssystem: CentOS Linux Version 7.3.1611
  • Python-Version: Python 3.4.5
  • Tools installieren: yum (aus dem EPEL-Repository)

Schritte zum Reproduzieren:

  1. asciinema upload asciicast.json

Erwartetes Verhalten:

Datei auf asciinema.org hochgeladen

Tatsächliches Verhalten:

Client-Druckfehlermeldung:

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

Zusätzliche Information:

Der Client erstellt eine fehlerhafte Aufzeichnung, wenn zsh (in meinem Fall 4.3.11 (x86_64-redhat-linux-gnu) ) verwendet und oh-my-zsh installiert ist. Wenn oh-my-zsh deaktiviert oder Bash als Shell verwendet wird, kann der Client die Aufzeichnung ohne Probleme erstellen und hochladen.

JSON aufzeichnen: https://gist.github.com/andyone/b2a883e8c3795a6ad393a715ff7a41df

compatibility help wanted hosting

Hilfreichster Kommentar

Ich habe gerade zur vorherigen Konfiguration zurückgekehrt (Beenden von SSL in Nginx). Lassen Sie mich wissen, ob es jetzt für Sie funktioniert @andyone @ThiefMaster @benaryorg @peterbrittain @ThomasWaldmann

Alle 58 Kommentare

Passiert auch für mich. Verwenden Sie ZSH, aber nicht OMZ.

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

tmpw6byrbv8-asciinema.json

Ich habe festgestellt, dass alles gut funktioniert, wenn ich die API-URL von HTTPS in HTTP ändere.

Ich habe gestern die Load Balancer-Konfiguration geändert, damit dies möglicherweise zusammenhängt.

Ich konnte dies in Centos 7 Vagrant VM reproduzieren. Ich denke, das hat etwas mit dem Brightbox Load Balancer (mit SSL-Terminierung, automatischem Let's Encrypt-Zertifikat) zu tun, den wir seit gestern verwenden.

@andyone @ThiefMaster kannst du es jetzt versuchen? Ich habe es vielleicht gelöst.

immer noch eine 400

Ich denke, es ist ein OpenSSL-Problem. Das Senden von Daten mit Curl ist in Ordnung, da Curl NSS (Network Security Services) für die Arbeit mit SSL / TLS verwendet.

mit Brightbox Load Balancer

Es ist eine Nginx-basierte Lösung?

@andyone Ich denke, Brightbox Load Balancer verwendet Haproxy.

Ich kann das konsequent reproduzieren. Ich habe Vagrantfile und Anweisungen erstellt: https://github.com/sickill/bb-lb-400

@andyone das Problem scheint nicht diese bestimmte Zeile in Ihrer Aufnahme zu sein, sondern die Gesamtgröße der hochgeladenen JSON-Datei.

Ich habe mit dieser Konfiguration einen Proxy https://ascii.kaos.io erstellt, der auf Webkaos basiert (es ist @ ThiefMaster- Aufnahmen wurden erfolgreich über diesen Proxy hochgeladen.

Folgendes weiß ich bisher:

HTTP-Anforderungen werden über den Brightbox Load Balancer problemlos ausgeführt, HTTPS-Anforderungen geben jedoch 400 Bad Request aus
für die Anforderung ist , wenn der Antrag Körper größer als etwa 4 KB.

Interessant ist, dass wir unter CentOS 400 für HTTPS bekommen. HTTPS unter macOS funktioniert einwandfrei. (HTTP funktioniert überall gut).

Ich schaute tiefer und versuchte herauszufinden, wo der Unterschied ist. Ich habe tcpdump verwendet, um die Anforderungen sowohl unter CentOS als auch unter macOS anzuzeigen (HTTP, vorausgesetzt, die Anforderung selbst ist wie unter HTTPS formatiert).

Der einzige Unterschied scheint 2 leere Zeilen vor dem Text unter macOS und 1 leere Zeile unter CentOS zu sein (wahrscheinlich aufgrund einer geringfügig abweichenden Version von urllib, die mit Python 3 unter diesen Betriebssystemen geliefert wird):

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>

Mac OS:

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>

Um zu sehen, wie sich dies auf Dinge auswirkt, habe ich die "Anforderungspuffergröße" auf LB vorübergehend von 4096 (Standard) auf 8192 (max) geändert und es hat plötzlich überall gut funktioniert (alle Betriebssysteme, HTTPS), yay!

Ich bin nicht sehr sicher, dass dies die ultimative Lösung ist, denn mit einer Puffergröße von 4096 ist dies wahr:

  • Ich bin in der Lage, POST-Anfrage mit 3 MB Körper ohne Probleme zu machen
    HTTPS unter macOS
  • Daher gehe ich davon aus, dass diese Puffergröße für Header und nicht für den Anforderungshauptteil gilt (dies wurde von John von Brightbox bestätigt).
  • Ich bin in der Lage, POST-Anfragen mit <4 KB Körper ohne Probleme zu stellen
    HTTPS unter CentOS
  • Ich kann unter CentOS keine POST-Anfrage mit einem Body von> 4 KB über HTTPS stellen
  • Oben widerspricht meiner Annahme, dass Puffer nur für Header gelten ...
  • Anforderungsheader sind in allen Fällen klein (~ 330 Byte)

Wenn ich "Anforderungspuffergröße" auf 8192 stoße, werden die Körpergröße und das Protokoll angezeigt
spielt keine Rolle und alles funktioniert gut. Ich frage mich allerdings, ob durch Stoßen
es bis 8192 Ich kaufe nur Zeit (machen weniger Menschen betroffen) oder dies
löst das Problem vollständig (wenn ja, warum?).

Ich habe Brightbox darüber kontaktiert, hoffentlich können sie erklären, was los ist.

Update bezüglich 8192 Puffergröße auf Brightbox-Seite: Mit dieser Nummer funktioniert es für mich unter CentOS, aber immer noch nicht für @ThiefMaster .

Ops, sorry.

Bevor ich den Datenverkehr über Brightbox LB leitete, beendete ich SSL in Nginx und alles funktionierte jahrelang einwandfrei. Wenn es mit dem auf Nginx basierenden Proxy von @andyone funktioniert , kann dies darauf hindeuten, dass Nginx die Formatierung von Anforderungen "verzeiht", während Haproxy strenger ist und der asciinema-Client die Anforderung unter Python 3.4 (und seinen) falsch formatiert (für Haproxy-Standards) urllib, das älter ist als das 3.6.1, das ich auf dem Mac benutze).

Ich kann es später mit Haproxy überprüfen, aber meine Version wurde mit LibreSSL anstelle von OpenSSL erstellt.

Meine aktuelle Theorie lautet:

Diese einzelne neue Zeile vor Headern und Body reicht nicht aus, damit LB das Lesen von Headern beendet (es werden 2 neue Zeilen erwartet), und es werden weiterhin alle darunter liegenden Daten als Header gelesen, wobei Bytes gezählt werden, die schließlich die maximale Größe für Header überschreiten. Wenn LB eine Variable wie bytes_read (vom Socket gelesene Bytes) hat, überprüft sie ihren Wert nach Abschluss des Lesens der Header und später erneut nach dem Lesen des Körpers. Wenn Sie eine Datei mit <4 KB hochladen, wird das 4-KB-Limit für Header nie überschritten, und wenn Sie> 4 KB hochladen, wird es überschritten.
(und das passiert nur unter HTTPS)

Keine Ahnung, ob das der Fall ist, nur laut nachdenken 😀

Der Quellcode wurde aktualisiert, sodass eine zusätzliche neue Zeile hinzugefügt wird, die unter CentOS überprüft wird und weiterhin fehlschlägt. Die obige Theorie ist also falsch.

Dies funktioniert unter CentOS mit 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

Vielleicht unterscheidet sich die von Python verwendete SSL-Bibliothek von Curl und das Problem liegt irgendwo im SSL-Land?

Ich glaube schon. Python verwendet OpenSSL, Curl verwendet NSS.

@andyone das Zertifikat für ascii.kaos.io ist nicht Let's Encrypt?

RapidSSL SHA256withRSA

Normalerweise würde ich sagen, dass CentOS das Stammzertifikat für Let's Encrypt (oder so ähnlich 😊) fehlt, aber die SSL-Verbindung wird hergestellt und der Fehler liegt auf HTTP-Protokollebene (400 Bad Request), also ... 👐

Wenn das Stammzertifikat für Let's Encrypt fehlt, funktioniert es auch mit Curl nicht.

Unser (Brightbox) Load Balancer verwendet tatsächlich Haproxy. Der HTTP-RFC und die Haproxy-Dokumente geben an, dass eine CRLF erforderlich ist, um die Header vom Body zu trennen:

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

Ist es möglich, dass Sie hier nur eine CR oder eine LF senden, anstatt eine vollständige CRLF?

@sickill Dies ist ein Proxy für HA-Proxy 1.7.5 mit LibreSSL 2.5.0 - https://ascii-ha.kaos.io. Meine und @ ThiefMaster- Aufnahmen sowie over-4k.json aus Ihrem Repository wurden erfolgreich über diesen Proxy hochgeladen.

@andyone ok. Können Sie also tune.bufsize (https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#3.2-tune.bufsize) in 4096 ändern?

@ Johnl Ich habe nach CRLF

Ich habe die Anforderung sowohl unter CentOS als auch unter macOS erneut ausgegeben (wiederum über HTTP, vorausgesetzt, die HTTP-Nutzdaten sind für HTTPS gleich).

dump-centos.pcap.txt und dump-mac.pcap.txt enthalten tcpdump capture ( tcpdump -s 0 dst port 80 -w dump-centos.pcap.txt ).
dump-centos-hex.txt und dump-mac-hex.txt enthalten hexadezimal formatierte Dumps (über hexdump -C ).

dump-centos-hex.txt
dump-centos.pcap.txt
dump-mac-hex.txt
dump-mac.pcap.txt

Es scheint, dass auf beiden Betriebssystemen CRLF für neue Zeilen verwendet wird und es eine leere Zeile zwischen Kopfzeilen und Text gibt.

Links CentOS, rechts macOS:

centos-mac-comparison

@sickill Config aktualisiert. over-4k.json hochgeladen.

@andyone danke für das Update. Es scheint, dass kein X-Forwarded-Proto -Header hinzugefügt wird (da die zurückgegebene Aufnahme-URL http:// ). Können Sie http-request set-header X-Forwarded-Proto https if { ssl_fc } hinzufügen?

Das ist meine Konfiguration:

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

Wo soll ich diese Zeile hinzufügen?

@andyone Ich denke, es muss in den Bereich backend (ich bin allerdings kein Haproxy-Experte).

@andyone übrigens, ich schätze es WIRKLICH, dass Sie beim Debuggen helfen. 😍 Danke!

Vergiss nicht, vorwärts zu gehen. Dies sollte das Setup ziemlich genau replizieren, auch mit den SSL-Chiffren:

    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

Ich habe die Konfiguration dahingehend geändert, aber ohne Glück:

    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

Der Client gibt weiterhin Links mit http:// .

Ich bin immer gerne bereit, die nützlichen Dienste zu verbessern 😉.

@johnl Dies ist die vollständige Konfiguration. Alle erforderlichen Optionen sind in den Abschnitten defaults und 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

Wenn die Haproxy -Konfiguration von @andyone jetzt sehr nahe an BB liegt und wir das Problem immer noch nicht reproduzieren können, ist es sinnvoll, es mit Let's Encrypt cert zu versuchen? Dies ist einer der Unterschiede zwischen https://ascii-ha.kaos.io und https://asciinema.org.

Dies ist einer der Unterschiede zwischen https://ascii-ha.kaos.io und https://asciinema.org.

BB LB kann mit OpenSSL erstellt werden (ich verwende LibreSSL).

Ich werde versuchen, das Let's Encrypt-Zertifikat für https://ascii-ha.kaos.io hinzuzufügen

Fertig - https://ascii.kaos.re
HA-Proxy 1.7.5 (mit LibreSSL 2.5.0) + Verschlüsseln wir das Zertifikat (erstellt von Certbot)
Konfiguration:

    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

Sieht so aus, als ob alles gut funktioniert. over-4k.json erfolgreich hochgeladen.

Ich habe keine weiteren Ideen dafür. Ich erwäge, für den Lastausgleich und die SSL-Beendigung auf meine eigene Nginx-Instanz zurückzugreifen

Ich versuche, dies auf einen einzigen Curl-Befehl zu reduzieren, der das Problem reproduzieren kann, es aber noch nicht geschafft hat. Kann mir jemand helfen?

Ich poste einen 5k-Body mit einem Authentifizierungs-Benutzernamen / Passwort unter Verwendung von Curl. Ich treffe einen Brightbox-Load-Balancer mit einem Netcat-Webserver-Backend, damit ich den Rohanforderungstext sehen kann. Es geht immer durch - kann nicht dazu führen, dass eine schlechte Anforderungsantwort ausgelöst wird.

Wenn dies vom Load Balancer abgelehnt wird, sollte ich keine echte Instanz der App im Backend benötigen, da sie niemals so weit kommen sollte - also sollten wir dies mit Curl und ohne App reproduzieren können.

Ich habe Curl auf Ubuntu und Centos7 und speziell mit openssl ausprobiert (beachten Sie, dass Sie den Befehl --engine zum Curlen angeben können, um auszuwählen, welche sslib-Bibliothek verwendet werden soll. Centos7-Curl-Binärdateien werden für die meisten Optionen erstellt).

@ Johnl, danke, dass

Es ist sinnvoll, netcat als Backend zum Testen zu verwenden 👍

Das Curl-Äquivalent für asciinema upload over-4k.json ist mehr oder weniger Folgendes:

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

(Ersetzen Sie uuid4 durch das Ergebnis von python3 -c 'import uuid; print(uuid.uuid4())' )

Und es funktioniert tatsächlich mit Locken ...

Ich habe tcpdump von asciinema upload und die oben genannte Locke verglichen, und auf HTTP-Protokollebene gibt es nichts, was mir verdächtig erscheint. Einige TCP-Frames werden jedoch an verschiedenen Orten angezeigt (möglicherweise werden mehr / weniger Daten gesendet / passen in jedes TCP-Paket).

Ich habe eine HTTP-Anfrage (an http://asciinema.org) mit tcpflow in CentOS 7 VM erfasst:

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

Dann lief in einer anderen Shell (in derselben VM):

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

Ich habe die Antwort abgeschnitten und nur eine Anfrage hinterlassen. Folgendes wird byteweise tcpflow-req.txt

Ich habe diese erfasste HTTP-Anfrage gegen asciinema wiedergegeben. org: 80 mit 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

Alles gut.

Jetzt habe ich über SSL an asciinema gesendet. org: 443 :

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

Hier ist das Ergebnis:

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 Können Sie dieselbe Anfrage mit https://ascii.kaos.re überprüfen

@andyone gerade überprüft. Hat dies (cat tcpflow-req.txt; cat) | openssl s_client -connect ascii.kaos.re:443 - erfolgreich hochgeladen.

Ich habe hier mehr gegraben. curl on centos7 verwendet nss, aber wget verwendet openssl. Ich kann die Anfrage erfolgreich entweder mit curl oder wget senden. Ich kann sogar mit dem Python-httpie-Tool (unter Python 3) senden.

es kann jedoch nicht über stdin an openssl s_client gesendet werden

Es ist jedoch erfolgreich, es an openssl s_client zu senden, indem die Anforderung eingefügt wird, anstatt stdin zu verwenden!

Ich bin mir jetzt ziemlich sicher, dass dies daran liegt, dass etwas Anfragen mit LF-Zeilenenden anstatt mit den erforderlichen CRLF-Zeilenenden sendet, aber ich bin mir nicht ganz sicher, was. Ich denke, "openssl s_client" ist ein schlechtes Testwerkzeug und macht es schwierig, sicher zu sein, was los ist.

Aber ich habe dies noch nicht mit einem richtigen http-Client reproduziert, egal ob mit nss oder openssl (curl on ubuntu verwendet openssl und funktioniert auch einwandfrei, also habe ich das doppelt bestätigt). Schafft das sonst noch jemand?

Ich habe gerade selbst einige Tests durchgeführt und kann bestätigen, dass dieses Problem bei einer Inhaltslänge von 4520 weiterhin besteht, jedoch nicht bei derselben Anforderung, die um 1000 Zeichen reduziert wurde ( Content-Length angepasst an die vorgenommenen Änderungen).

Die CRLF sind in allen meinen Tests vorhanden und xxd bestätigt, dass sie über die Pipe gesendet werden.
Ich könnte auch mit OpenBSDs nc (das TLS unterstützt) testen.

Aus der Dokumentation :

tune.bufsize
Legt die Puffergröße auf diese Größe (in Bytes) fest. Niedrigere Werte ermöglichen mehr
Sitzungen können in derselben RAM-Größe koexistieren, und höhere Werte ermöglichen einige
Anwendungen mit sehr großen Cookies funktionieren. Der Standardwert ist 16384 und
kann zur Erstellungszeit geändert werden. Es wird dringend empfohlen, dies nicht zu ändern
vom Standardwert, da sehr niedrige Werte einige Dienste wie z
Statistiken und Werte, die größer als die Standardgröße sind, erhöhen die Speichernutzung.
Dies kann dazu führen, dass dem System der Speicher ausgeht. Zumindest die globale maxconn
Der Parameter sollte um den gleichen Faktor verringert werden, um den dieser erhöht wird.
Wenn die HTTP-Anforderung größer als (tune.bufsize - tune.maxrewrite) ist, wird haproxy dies tun
Rückgabe HTTP 400 (Bad Request) Fehler. Ebenso, wenn eine HTTP-Antwort größer ist
Als diese Größe gibt Haproxy HTTP 502 (Bad Gateway) zurück.

Im Gegensatz zu Nginx, das nicht die gesamte Anforderung im Speicher behält, sondern sie im laufenden Betrieb weiterleitet (AFAIK) oder zumindest in eine temporäre Datei puffert.

Es gibt die Option no option http-buffer-request , die, wenn ich das richtig verstanden habe, genau dieses Verhalten deaktiviert (geschrieben für option http-buffer-request , ohne no ):

Es ist manchmal wünschenswert, vorher auf den Text einer HTTP-Anforderung zu warten
eine Entscheidung treffen. Dies ist, was von "balance url_param" für getan wird
Beispiel. Der erste Anwendungsfall besteht darin, Anforderungen von langsamen Clients vorher zu puffern
Verbinde mit dem Server. Ein weiterer Anwendungsfall besteht darin, das Routing zu übernehmen
Entscheidung auf der Grundlage des Inhalts der Anforderungsstelle. Diese Option befindet sich in einem
Frontend oder Backend zwingen die HTTP-Verarbeitung, auf das Ganze zu warten
body wird empfangen oder der Anforderungspuffer ist voll oder der erste Block ist
vollständig bei Chunked-Codierung. Es kann unerwünschte Nebenwirkungen mit haben
Einige Anwendungen missbrauchen HTTP, indem sie ungepufferte Übertragungen zwischen erwarten
das Frontend und das Backend, daher sollte dies definitiv nicht von verwendet werden
Standard.

Ich habe das auch gerade getroffen. Es fällt mir auf, dass beim Testen desselben Inhalts, der über HTTP, jedoch nicht über HTTPS funktioniert, wahrscheinlich nicht die Puffergröße fehlerhaft ist, es sei denn, etwas zwischen Ihrem Client und dem Proxy fügt viele zusätzliche Header hinzu.

Aber vielleicht gibt es einen Fehler bei der Beendigung Ihrer SSL-Verbindungen, so dass die Header leicht beschädigt werden.

In diesem Fall gibt es eine Option, die die Sicherheit von HAProxy verringert, jedoch weniger konformen HTTP-Verkehr zulässt. Siehe https://stackoverflow.com/questions/39286346/extra-space-in-http-headers-gives-400-error-on-haproxy

Obwohl ich nicht befürworte, die Sicherheit als endgültige Lösung zu reduzieren, können Sie den Dienst möglicherweise während des Debuggens beibehalten.

@peterbrittain im Moment verwendet asciinema.org den Brightbox Cloud Load Balancer, daher kontrolliere ich ihre Haproxy-Konfiguration nicht. Wir haben SSL in unserem eigenen Nginx beendet und das hat gut funktioniert. Seit ich zu BB LB gewechselt bin, tritt dieses Problem (für einige) auf. Erleben Sie es unter CentOS oder einem anderen System?

Ehrlich gesagt hatte ich kein Problem mit der vorherigen Nginx-basierten Lösung. Das SSL-Zertifikat, das wir hatten, lief ab, also dachte ich, ich werde mit Let's Encrypt gehen. Da LE-Zertifikate nur von kurzer Dauer sind, werden sie am besten automatisch verwaltet, und Brightbox LB erledigt das für mich. Ich wollte mir nur die Arbeit beim Einrichten von LE sparen und BB LB schien die einfachste Lösung zu sein (da asciinema.org von Brightbox gesponsert wird und auf ihrer großartigen Infrastruktur läuft). Jetzt denke ich, dass das Einrichten von LE selbst in Nginx wahrscheinlich 1/10 der Zeit in Anspruch nehmen würde, die ich bereits damit verbracht habe, dieses Problem zu beheben 😞😞😞

Ah. Ich habe die Subtilität nicht erkannt, wem welche Teile gehörten. Haben Sie Glück gehabt, Diags von BB für diese Ausgabe zu bekommen?

Und als Antwort auf Ihre Frage: Meine Box ist eine CentOS 6-VM.

Ich habe auch gerade das Problem mit der schlechten Anfrage mit asciinema 1.2.0 (Version von Ubuntu 16.04 lts) erlebt.

Der oben angegebene Curl-Hack hat funktioniert, danke.

Ich habe gerade festgestellt, dass dieselbe Datei auf meiner Gentoo [1] -Box eine schlechte Anfrage liefert, nicht jedoch auf meiner OpenBSD [2] -Box.
Das OpenBSD lädt es ganz gut hoch.
Ich denke, es sollte weitere Untersuchungen zum Unterschied zwischen diesen Kunden geben.
Die Gentoo-Box unterstützt die folgenden Python-Ziele pro Ebuild:

PYTHON_TARGETS="python3_4 -python3_5"

Ich kann Python3.5 derzeit zwar nicht einfach testen, aber vielleicht hilft das schon.

Bearbeiten : Ich habe die OpenSSL-Versionen hinzugefügt und diese komplett vergessen.

  • asciinema 1.4.0

    • ausgeführt mit python-exec 2.4.5

    • wiederum Python 3.4.6 ausführen

  • OpenSSL 1.0.2l 25. Mai 2017

  • asciinema 1.3.0

    • ausgeführt mit Python 3.6.0
  • LibreSSL 2.5.2

Ich habe gerade zur vorherigen Konfiguration zurückgekehrt (Beenden von SSL in Nginx). Lassen Sie mich wissen, ob es jetzt für Sie funktioniert @andyone @ThiefMaster @benaryorg @peterbrittain @ThomasWaldmann

@sickill Ich bin nur zu 85% sicher, dass es dieselbe Datei ist, die zuvor fehlgeschlagen ist, aber wenn ja, haben Sie sie behoben.

@sickill Funktioniert jetzt wie ein Zauber für mich. 👍

Ja, funktioniert jetzt auch für mich (mit asciinema upload ). Vielen Dank!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

pfalcon picture pfalcon  ·  4Kommentare

redaxmedia picture redaxmedia  ·  3Kommentare

ThomasWaldmann picture ThomasWaldmann  ·  3Kommentare

yuvalif picture yuvalif  ·  10Kommentare

bashfulrobot picture bashfulrobot  ·  11Kommentare