Spring 启动 Web / Tomcat 拒绝连接特定网络 (Vodafone)

Spring Boot Web / Tomcat refusing connection for specific network (Vodafone)

我在 WebRTC 信令应用程序中使用 Spring Boot + Spring Web。它工作得很好,每个测试的人都可以在他们的浏览器中使用它。但我发现了一个案例,其中一个人无法通过 websockets 连接到我的服务。此人使用的是 TP-Link M7350,这是一个 Mini-Wifi 路由器,里面有一张 SIM 卡(Vodafone)。我研究、调试并在我的应用程序中尝试了几件事来捕获错误。但我发现,它与我的应用程序或 websockets 无关,这似乎是 TomCat / Spring 引导本身的问题。我能够使用这个简单的 spring 引导 Web 应用程序重现该问题:

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

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

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

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

我把路由器里的SIM卡换成了Telekom的SIM卡,然后重启。我能够访问该页面并看到“我还活着”。将 Vodafone 卡放入我的手机 phone,我无法打开页面并且超时。当我在使用 Vodafone 卡连接到路由器时打开计算机上的任何 VPN 时,我能够正确访问它。

所以由于某种原因,这张 Vodafone SIM 卡导致我无法使用上面的 Github Link 连接到这个迷你网络服务器。

为了更好地调试,我将 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 并用它打开这个 Whosebug 线程。基本上这个演示应用程序 + 我自己的是我发现的唯一不能正常使用它的页面。星期一,我将去一家零售店购买另一张 Vodafone SIM 卡,看看这是 Vodafone 的一般问题还是此 SIM 卡的任何特定问题 - 我不得不说我不是这方面的专家。因此,我在这里打开这个线程,希望有人知道我如何解决这个问题,因为当这种情况发生在一个 device/router 上时,它可能会发生在很多地方,我需要我的服务为所有客户提供服务。提前谢谢大家了,希望提供的这些信息能帮到你。

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

编辑 2 为了证明中间没有任何阻塞,我在同一台机器上用 https 设置了一个简单的 nginx 服务器,并在端口 443 上打开它。使用路由器 + Vodafone 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 时都有效。对于所有其他网络,没问题。

调试了很久终于找到解决办法了。显然出于某种原因,Vodafone 网络阻止了与 运行 我使用 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

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