Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[疑似Bug]当使用Nginx前置SNI分流且开启PROXY protocol时,Android浏览器中出现ERR_SSL_BAD_RECORD_MAC_ALERT报错 #1873

Open
xiaomage2000 opened this issue Mar 29, 2023 · 26 comments

Comments

@xiaomage2000
Copy link

如题,我在Android设备上浏览网页时,会间歇性的出现ERR_SSL_BAD_RECORD_MAC_ALERT错误。具体表现是,点击一个网页,很长时间没有反应,网页进度条不动。再次点击网页链接时,报"ERR_SSL_BAD_RECORD_MAC_ALERT"错误。电脑端基本没有遇到过。

服务端Core版本:1.7.5
Android V2RayNG版本:1.7.38(Core版本1.7.5)
协议:Vision
尝试过1.8.0版本,同样有这个问题,因为要兼容小火箭上的旧版Vision,故退回1.7.5

使用Nginx Stream模块进行SNI分流,与网站共享443端口,Nginx和Xray之间使用PROXY protocol传递访客IP。如果使用PROXY protocol则会出现上述问题,关闭(Nginx注释proxy_protocol on,Xray注释acceptProxyProtocol)则不会出现问题。

Nginx分流配置:

stream {
  map $ssl_preread_server_name $xray {
    vision.example.com vision;
    example.com web;
    default web;
  }

  upstream vision {
    server unix:/dev/shm/vision.sock;
  }
  upstream web {
    server unix:/dev/shm/web.sock;
  }

  server {
    listen 443 reuseport so_keepalive=on;
    proxy_pass $xray;
    ssl_preread on;
    proxy_protocol on;
  }
}

server { //回落伪装站
  listen 80;
  listen unix:/dev/shm/web.sock ssl http2 proxy_protocol;
  listen unix:/dev/shm/fake.sock proxy_protocol;
  listen unix:/dev/shm/fakeh2.sock http2 proxy_protocol;
......

客户端应该是正确配置的,使用的电脑上没有问题的配置导出的二维码。
服务端配置:

    {
      "protocol": "vless",
      "listen": "/dev/shm/vision.sock",
      "settings": {
        "clients": [
          {
            "id": "xxxxxxx",
            "flow": "xtls-rprx-vision"
          }
        ],
        "fallbacks": [
          {
            "dest": "/dev/shm/fake.sock",
            "xver": 1
          },{
            "dest": "/dev/shm/fakeh2.sock",
            "alpn": "h2",
            "xver": 1
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tcpSettings": {
          "acceptProxyProtocol": true
        },
        "tlsSettings": {
          "alpn": [
            "h2",
            "http/1.1"
          ],
          "certificates": [
            {
              "ocspStapling": 3600,
              "certificateFile": "/usr/local/nginx/conf/ssl/server.cert.pem",
              "keyFile": "/usr/local/nginx/conf/ssl/server.key.pem"
            }
          ]
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    },

服务端日志,约22:02:13报ERR_SSL_BAD_RECORD_MAC_ALERT错误:
err.log

V2RayNG 客户端日志:
client.log

困扰很长时间了,似乎比较早的版本就有,一直待1.8.0都有这个问题,不知道是Xray本身的问题,还是用到的库的问题,还是V2RayNG的问题了(麻了 实在无解,来发issue吧(

@chika0801
Copy link
Contributor

我没用过sni分流,有看别人用,没见和你类似现象的反馈。

建议先不用sni分流,直接搭(比如你要用1.7.5)看是否复现。

@xiaomage2000
Copy link
Author

我没用过sni分流,有看别人用,没见和你类似现象的反馈。

建议先不用sni分流,直接搭(比如你要用1.7.5)看是否复现。

直接搭不分流是没事的,SNI分流不用PROXY protocol获取访客IP也没事。偏偏加上acceptProxyProtocol的那一段,用上PROXY protocol就不行了。
另外用旧版Direct试了一下午,似乎也没事,问题可能出在Vision的PROXY protocol处理上了...?(大胆推断
如果需要什么样的更多测试,都可以进行的。

@picklefan

This comment was marked as outdated.

@xiaomage2000
Copy link
Author

xiaomage2000 commented Mar 30, 2023

看起来跟 sniffing 没有任何关系
是的,客户端和服务端的sniffing 都反复开关过,sniffing开启和问题出现没有关系。
因为旧版Direct流控不会出现这个问题,而旧版流控不支持fingerprint,因此还测试了Vision下留空fingerprint,还是不行,跟fingerprint也没有关系。

日志中有大量的failed to close connection > tls: failed to send closeNotify alert (but connection was closed anyway): write unix /dev/shm/vision.sock->@: write: broken pipe报错,即使不使用domain socket,还是会有报错,个人感觉问题在这里。

这个问题很随机,不容易复现,经过测试摸索出了一个相对容易复现的方法:

  1. 打开一个网站,等他加载完毕。
  2. 重启Xray服务端
  3. 点击网站上的一个网页。如果很快加载完成,则复现失败;否则如果加载了10秒还是没有反应,再点击一个网页,就很可能复现。

试了下sing-box上的vision,同样SNI分流,似乎还没有出现这个问题。

@picklefan

This comment was marked as outdated.

@picklefan
Copy link

我这边已经复现了, 就是 IPv6 的问题, 你可以试一下吧全局代理打开(也就是没有分流规则, 全部proxy), 看一下还会有这种情况吗

@xiaomage2000
Copy link
Author

我这边已经复现了, 就是 IPv6 的问题, 你可以试一下吧全局代理打开(也就是没有分流规则, 全部proxy), 看一下还会有这种情况吗

我电脑是有IPv6的,但是电脑上确实没事
刚刚关了本地的IPv6和服务器上的IPv6,正在尝试能不能复现。不能复现的话就是IPv6的锅了。
但个人感觉应该不是,因为我的问题主要是Nginx前置分流+Vision+PROXY protocol下面出现的,破坏任意一个就不能复现了,应该不是IPv6的问题。

@picklefan

This comment was marked as outdated.

@xiaomage2000
Copy link
Author

手机上可以建一个仅IPv4的APN,数据流量就只支持IPv4了。另外刚刚禁用v6还是能复现,说明跟v6没有关系(

@picklefan
Copy link

picklefan commented Mar 31, 2023

那看起来我们的问题确实不一样, 我跟你服务端结构一样的, 除了我的 VISION 是在 REALITY 里

不过让我想到了这个 issue #1690 不过好像没啥关系

@picklefan
Copy link

确实是PROXY protocol 的问题, 我这边又出现了, 关掉就正常了

@xiaomage2000 xiaomage2000 changed the title 当使用Nginx前置SNI分流且开启PROXY protocol时,Android浏览器中出现ERR_SSL_BAD_RECORD_MAC_ALERT报错 [疑似Bug]当使用Nginx前置SNI分流且开启PROXY protocol时,Android浏览器中出现ERR_SSL_BAD_RECORD_MAC_ALERT报错 Apr 2, 2023
@xiaomage2000
Copy link
Author

确实是PROXY protocol 的问题, 我这边又出现了, 关掉就正常了

我有了新的发现,也许不能说完全是PROXY protocol的问题,可能问题出在SNI分流上(

我之前只注意到了问题发生时候的日志,现在查看日志,有了新的发现。Nginx前置分流,在没有发生问题时,浏览完毕关闭浏览器时却出现了如下大量报错,直接占据了一个屏幕:

2023/04/02 22:51:33 [Info] [1350649912] app/proxyman/inbound: connection ends > proxy/vless/inbound: connection ends > proxy/vless/inbound: failed to transfer response payload > write unix /dev/shm/@vision.sock->@: write: broken pipe 2023/04/02 22:51:33 [Info] [1350649912] app/proxyman/inbound: failed to close connection > tls: failed to send closeNotify alert (but connection was closed anyway): write unix /dev/shm/@vision.sock->@: write: broken pipe

我又进行了三项测试:

  1. Xray直接监听443
  2. Nginx前置SNI分流 不开启PROXY protocol
  3. Nginx前置SNI分流 开启PROXY protocol

前一项测试没有任何问题。第二项出现了上述的大量错误日志,但是浏览正常。最后一项不但有大量错误日志,还出现偶发ERR_SSL_BAD_RECORD_MAC_ALERT报错。也就是报错只是表象,问题在SNI分流上,有Bug或者我的配置有误。您那边开启SNI分流会有这样的报错吗? @picklefan

@picklefan
Copy link

我 proxy_protocol 关了也出现了点击没反应的情况.
stream SNI 的话我是一直开的, 以前没用过VISION (我甚至没怎么用过XTLS), 没见过这种情况, 从 REALITY 开始才用的 VISION,
刚开始用 REALITY 也没发现这种情况, 出现问题的版本我都用了一个多月了, 直到前几天才注意到这个问题, 所以这个问题就很诡异, 用了一个月才出问题.
SNI 分流的话我就是 stream 直接转发, 难道还需要其他配置?

这个日志不知道在讲什么, 你那边看起来是 fallbacks ,但是我这边就没配置, 我看不懂这个日志, 我这边是这样的, 出现的概率是200万条里面有2000多条

2023/04/02 08:19:19 [Info] [3695363848] app/proxyman/inbound: connection ends > proxy/vless/inbound: connection ends > proxy/vless/inbound: failed to transfer response payload > io: read/write on closed pipe

@xiaomage2000
Copy link
Author

我 proxy_protocol 关了也出现了点击没反应的情况. stream SNI 的话我是一直开的, 以前没用过VISION (我甚至没怎么用过XTLS), 没见过这种情况, 从 REALITY 开始才用的 VISION, 刚开始用 REALITY 也没发现这种情况, 出现问题的版本我都用了一个多月了, 直到前几天才注意到这个问题, 所以这个问题就很诡异, 用了一个月才出问题. SNI 分流的话我就是 stream 直接转发, 难道还需要其他配置?

这个日志不知道在讲什么, 你那边看起来是 fallbacks ,但是我这边就没配置, 我看不懂这个日志, 我这边是这样的, 出现的概率是200万条里面有2000多条

2023/04/02 08:19:19 [Info] [3695363848] app/proxyman/inbound: connection ends > proxy/vless/inbound: connection ends > proxy/vless/inbound: failed to transfer response payload > io: read/write on closed pipe

并不是回落fallbacks。大量错误日志产生的时间点是:Nginx开启SNI分流,Xray在Nginx后面,不管开不开PROXY protocol都会出现这些错误日志:

2023/04/03 14:13:34 [Info] [37353324] app/proxyman/inbound: connection ends > proxy/vless/inbound: connection ends > proxy/vless/inbound: failed to transfer respon
se payload > write unix /dev/shm/@vision.sock->@: write: broken pipe
2023/04/03 14:13:34 [Info] [37353324] app/proxyman/inbound: failed to close connection > tls: failed to send closeNotify alert (but connection was closed anyway):
write unix /dev/shm/@vision.sock->@: write: broken pipe
2023/04/03 14:13:34 [Info] [2960971761] app/proxyman/inbound: connection ends > proxy/vless/inbound: connection ends > proxy/vless/inbound: failed to transfer resp
onse payload > write unix /dev/shm/@vision.sock->@: write: broken pipe
2023/04/03 14:13:34 [Info] [2960971761] app/proxyman/inbound: failed to close connection > tls: failed to send closeNotify alert (but connection was closed anyway)
: write unix /dev/shm/@vision.sock->@: write: broken pipe

这些日志表明,关闭浏览器,Nginx和Xray之间的连接被Nginx打断,日志里面就会报broken pipe的错。也就是说,开启PROXY protocol间歇性报ERR_SSL_BAD_RECORD_MAC_ALERT的错是表象,问题出在Nginx和Xray的交互上,只是开了PROXY protocol让这个问题显现出来了。可能Vision对连接的处理不如Direct,就会报错。

原因应该是这样的,因为我应对这样的原因找到了解决方案,Nginx Stream模块里面加一行proxy_half_close on;就一切正常了,测试了一段时间,没有再出现过了。

但看您那边错误信息和我不太一样,可能不是同一个问题,但是您可以试试 @picklefan

@picklefan
Copy link

我们两个问题应该是一样的, 只是你直接用的 vision, 我用的 vision 是在 REALITY 里面.
ERR_SSL_BAD_RECORD_MAC_ALERT 这个报错我倒是从来没见过, 浏览器没有, Nginx 和 xray 日志里也没有.
感谢测试并找到了解决方案, 我会尝试你的解决方案

@moll33er
Copy link

可以用nginx先代理去除proxy_protocol(如果一定需要使用proxy_protocol直达xray请忽略),配置如下

stream {
    # 第一跳 
    upstream xray_proxy_protocol {
        server 127.0.0.1:7070;
    }
    # 接受proxy_protocol
    server {
        listen 7070 proxy_protocol;
        proxy_pass  xray_proxy;
    }
    # 第二跳
    upstream xray_proxy { 
        # 代理端口
        server 127.0.0.1:30001;
    }
}

@AAkira45
Copy link

AAkira45 commented Jun 3, 2024

2024.6.3 更新:
也遇到了相同的问题,网站随机出现err_ssl_bad_record_mac_alert,哪怕在PC端Chrome也是相同现象。
nginx端口使用proxy_half_close on;配置依旧无法解决问题,在使用此跳转去除proxy_protocol后问题消失,同时xray内也无需开启acceptProxyProtocol.

在此更新一下我个人的解决方案,希望对后来者有所帮助。
PS:另外不知道这个是不是bug,不过总之这样可以解决,缺点是xray因为没有代理协议从而无法得到客户端ip,不过这个对有nginx前置的情况下并不是很重要。

@donnyxray
Copy link

@AAkira45 this happens for me too.

It does not matter whether I use NGINX or HAPROXY. As soon as the proxy protocol is enabled, random requests will fail with ERR_SSL_BAD_RECORD_MAC_ALERT.

I suspect the bug is in xray-core, not both nginx and haproxy. But due to it's rare and random character it's very difficult to debug.

@AAkira45
Copy link

@AAkira45 this happens for me too.

It does not matter whether I use NGINX or HAPROXY. As soon as the proxy protocol is enabled, random requests will fail with ERR_SSL_BAD_RECORD_MAC_ALERT.

I suspect the bug is in xray-core, not both nginx and haproxy. But due to it's rare and random character it's very difficult to debug.

这样看起来首先这基本确定应该是一个bug,其次照时间计算这个bug已经存在一年时间尚未在现有版本中得到解决,如有可能需要有人reopen这个issue或者进行修复,只可惜本人对go实在不熟,只能寄希望于开发者们能对这个问题再review一下,在此谢谢各位开发者辛勤付出!

@AAkira45
Copy link

@AAkira45 this happens for me too.
It does not matter whether I use NGINX or HAPROXY. As soon as the proxy protocol is enabled, random requests will fail with ERR_SSL_BAD_RECORD_MAC_ALERT.
I suspect the bug is in xray-core, not both nginx and haproxy. But due to it's rare and random character it's very difficult to debug.

这样看起来首先这基本确定应该是一个bug,其次照时间计算这个bug已经存在一年时间尚未在现有版本中得到解决,如有可能需要有人reopen这个issue或者进行修复,只可惜本人对go实在不熟,只能寄希望于开发者们能对这个问题再review一下,在此谢谢各位开发者辛勤付出!

我这边使用的配置为nginx前置ssl sni分流,xray为reality vision,具体配置见:
#3548
当不使用此转换配置时便会出现问题
stream {
# 第一跳
upstream xray_proxy_protocol {
server 127.0.0.1:7070;
}
# 接受proxy_protocol
server {
listen 7070 proxy_protocol;
proxy_pass xray_proxy;
}
# 第二跳
upstream xray_proxy {
# 代理端口
server 127.0.0.1:30001;
}
}

@xiaomage2000
Copy link
Author

2024.6.3 更新: 也遇到了相同的问题,网站随机出现err_ssl_bad_record_mac_alert,哪怕在PC端Chrome也是相同现象。 nginx端口使用proxy_half_close on;配置依旧无法解决问题,在使用此跳转去除proxy_protocol后问题消失,同时xray内也无需开启acceptProxyProtocol.

在此更新一下我个人的解决方案,希望对后来者有所帮助。 PS:另外不知道这个是不是bug,不过总之这样可以解决,缺点是xray因为没有代理协议从而无法得到客户端ip,不过这个对有nginx前置的情况下并不是很重要。

你的解决方案是可以的,但是Xray无法获取到使用者的IP,虽然不影响使用。
后来我又测试,proxy_half_close on确实不行。
再之后没办法,我就暂时放弃Nginx前置SNI分流了,改成Xray前置。这个Bug到现在还没有修复。
开发者们应该是在忙着开发新协议,Nginx前置这种玩法好像不被重视(
同样希望开发者能再review一下这个问题,我这边也可以再尝试复现一下,提交一些更详细的日志

@xiaomage2000 xiaomage2000 reopened this Jul 21, 2024
@simplerick-simplefun
Copy link

simplerick-simplefun commented Jul 26, 2024

2024.6.3 更新: 也遇到了相同的问题,网站随机出现err_ssl_bad_record_mac_alert,哪怕在PC端Chrome也是相同现象。 nginx端口使用proxy_half_close on;配置依旧无法解决问题,在使用此跳转去除proxy_protocol后问题消失,同时xray内也无需开启acceptProxyProtocol.
在此更新一下我个人的解决方案,希望对后来者有所帮助。 PS:另外不知道这个是不是bug,不过总之这样可以解决,缺点是xray因为没有代理协议从而无法得到客户端ip,不过这个对有nginx前置的情况下并不是很重要。

你的解决方案是可以的,但是Xray无法获取到使用者的IP,虽然不影响使用。 后来我又测试,proxy_half_close on确实不行。 再之后没办法,我就暂时放弃Nginx前置SNI分流了,改成Xray前置。这个Bug到现在还没有修复。 开发者们应该是在忙着开发新协议,Nginx前置这种玩法好像不被重视( 同样希望开发者能再review一下这个问题,我这边也可以再尝试复现一下,提交一些更详细的日志

可以使用 https://github.com/path-network/go-mmproxy 作为中间件帮助不支持proxy protocol的程序获得分流前的原来源IP。配置略微复杂一些,但是教程很清晰,不难。

@berserkBoyi
Copy link

你们测试时是否在网络环境比较好的时候进行?
你们开启sni后,应该会跑一些网页,这些网页的数据库需要占用内存,是否有检查主机内存留有足够内存?
我也整了一个sni,分别为xray和网页设置了证书。一开始因为不会设置,没有开启nginx到xray这段过程的proxy_protocol,最近学会了设置,但发现链接中断的概率提高了。主要表现就是:

safari:“Safari can't open the page because it couldn't establish a secure connection to the server.”

firefox focus:“An SSL error has occurred and a secure connection to the server cannot be made.”

不同浏览器表达不同,但是就是与ssl相关。
这种错误在网络丢包率较高时出现,但我开启了nginx 到 xray 这段proxy_protocol后出现的频率更高了。
我一开始以为是bug,后面试着做一些排除,其中一处是内存不够。因为我的网页时wordpress搭的,mysql占用几百M,使得系统内存只有十几M,后面我的做法是,停用网页相关的数据库部分,让系统有200m内存空余;感觉有所改善。
但我不确定是不是因为内存太小导致网络丢包的概率提升。
希望我回复对你们有帮助。

@AAkira45
Copy link

AAkira45 commented Aug 5, 2024

你们测试时是否在网络环境比较好的时候进行? 你们开启sni后,应该会跑一些网页,这些网页的数据库需要占用内存,是否有检查主机内存留有足够内存? 我也整了一个sni,分别为xray和网页设置了证书。一开始因为不会设置,没有开启nginx到xray这段过程的proxy_protocol,最近学会了设置,但发现链接中断的概率提高了。主要表现就是:

safari:“Safari can't open the page because it couldn't establish a secure connection to the server.”

firefox focus:“An SSL error has occurred and a secure connection to the server cannot be made.”

不同浏览器表达不同,但是就是与ssl相关。 这种错误在网络丢包率较高时出现,但我开启了nginx 到 xray 这段proxy_protocol后出现的频率更高了。 我一开始以为是bug,后面试着做一些排除,其中一处是内存不够。因为我的网页时wordpress搭的,mysql占用几百M,使得系统内存只有十几M,后面我的做法是,停用网页相关的数据库部分,让系统有200m内存空余;感觉有所改善。 但我不确定是不是因为内存太小导致网络丢包的概率提升。 希望我回复对你们有帮助。

过程中并没有观察到内存占用过高,实际上在启动完成以后还有1.5GB的RAM可以使用,且去掉protocol以后问题完全消失,重新加上部分网页问题偶发,并不是每一次打开网页都会触发这个问题。但是频率也不罕见。目前尚不清楚触发必须的条件是什么,且并不会每次都出现,debug需要耗费相当的时间和精力去寻找问题。

@lxhao61
Copy link

lxhao61 commented Aug 5, 2024

特意报告一下:使用 Caddy 前置 SNI 分流且开 PROXY protocol 一样会产生类似问题。

@Yochee
Copy link

Yochee commented Aug 26, 2024

我也遇到同样问题,而且是纯ipv4下桌面chrome报的错。服务端是nginx+sni分流到后端xray

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants