首页 > 解决方案 > Spring Boot Web / Tomcat 拒绝特定网络的连接(沃达丰)

问题描述

Spring Boot + Spring Web在 WebRTC Signalling 的应用程序中使用。它运行良好,每个测试者都可以在他们的浏览器中使用它。但是我发现了一种情况,其中一个人无法通过 websockets 连接到我的服务。此人使用的是 TP-Link M7350,这是一个内置 SIM 卡(沃达丰)的 Mini-Wifi 路由器。我研究和调试并在我的应用程序中尝试了几件事来捕获错误。但我发现,这与我的应用程序或 websockets 无关,这似乎是 TomCat / Spring Boot 本身的问题。我能够使用这个简单的 Spring Boot Web 应用程序重现该问题:

https://github.com/mxk1011/springboot-mini-demo

这是一个非常简单的 Web 应用程序,在单个控制器中访问 /test 时会输出“我还活着”。

我在与我的任何应用程序无关的新服务器上克隆了这个应用程序,使用 ufw 打开端口 443 并以mvn -U clean spring-boot:run. 从我测试的所有不同网络中,当我在服务器上访问 /test 时,我能够看到“我还活着”,我使用了来自手机的不同 WiFi 和热点。但是当我用 Vodafone SIM 切换到这个 TP-Link 路由器的 WiFI 时,我得到:

ERR_CONNECTION_TIMED_OUT在我的 Chrome 和所有其他浏览器中。

我将路由器中的 SIM 卡切换到 Telekom SIM 卡并重新启动。我能够访问该页面并看到“我还活着”。将沃达丰卡放入我的手机,我无法打开页面并且也超时。当我在使用沃达丰卡连接到路由器的同时打开计算机上的任何 VPN 时,我能够正确访问它。

因此,由于某种原因,这张 Vodafone SIM 卡导致我无法使用上面的 Github Link 连接到这个 Mini Webserver。

为了更好地调试,我将 LOG LEVEL 更改为 TRACE。当您能够连接到该页面时,会发生以下情况:

https://github.com/mxk1011/springboot-mini-demo/blob/master/works.log

当我将 Vodafone SIM 卡连接到服务器时会发生这种情况:

https://github.com/mxk1011/springboot-mini-demo/blob/master/fails.log

在我的生产应用程序中,我使用了 Let's Encrypt 的证书,对于这个示例,我在商店中使用自签名密钥(参见 github,它是我用于测试的密钥)。在演示服务器上使用 Let's Encrypt 证书不会改变任何我也尝试过的东西。

我不知道为什么这会失败。我得到这个路由器+ SIM卡的人每天都在用它来工作,完全没有问题。我还能够将文件推送到 GitHub 并用它打开这个 StackOverflow 线程。基本上这个演示应用程序 + 我自己的是我发现的唯一不能正常工作的页面。周一我将去零售店购买另一张 Vodafone SIM 卡,看看这是否是 Vodafone 的一般问题或此 SIM 卡的任何特定问题 - 我必须在这一点上说我不是这方面的专家。因此,我在这里打开这个帖子,希望有人知道如何解决这个问题,因为当这种情况发生在一个设备/路由器上时,它可能会发生在很多设备上,我需要为所有客户提供服务。提前感谢大家,

编辑我知道很可能,设备之间的某些东西,从 Vodafone 一直到应用程序都阻止了请求,没有什么可以责怪 Spring web/boot。但正如您在日志中看到的那样,路由器有一个来自我的 IP 地址的传入请求。如果您可能对我的问题没有解决方案,也许您知道什么可以帮助找到更多关于它的信息,也许通过使用服务器/客户端上的任何工具/脚本?我愿意接受任何想法。谢谢!

编辑 2为了证明中间没有任何阻塞,我在同一台机器上用 https 设置了一个简单的 nginx 服务器,并在端口 443 处打开它。使用路由器 + 沃达丰 SIM 卡,我能够通过 https 连接到它。所以对我来说,失败点似乎是 Spring / Java 部分。

编辑 3我现在尝试通过 curl -vvv 访问服务器,以使用此命令获取更多信息。我用它访问了服务器,但得到了这个响应:

*   Trying 1.2.3.x...
* TCP_NODELAY set
* Connected to xxx.com (1.2.3.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* 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 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: self signed certificate
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

很公平,我需要一个证书。我添加了一个脚本来获取 Let's encrypt 证书并将其转换为 pkcs12 到上面的 git。生成它后,我将它复制到类路径并重新开始。我再次 curl -vvv myhost.com 并且能够毫无问题地访问:

*   Trying x.x.x.x...
* TCP_NODELAY set
* Connected to myhost.com (x.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* 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, 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 change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=myhost.com
*  start date: Jun 21 10:08:36 2020 GMT
*  expire date: Sep 19 10:08:36 2020 GMT
*  subjectAltName: host "myhost.com" matched cert's "myhost.com"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
> GET /test HTTP/1.1
> Host: myhost.com
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 200 
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 11
< Date: Sun, 21 Jun 2020 11:11:27 GMT
< 
* Connection #0 to host myhost.com left intact
I am alive!* Closing connection 0

这在使用此 SIM 卡在任何浏览器中打开相同的 URL 失败时有效。对于所有其他网络,没问题。

标签: javaspring-bootspring-mvchttpsrouter

解决方案


经过长时间的调试,我终于找到了解决方案。显然出于某种原因,沃达丰网络阻止了与运行我的 SSL 应用程序的服务器的连接。通过向应用程序属性添加以下内容,它最终让请求通过:

server.ssl.ciphers=ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384
server.http2.enabled=true

我希望这会帮助其他面临类似问题的人。


推荐阅读