Asciinema: 在CentOS(Python 3.4)下,对上传> 4kb录音的错误请求

创建于 2017-06-07  ·  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 :

compatibility help wanted hosting

最有用的评论

我刚刚切换回以前的配置(在Nginx中终止SSL)。 让我知道它现在是否对您有用@andyone @ThiefMaster @benaryorg @peterbrittain @ThomasWaldmann

所有58条评论

也为我而发生。 使用ZSH,但不使用OMZ。

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

tmpw6byrbv8-asciinema.json

我发现,如果我将API网址从HTTPS更改为HTTP,则一切正常。

我昨天更改了负载均衡器配置,因此可能与之相关。

我能够在Centos 7 Vagrant VM中重现它。 我认为这与我们从昨天开始使用的Brightbox负载平衡器(具有SSL终止功能,自动让我们加密证书)有关。

@andyone @ThiefMaster您现在可以尝试吗? 我可能已经解决了。

仍然得到400

我认为这是与OpenSSL相关的问题。 使用curl发送数据是可以的,因为curl使用NSS(网络安全服务)来使用SSL / TLS。

使用Brightbox负载平衡器

这是基于nginx的解决方案吗?

@andyone我认为Brightbox负载平衡器使用Haproxy。

我可以始终如一地重现这一点。 我创建了Vagrantfile和说明: https :

@andyone问题似乎不是录制中的特定行,而是上传的json文件的整体大小。

我使用此配置基于webkaos (使用BoringSSL改进了nginx)创建了一个代理https://ascii.kaos.io 。 我和@ThiefMaster录音已通过此代理成功上传。

到目前为止,这是我所知道的:

HTTP请求可以通过Brightbox负载平衡器正常运行,但是HTTPS可以提供​​400错误请求
对于请求,其中请求正文大于约4KB。

有趣的是,在CentOS下,我们的HTTPS获得400。 在macOS下使用HTTPS可以正常工作。 (HTTP在任何地方都可以正常工作)。

我看得更深,试图找出区别。 我使用tcpdump来查看CentOS和macOS上的请求(HTTP,假定请求本身的格式与HTTPS下的格式相同)。

唯一的区别似乎是在macOS上的正文之前有2个空行,在CentOS上有1个空行(可能是由于这些操作系统上的Python 3附带的urllib版本略有不同):

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>

苹果系统:

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的缓冲区大小,这是真的:

  • 我可以用3MB的主体发出POST请求,而不会出现问题
    macOS上的HTTPS
  • 因此,我假设此缓冲区的大小用于标题而不是请求正文(这已由Brightbox的John确认)
  • 我可以发出<4KB正文的POST请求,而不会出现问题
    CentOS上的HTTPS
  • 我无法在CentOS上通过HTTPS发出大于4KB正文的POST请求
  • 以上与我关于仅适用于标头的缓冲区的假设相矛盾...
  • 在所有情况下,请求标头都很小(〜330字节)

当我将“请求缓冲区大小”提高到8192时,主体大小和协议
没关系,一切正常。 我想知道是否通过颠簸
到8192我只是在买时间(减少受影响的人),或者这样
完全解决问题(如果是,那么为什么?)。

我就此事联系了Brightbox,希望他们能解释发生了什么。

在Brightbox侧更新re 8192缓冲区大小:使用此数字,它在CentOS下对我有效,但对于@ThiefMaster仍然不起作用。

抱歉,对不起。

在通过Brightbox LB传输流量之前,我在Nginx中终止了SSL,多年来一切正常。 如果它与基于Nginx的@andyone代理一起工作,则可能表明Nginx对请求格式更为“宽容”,而Haproxy更为严格,并且asciinema客户端在Python 3.4(及其Haperoxy标准)下错误地格式化了请求(对于Haproxy标准) urllib,该版本早于我在Mac上使用的3.6.1)。

我可以稍后使用Haproxy进行检查,但是我的版本是使用LibreSSL而不是OpenSSL构建的。

我目前的理论是这样的:

标头和正文之前的这一新行不足以使LB完成读取标头的工作(它需要2条新行),并且它将继续读取其下的所有数据作为标头,并计数字节,最终超过标头的最大大小。 如果LB具有bytes_read类的变量(从套接字读取的字节),则在完成读取标头之后,然后在读取正文之后,再检查其值。 如果您上传<4kb文件,则该文件头永远不会超过4kb的限制;如果您上传> 4kb,则该文件会超过该限制。
(这仅在HTTPS下发生)

不知道是不是这样,只是大声思考😀

更新了源代码,因此它添加了额外的新行,在CentOS下进行了检查,但仍然失败。 所以以上理论是错误的。

在带有HTTPS的CentOS下可以使用:

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

因此,也许Python使用的SSL库与curl有所不同,问题出在SSL领域吗?

我想是这样。 Python使用OpenSSL,curl使用NSS。

@andyone ascii.kaos.io的证书不是“让我们加密吗?”

使用SSL的RapidSSL SHA256

通常,我会说CentOS缺少“让我们加密”(或类似😊)的根证书,但是正在建立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这是具有LibreSSL 2.5.0的HA-Proxy 1.7.5-https://ascii-ha.kaos.io 我和@ThiefMaster录音,以及您存储库中的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上tcpdump了该请求(再次通过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 )。

dump-centos-hex.txt
dump-centos.pcap.txt
dump-mac-hex.txt
dump-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这是完整的配置,所有必需的选项都在defaultsglobal部分中设置:

    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.iohttps://asciinema.org之间的区别之一

这是https://ascii-ha.kaos.iohttps://asciinema.org之间的区别之一

不可以。BBLB可以使用OpenSSL构建(我使用LibreSSL)。

我将尝试为https://ascii-ha.kaos.io添加“让我们加密”证书

完成-https: //ascii.kaos.re
HA-Proxy 1.7.5(含LibreSSL 2.5.0)+加密证书(由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的身份验证用户名/密码。 我正在使用netcat Web服务器后端连接Brightbox负载平衡器,因此可以看到原始请求文本。 它总是经过-无法使其触发错误的请求响应。

如果负载均衡器拒绝了此操作,则我不需要后端上的应用程序真实实例,因为它永远不会那么遥远-因此我们应该能够使用curl而不使用任何应用程序来重现该实例。

我已经尝试过在ubuntu和centos7上使用curl,特别是使用openssl(注意,您可以指定--engine命令来curl来选择要使用的sslib库。centos7 curl二进制文件是针对大多数选项构建的)

@johnl感谢您对此进行调查。

将netcat用作测试的后端很有意义👍

asciinema upload over-4k.json curl等效值大致是这样的:

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

(用uuid4的结果替换python3 -c 'import uuid; print(uuid.uuid4())'

它确实可以卷曲...

我比较了asciinema upload tcpdump和上面的卷曲,在HTTP协议级别上没有任何可疑的东西。 但是,某些tcp帧显示在不同的位置(可能在每个tcp数据包中发送/适配的数据更多/更少)。

我在CentOS 7 VM中使用tcpflow捕获了HTTP请求(到http://asciinema.org):

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

然后在另一个shell(在同一VM中)中运行:

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

我切断了响应,只留下了请求。 这是逐字节发送的内容: tcpflow-req.txt

我针对asciinema重播了这个捕获的HTTP请求。 org:80nc

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。 org: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 @约翰

@sickill您可以通过https://ascii.kaos.re检查相同的请求

@andyone刚刚检查。 这(cat tcpflow-req.txt; cat) | openssl s_client -connect ascii.kaos.re:443 -成功上传了吗?

我在这里做了更多的挖掘工作。 centos7上的curl使用nss,而wget使用openssl。 我可以使用curl或wget成功发送请求。 我什至可以使用python httpie工具(在python 3下)发送。

但它无法通过stdin将其发送到openssl s_client

但是通过将请求粘贴到openssl s_client而不是使用stdin,成功将其发送到openssl s_client!

我现在很确定这是因为某些东西正在发送带有LF行尾而不是必需的CRLF行尾的请求,但是我不确定是什么。 我认为“ openssl s_client”是一个不好的测试工具,并且很难确定发生了什么。

但是我还没有使用适当的http客户端,无论是使用nss还是openssl来重现此代码(ubuntu上的curl也使用openssl并且也可以正常工作,因此请再次确认)。 有人管理吗?

我刚刚进行了一些测试,可以确认内容长度为4520的问题仍然存在,但是相同的请求被1000个字符剥离( Content-Length根据所做的更改进行

我的所有测试中都包含CRLF,并且xxd确认它们已通过管道发送。
我还可以使用OpenBSD的nc (支持TLS)进行测试。

文档中

tune.bufsize
将缓冲区大小设置为此大小(以字节为单位)。 较低的值允许更多
会话共存于相同数量的RAM中,更高的值允许一些
具有非常大的Cookie的应用程序。 默认值为16384,
可以在构建时更改。 强烈建议不要更改此设置
从默认值开始,因为非常低的值会破坏某些服务,例如
统计信息,并且值大于默认大小会增加内存使用量,
可能导致系统内存不足。 至少是全局的maxconn
参数的减小应与增加该参数的因素相同。
如果HTTP请求大于(tune.bufsize-tune.maxrewrite),则haproxy将
返回HTTP 400(错误请求)错误。 同样,如果HTTP响应较大
超过此大小后,haproxy将返回HTTP 502(错误网关)。

与nginx相比,nginx不会将整个请求保留在内存中,而是即时传递(AFAIK)或至少将其传递到一个临时文件中。

no option http-buffer-request Option ,如果我没弄错的话,它会完全禁用该行为(为option http-buffer-request编写,没有no ):

有时最好先等待HTTP请求的内容,然后再执行
做出决定。 这是通过“ balance url_param”来完成的
例子。 第一个用例是在启动之前缓冲来自慢速客户端的请求
连接到服务器。 另一个用例是进行路由
根据请求主体的内容进行决策。 此选项放置在
前端或后端强制HTTP处理要等到整个
接收到正文,或者请求缓冲区已满,或者第一个块是
在分块编码的情况下完成。 它可能具有不希望出现的副作用
一些应用程序期望HTTP和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配置。 我们曾经在自己的Nginx中终止SSL,并且工作正常。 由于我切换到BB LB,因此会发生此问题(某些情况)。 您是否正在CentOS或其他系统上体验它?

坦白说,我以前的基于Nginx的解决方案没有任何问题。 我们拥有的SSL证书即将到期,所以我认为我会选择“让我们加密”。 由于LE证书的寿命很短,因此最好对其进行自动管理,而Brightbox LB会为我做到这一点。 我只是想节省设置LE的工作,而BB LB似乎是最简单的解决方案(因为asciinema.org由Brightbox赞助并在其强大的基础架构上运行)。 现在,我认为自己在Nginx中设置LE可能会花费我已经花费了很多时间解决该问题的时间的1/10😞😞😞

啊。 我没有发现谁拥有哪些位的微妙之处。 您是否有运气从BB获得此问题的诊断?

并回答您的问题:我的机器是CentOS 6 VM。

我还遇到了错误的请求问题,使用了asciinema 1.2.0(来自ubuntu 16.04 lts的版本)。

上面给出的curl hack起作用了,谢谢。

我刚刚发现,同一文件确实在我的Gentoo [1]框上产生了一个错误的请求,但在我的OpenBSD [2]框上却没有发出错误的请求。
OpenBSD上传就可以了。
我认为应该进一步调查这些客户之间的区别。
每个ebuild的Gentoo框都支持以下Python目标:

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 2017年5月25日

  • 腹水1.3.0

    • 使用Python 3.6.0执行
  • LibreSSL 2.5.2

我刚刚切换回以前的配置(在Nginx中终止SSL)。 让我知道它现在是否对您有用@andyone @ThiefMaster @benaryorg @peterbrittain @ThomasWaldmann

@sickill我只能确定它与之前失败的文件相同,但只有85%,如果已修复,则可以修复。

@sickill现在对我来说就像是一种魅力。 👍

是的,现在也为我工作(使用asciinema upload )。 谢谢!

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

redaxmedia picture redaxmedia  ·  3评论

yuvalif picture yuvalif  ·  10评论

abaykan picture abaykan  ·  10评论

Bux42 picture Bux42  ·  9评论

deeplook picture deeplook  ·  10评论