我有一个Azure应用服务,我需要在其中激活 tls相互认证,我遇到了一个完全出乎意料的问题。我们需要此服务才能从IoT设备上传图像;这些图像相对较小(< 300 kb),并且它们通过 multipart/form-data
http post请求上传到此端点。
问题:通过启用客户端身份验证,我们只能上传小于100 kb的文件(我不知道确切的限制;我知道100,000个字节可以工作,而150,000个字节不起作用)。任何比这更大的东西,我们从Load Balancer 中收到403 Forbidden (请求永远不会达到我们的代码)。如果我们禁用客户端身份验证,所有内容均可按预期工作(请求达到我们的代码,该代码会记录请求,然后显然会失败,因为 X-arr-clientcert
header缺少header,但至少至少该请求浏览我们的应用程序)。
我无法找到有关此主题的任何资源,Microsoft在使用客户端身份验证时似乎没有记录任何尺寸限制,而且我们从未打算限制文件大小。最让我感到困扰的是,限制似乎仅在使用客户端身份验证时才会出现,这对我而言对我没有意义(如果有的话,使用客户端身份验证时,规则应该更加放松)。
还有其他人遇到过吗?任何指针都会有所帮助,我完全认为它是这样的,我应该如何进一步调查它,或者如何解决这个问题。
le :这是我尝试上传小文件(100,000字节)时的行为:
$ curl --cert my.crt --key my.key https://my-site.azurewebsites.net/Upload/uploadImage -F [email protected] --cookie-jar sys-cookies.jar --cookie sys-cookies.jar --tlsv1.2 -v
* Trying x.x.x.x:443...
* Connected to my-site.azurewebsites.net (x.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; CN=*.azurewebsites.net
* start date: Mar 14 18:39:55 2022 GMT
* expire date: Mar 9 18:39:55 2023 GMT
* subjectAltName: host "my-site.azurewebsites.net" matched cert's "*.azurewebsites.net"
* issuer: C=US; O=Microsoft Corporation; CN=Microsoft Azure TLS Issuing CA 01
* SSL certificate verify ok.
> POST /Upload/uploadImage
> Host: my-site.azurewebsites.net
> User-Agent: curl/7.74.0
> Accept: */*
> Cookie: ARRAffinitySameSite=b[...]7; ARRAffinity=b[...]7
> Content-Length: 100193
> Content-Type: multipart/form-data; boundary=------------------------e6811f73870ec90c
>
* We are completely uploaded and fine
* TLSv1.2 (IN), TLS handshake, Hello request (0):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< Content-Type: application/json; charset=utf-8
< Date: Thu, 09 Jun 2022 06:46:01 GMT
< Server: Microsoft-IIS/10.0
< Access-Control-Allow-Origin: *
* Replaced cookie ARRAffinity="b[...]7" for domain my-site.azurewebsites.net, path /, expire 0
< Set-Cookie: ARRAffinity=b[...]7;Path=/;HttpOnly;Secure;Domain=my-site.azurewebsites.net
* Replaced cookie ARRAffinitySameSite="b[...]7" for domain my-site.azurewebsites.net, path /, expire 0
< Set-Cookie: ARRAffinitySameSite=b[...]7;Path=/;HttpOnly;SameSite=None;Secure;Domain=my-site.azurewebsites.net
< Transfer-Encoding: chunked
< X-Powered-By: ASP.NET
<
* Connection #0 to host my-site.azurewebsites.net left intact
{"error":"Error on uploading image!"}
错误是由我们的代码发出的,因为我只是将JPEG文件截断为100,000字节,因此显然不再是有效的图像。
为了进行比较,这是一个大文件(150,000字节)的情况:
$ curl --cert my.crt --key my.key https://my-site.azurewebsites.net/Upload/uploadImage -F [email protected] --cookie-jar sys-cookies.jar --cookie sys-cookies.jar --tlsv1.2 -v
* Trying x.x.x.x:443...
* Connected to my-site.azurewebsites.net (x.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; CN=*.azurewebsites.net
* start date: Mar 14 18:39:55 2022 GMT
* expire date: Mar 9 18:39:55 2023 GMT
* subjectAltName: host "my-site.azurewebsites.net" matched cert's "*.azurewebsites.net"
* issuer: C=US; O=Microsoft Corporation; CN=Microsoft Azure TLS Issuing CA 01
* SSL certificate verify ok.
> POST /Upload/uploadImage HTTP/1.1
> Host: my-site.azurewebsites.net
> User-Agent: curl/7.74.0
> Accept: */*
> Cookie: ARRAffinitySameSite=b[...]7; ARRAffinity=b[...]7
> Content-Length: 150193
> Content-Type: multipart/form-data; boundary=------------------------8f78ee43724d4b8d
>
* TLSv1.2 (IN), TLS handshake, Hello request (0):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Content-Length: 0
< Connection: close
< Date: Thu, 09 Jun 2022 06:45:39 GMT
<
* we are done reading and this is set to close, stop send
* Closing connection 0
请注意,加载平衡器如何主动终止请求过早终止请求 - 交易所对于更长的文件而言要短得多,并且Curl永远不会完成上传文件。 ; 它甚至从未达到100,000个字节!
I have an Azure App Service where I need to activate TLS mutual authentication, and I ran into a completely unexpected issue. We need this service in order to upload images from IoT devices; the images are relatively small (<300 KB), and they are uploaded via multipart/form-data
HTTP POST requests to this endpoint.
The problem: with client-side authentication enabled we can only upload files smaller than 100 KB (I don't know the exact limit; I know 100,000 bytes works, and 150,000 bytes doesn't work). Anything larger than that, and we receive 403 Forbidden from the load balancer (the request never reaches our code). If we disable client-side authentication everything works as expected (the request reaches our code, which logs the request and then obviously fails, since the X-ARR-ClientCert
header is missing – but at least the request goes through to our application).
I was unable to find any resources regarding this topic, Microsoft doesn't seem to document any size limitation when using client-side authentication, and we never intended to limit the file sizes. The thing that bothers me most is that the limitation seems to appear only when using client-side authentication, which makes no sense to me from a security perspective (if anything, the rules should be more relaxed when using client-side authentication).
Did anyone else encounter this? Any pointers would help, I'm totally stumped as to why it behaves like this, how I should investigate it further, or how I could go about addressing the issue.
LE: here's how it behaves when I try to upload a small file (100,000 bytes):
$ curl --cert my.crt --key my.key https://my-site.azurewebsites.net/Upload/uploadImage -F [email protected] --cookie-jar sys-cookies.jar --cookie sys-cookies.jar --tlsv1.2 -v
* Trying x.x.x.x:443...
* Connected to my-site.azurewebsites.net (x.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; CN=*.azurewebsites.net
* start date: Mar 14 18:39:55 2022 GMT
* expire date: Mar 9 18:39:55 2023 GMT
* subjectAltName: host "my-site.azurewebsites.net" matched cert's "*.azurewebsites.net"
* issuer: C=US; O=Microsoft Corporation; CN=Microsoft Azure TLS Issuing CA 01
* SSL certificate verify ok.
> POST /Upload/uploadImage
> Host: my-site.azurewebsites.net
> User-Agent: curl/7.74.0
> Accept: */*
> Cookie: ARRAffinitySameSite=b[...]7; ARRAffinity=b[...]7
> Content-Length: 100193
> Content-Type: multipart/form-data; boundary=------------------------e6811f73870ec90c
>
* We are completely uploaded and fine
* TLSv1.2 (IN), TLS handshake, Hello request (0):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< Content-Type: application/json; charset=utf-8
< Date: Thu, 09 Jun 2022 06:46:01 GMT
< Server: Microsoft-IIS/10.0
< Access-Control-Allow-Origin: *
* Replaced cookie ARRAffinity="b[...]7" for domain my-site.azurewebsites.net, path /, expire 0
< Set-Cookie: ARRAffinity=b[...]7;Path=/;HttpOnly;Secure;Domain=my-site.azurewebsites.net
* Replaced cookie ARRAffinitySameSite="b[...]7" for domain my-site.azurewebsites.net, path /, expire 0
< Set-Cookie: ARRAffinitySameSite=b[...]7;Path=/;HttpOnly;SameSite=None;Secure;Domain=my-site.azurewebsites.net
< Transfer-Encoding: chunked
< X-Powered-By: ASP.NET
<
* Connection #0 to host my-site.azurewebsites.net left intact
{"error":"Error on uploading image!"}
The error is issued by our code, because I simply truncated a JPEG file to 100,000 bytes, so it's obviously not a valid image anymore.
For comparison, here's what happens with a large file (150,000 bytes):
$ curl --cert my.crt --key my.key https://my-site.azurewebsites.net/Upload/uploadImage -F [email protected] --cookie-jar sys-cookies.jar --cookie sys-cookies.jar --tlsv1.2 -v
* Trying x.x.x.x:443...
* Connected to my-site.azurewebsites.net (x.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; CN=*.azurewebsites.net
* start date: Mar 14 18:39:55 2022 GMT
* expire date: Mar 9 18:39:55 2023 GMT
* subjectAltName: host "my-site.azurewebsites.net" matched cert's "*.azurewebsites.net"
* issuer: C=US; O=Microsoft Corporation; CN=Microsoft Azure TLS Issuing CA 01
* SSL certificate verify ok.
> POST /Upload/uploadImage HTTP/1.1
> Host: my-site.azurewebsites.net
> User-Agent: curl/7.74.0
> Accept: */*
> Cookie: ARRAffinitySameSite=b[...]7; ARRAffinity=b[...]7
> Content-Length: 150193
> Content-Type: multipart/form-data; boundary=------------------------8f78ee43724d4b8d
>
* TLSv1.2 (IN), TLS handshake, Hello request (0):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Content-Length: 0
< Connection: close
< Date: Thu, 09 Jun 2022 06:45:39 GMT
<
* we are done reading and this is set to close, stop send
* Closing connection 0
Notice how the load balancer actively terminates the request prematurely – the exchange is much shorter for the longer file, and cURL never finishes uploading the file; it never even reaches the 100,000 byte mark!
发布评论
评论(1)
le 2022-09 :事实证明,这是由于传统IIS引擎的行为与
curl
(不是openssl
)引起的。如果您遇到此问题,只需使用-H期望拨打卷发:100-CONTINUE
才能强迫它发送该标头。您可以安全地忽略本段以下的所有内容;我只是出于历史目的将其留在这里。事实证明,目前在Azure App Services中有一个小故障,它仅在这些特定情况下表现出来:
我已经执行了以下测试:
在有限的时间内 可以使用任何Linux的味道检查自己的ARM设备:
或者,如果您想更加小心(如应该是),请在URL上下载脚本,对其进行检查,然后执行该脚本,
或者可以测试任何在上面的容器替代方案中,
我昨晚在Microsoft提交了一个错误报告,
le :我还提交了 bug openssl ,因为这一定是问题的根本原因(Azure可能对TLS交换太挑剔,但是OpenSSL在不同的平台上的行为不应有所不同)。
le2 :我发表了我的实验性工作台任何人都发现它有用。
le3 :事实证明毕竟对于特定的Linux发行版!
le4 :经过初步评估后,Microsoft支持人员告诉我使用五岁的博客文章描述了2007年大约2007年的IIS问题。或禁用相互tls共。我笑了。
le5 :这是Microsoft在此问题上的最终立场:
我认为这是关闭的。我们基本上应该解决它;就是这样。
LE 2022-09: It turns out this is caused by a mismatch between the behavior of a legacy IIS engine and
curl
(notopenssl
). If you ever encounter this issue, just call curl with-H Expect: 100-continue
in order to force it to send that header. You can safely ignore everything below this paragraph; I only left it here for historical purposes.It turns out there's currently a glitch in Azure App Services which only manifests itself in these particular circumstances:
I have performed the following tests:
For a limited time you can check your own ARM device using any flavor of Linux like so:
or, if you want to be more careful (as you should be), download the script at the URL, inspect it, and then execute it,
or you can test any of the containerized alternatives above with
I submitted a bug report to Microsoft last night after a bit of struggle; I'll update this answer as things progress.
LE: I also submitted a bug to openssl, since that must be the root cause of the issue (Azure is probably too fussy about the TLS exchange, but openssl shouldn't behave differently on different platforms).
LE2: I published my experimental workbench, in case anyone finds it useful.
LE3: It turns out the bug is also replicable on x86 for particular Linux distros, after all!
LE4: After an initial assessment, the Microsoft support guy told me to use a five-year-old blog post describing an IIS issue from circa 2007. Or disable mutual TLS altogether. I laughed.
LE5: Here's Microsoft's final position on the issue:
I consider this closed. We're basically supposed to work around it; that's it.