java - 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 失败时有效。对于所有其他网络,没问题。
解决方案
经过长时间的调试,我终于找到了解决方案。显然出于某种原因,沃达丰网络阻止了与运行我的 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
我希望这会帮助其他面临类似问题的人。
推荐阅读
- java - 对象引用在不使用时被删除?
- android - 连接 PubNub 服务的频道时出现 PNTimeoutCategory 错误
- python - Python Pandas - 查找和分组异常值
- javascript - 为创建和编辑页面使用相同表单组件的良好做法
- flutter - 文本从大到小的颤动动画
- windows - Windows 上的 Flutter:如何调用外部 dll?
- c# - 是否可以创建连接到另一个 websocket 的 websocket 服务器?
- jodatime - 为什么 kotlinx-datetime 存在?或者:为什么数据时间库如此依赖于平台?
- azure - Azure DevOps API - 如何引用其他管道作为资源参数
- typescript - 如何避免 VSCode 自动补全中的省略号?