Xray-core icon indicating copy to clipboard operation
Xray-core copied to clipboard

fallback回落的问题

Open ifpig opened this issue 3 years ago • 17 comments

我本身用apache2搭建了正常个网站,本身80端口(http)和443端口(https)都可以访问,并且80端口http可以自动跳转https的443端口。

现在搭建了xray,假设暂时监听在444端口(因为如果监听在443,会导致正常访问网站时URL需要加个端口号很难看),然后向444端口发送https请求的时候,fallbcak的dest,无论怎么配置,都会出问题。我理解主要是两个原因,1采用302跳转,2直接用http去做各种跳转而不是https造成问题

如果dest:80,会显示Invaild 302,dest: 域名:80也一样

如果dest:443,因为302的时候用的是http,会导致: Bad Request Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please. Apache/2.4.41 (Ubuntu) Server at 127.0.0.1 Port 443

如果写:dest: "https://domain:443" 会导致respons超时

那究竟应该怎么fallback呢?是不是xray代码能把跳转443的协议改为https就可以了?

ifpig avatar Nov 19 '21 08:11 ifpig

  1. make real HTTP service on a localhost port, such as 127.0.0.1:6666, you don't need apache to serve https, leave your original port 80 redirect unchanged;
  2. xray inbound use port 443 and use your websites' certs, let it fallback to 6666 port; { "dest": 6666, "xver": 1 },

fgggid avatar Nov 19 '21 10:11 fgggid

  1. make real HTTP service on a localhost port, such as 127.0.0.1:6666, you don't need apache to serve https, leave your original port 80 redirect unchanged;
  2. xray inbound use port 443 and use your websites' certs, let it fallback to 6666 port; { "dest": 6666, "xver": 1 },

或许apache不能有"xver": 1

以前有这个就会不行,现在不知道啦

shenlijun avatar Nov 19 '21 11:11 shenlijun

{
    "log": {
        "loglevel": "warning"
    },
    "inbounds": [
        {
            "port": 443,
            "protocol": "vless",
            "settings": {
                "clients": [
                    {
                        "id": "自定义UUID 1",
                        "flow": "xtls-rprx-direct",
                        "level": 0
                    }
                ],
                "decryption": "none",
                "fallbacks": [
                    {
                        "dest": 自定义端口,
                        "xver": 1
                    }
                ]
            },
            "streamSettings": {
                "network": "tcp",
                "security": "xtls",
                "xtlsSettings": {
                    "allowInsecure": false,
                    "alpn": [
                        "http/1.1"
                    ],
                    "certificates": [
                        {
                            "certificateFile": "/etc/apache2/ssl/xxx.com-fullchain.pem",
                            "keyFile": "/etc/apache2/ssl/xxx.com-key.pem"
                        }
                    ]
                }
            }
        },
        {
            "protocol": "vmess",
            "port": 自定义端口,
            "settings": {
                "clients": [
                    {
                        "id": "自定义UUID 2"
                    }
                ],
                "decryption": "none",
                "fallbacks": [
                    {
                        "dest": 80
                    }
                ]
            },
            "streamSettings": {
                "network": "kcp",
                "kcpSettings": {
                    "header": {
                        "type": "自定义"
                    },
                    "seed": "自定义"
                }
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom"
        }
    ]
}

我和你情况一样,Apache本身有网站部署,有HTTPS,也有80自动重定向到443。直接参考这个配置就行了。没有你提到的必须加443端口才能访问网站的情况。 这个是优先vless(占443端口),然后回落到vmess(随便一个端口),最后回落到80端口。每层协议自己定义就行了,这里只是个参考。

ysy950803 avatar Nov 19 '21 11:11 ysy950803

也可以试试这个 { "inbounds": [ { "tag": "tunnel", "port": 443, "protocol": "vless", "settings": { "clients": [ { "email": "", "id": "", "level": 1 } ], "decryption": "none", "fallbacks": [ { "dest": "8800" }, { "alpn": "h2", "dest": "8802" } ] }, "streamSettings": { "network": "tcp", "security": "tls", "tlsSettings": { "alpn": [ "h2", "http/1.1" ], "certificates": [ { "ocspStapling": 3600, "certificateFile": "", "keyFile": "" } ], "minVersion": "1.2" } } } ], "outbounds": [ { "protocol": "freedom", "settings": {} }, { "protocol": "blackhole", "settings": {}, "tag": "blocked" } ], "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ { "type": "field", "outboundTag": "blocked", "protocol": [ "bittorrent" ] }, { "type": "field", "outboundTag": "blocked", "domain": [ "geosite:cn" ] }, { "type": "field", "outboundTag": "blocked", "ip": [ "geoip:cn" ] } ] } }

shenlijun avatar Nov 19 '21 12:11 shenlijun

  1. make real HTTP service on a localhost port, such as 127.0.0.1:6666, you don't need apache to serve https, leave your original port 80 redirect unchanged;
  2. xray inbound use port 443 and use your websites' certs, let it fallback to 6666 port; { "dest": 6666, "xver": 1 },

或许apache不能有"xver": 1

以前有这个就会不行,现在不知道啦

Yes, my suggestion above is not very clear. "xver" is optional. I'm using nginx, and add "proxy_protocol" to listen, so I use "xver".

fgggid avatar Nov 20 '21 13:11 fgggid

同样的问题,翻看了几天各种issuses,discussion,google博文数十篇,我真怀疑他们的nginx自己用过没,我已经非常熟练清楚知道nginx不能同端口同时处理https/1.1和http2,所以实际上有两种方法回落,一种用两个端口分别接替,一种用unix进程两个分别接替。 而后者可以使用proxy_protocol模块让nginx接收到访问者源ip,这些暂时都不重要,重要的是网站访问这边的问题: 以前nginx前置监听443分流的时候,基本上用的path路径分流vmess到后端v2ray进行处理,各种方便,只不过耗电一些,以及怀疑路由器cpu性能不够只能跑20mbps左右,于是将vless前置,监听443,使用vless +tcp +xls,而nginx我原来的配置(可能大部分人的配置)都是让一个80端口server监听www.your.domain和your.domain 301到https://www.your.domain 或者https://your.domain. 然后443端口做两个server,如果要全部跳转到无www的,就将此作为default_server,另一个带www的也301跳转过来,当然你最终要全部跳转到带www的https则反之。 vless监听443后,我将nginx处理https两个服务监听的443去掉,换成了各种大佬的samples,比如https://github.com/lxhao61/integrated-examples/tree/main/v2ray(vless%5Ctrojan%2Btcp%2Btls)%2Bnginx 或者: https://github.com/XTLS/Xray-examples/tree/main/VLESS-TCP-TLS-WS%20(recommended) 针对port fallback 到81 和82为例,这边nginx https这块接收 server { listen 127.0.0.1:81; #http/1.1 server,监听本地81端口。 listen 127.0.0.1:82 http2; #h2c server,监听本地82端口。 server_name xx.yy; #更改为自己的域名 这种方法连xray都broken pipe 查xray日志都没有访问日志,nginx站点那边连80的www和不带www的都连接错误 而采用unix方案,fallback "fallbacks": [ { "alpn": "h2", "dest": "/dev/shm/h2c.sock", "xver": 0 }, { "dest": "/dev/shm/h1.sock", "xver": 0 } ] 这边nginx https server块这边监听 listen unix:/dev/shm/h1.sock; #http/1.1 server进程 listen unix:/dev/shm/h2c.sock http2; #h2c server进程

server_name default_server http2 ssl; #更改为自己的域名 如果这里设置成default_server的话,80那边301跳转到不带www的https的话,http://your.domain 可以跳转到https://your.domain,但是http://www.your.domain则不跳转,直接连接报错,哪怕nginx配置的明明白白两个都要跳转,另一个80的http://your.domain就是无法访问。 server { listen 80; server_name www.your.domain your.domain; return 301 https://your.domain$request_uri; } 而最大的问题就是,即使80端口访问跳转过来的https,却是不安全页面,基本上所有连接地址都是http://而不是https://的,所以提示不安全,同时直接https访问的443端口网站,网站内部连接基本上也全是http连接了,所以我完全不明白,vless fallback回来的http/1.1和http2怎么也变成了无ssl数据了么? 而且不论监听port 82,81还是unix h1.sock h2c.sock, 对于https站点处理的https:// www 和不带www的301跳转就不兼容了,否则会提示重定向次数过多,这个我明白是我水平差,应该有解决方案。 目前就是两个80 www/不带www 跳转到一个残废的https协议的http不安全站点 访问443则是要么https://的不安全站点或者https://www 的不安全站点自选一个,做301的话另一个就是重定向次数过多。 看大佬们的教程,nginx正常站点访问配置我愣是没看到一个 落地的、真正的在用的人的配置,全是解释官方那些范例的,我真怀疑他们自己测试过真站点https使用环境么?不会都随便丢一个index.html或者完全没有考虑301跳转,完全没有保留www还是无www这种需求? 大佬们都是贴xray的配置,求一个nginx侧的实际配置真难。都能忍受实际站点https下全是http,css无法部署,站点提示不安全么?就我一个强迫症?

plumn avatar Jan 03 '22 07:01 plumn

Just give some advices from my nginx config:

  1. for 301 redirect, add HSTS, so browser can directly use https.
  2. use $host, you don't need to hard-coded. Of course, I don't quite get your points about redirection. For me, it is the simplest.
server
{
    listen 80;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    return 301 https://$host$request_uri;
}
  1. for http/1 and http/2, I do meet some weird problems, however I forget what it exactly is now. My current configuration is using separate listens.
    listen       unix:/run/nginx_h2.socket http2 proxy_protocol default_server;
    listen       127.0.0.1:5001 proxy_protocol default_server;

It seems I cannot use both TCP or both UDS, not sure why. It runs fine for months currently, I don't have time to investigate or check current situation.

For xray/v2ray fallback:

        "fallbacks": [
          {
            "name": "blahblahblah",  # vless + wss fallbacks; name is just a name, not a match condition.
            "path": "/vpn_path",
            "dest": 5000,          # my vless + ws inbound
            "xver": 1
          },
          {
            "alpn": "h2",  # http/2 fallback
            "dest": "/run/nginx_h2.socket",
            "xver": 1
          },
          {
            "dest": 5001,   # http/1 fallback; see nginx snip above
            "xver": 1
          }
        ]

I do see some weird nginx 400 access logs from 127.0.0.1 some times, but I don't have time to investigate yet.

/var/log/nginx/access.log:127.0.0.1 - - [04/Jan/2022:16:46:29 -0800] "" 400 0 "-" "-" <IP from Netherlands>:39518 "-"
/var/log/nginx/access.log:127.0.0.1 - - [04/Jan/2022:16:46:28 -0800] "" 400 0 "-" "-" <IP from Netherlands>:39314 "-"
/var/log/nginx/access.log:127.0.0.1 - - [04/Jan/2022:16:46:27 -0800] "" 400 0 "-" "-" <IP from Netherlands>:38974 "-"
/var/log/nginx/access.log:127.0.0.1 - - [04/Jan/2022:16:46:27 -0800] "" 400 0 "-" "-" <IP from Netherlands>:38762 "-"

fgggid avatar Jan 05 '22 01:01 fgggid

Thank you , my solution to force https is add fastcgi_param HTTPS "on"; in location ~.php , and what I want redirect is both http://mydomain.com & http://www.mydomain.com to https://mydomain.com , your choice return 301 https://$host$request_uri; only lead http://www.mydomain.com to https://www.mydomain.com redirect and rewrite in normal nginx config can't process correctly with xray fallback data.

plumn avatar Jan 05 '22 03:01 plumn

Redirection only need on 80 port, which is served by nginx, I don't think it will be affected by xray. Maybe you also want to redirect https://www.example.com to https://example.com ? I have a redirection like this too, but redirect my old domain to new domain. It receives fallback data from xtls, works fine too, nginx syntax only(of coz, my site only have static web contents).

fgggid avatar Jan 05 '22 13:01 fgggid

The fact is affected , I'm also sure your can redirect https://domainA.com to https://domainB.com , but data from xtls can't redirect correctly from http://www.mydomain.com to https://mydomain.com , neither with https://www.mydomain.com to https://mydomain.com , I have other website work pretty fine with single lnmp circumstance , all redirect methods show below work fine , but not good with xtls , test is very simple , you can test your config anytime you like . Here are common ways to redirect : sample A:

	listen unix:/dev/shm/h1.sock;
	listen unix:/dev/shm/h2c.sock http2;
        server_name www.yourdomain.com;
	if ( $host != 'yourdomain.com' ) {
		rewrite ^(.*)$ https://yourdomain.com$1 permanent;
	}

sample B:

{
listen 80;
server_name www.your.domain your.domain;
return 301 https://your.domain$request_uri;#can't work with http://www.your.domain to https://your.domain
}

sample C:

server
{
listen 80;
server_name www.mydomain.com mydomain.com;
if ($http_host !~ '^mydomain\.com$') {  # $host != 'mydomain.com' rewrite ^(.*)$ https://mydomain.com$1 permanent;
rewrite ^(.*) https://mydomain.com$1 redirect;
}

sample D:

server {
	listen unix:/dev/shm/h1.sock;
	listen unix:/dev/shm/h2c.sock http2;
	server_name www.yourdomain.com;
	rewrite ^(.*)$ https://yourdomain.com$1 permanent;
	}

sample E:

if ($server_port = 80){
return 301 https://$server_name$request_uri;} #visit http://www and can't reach https://www.mydomain.com page
if ($scheme = http){
return 301 https://$server_name$request_uri;}# visit http://www and can't reach https://www.mydomain.com page

sample F: if ($server_port = 80){ return 301 https://$mydomain.com$request_uri;} #can't work with http://www.mydomain.com to https://mydomain.com if ($scheme = http){ return 301 https://$mydomain.com$request_uri;} can't work with http://www.mydomain.com to https://mydomain.com

plumn avatar Jan 06 '22 08:01 plumn

我有两台机器,分别用sock和端口,好像都没有问题,不过我用的是tls return 301后面用$http_host试试?

    server {
            listen 80 default_server;
            listen [::]:80 default_server;
            server_name mydomain.com *.mydomain.com;
            return 301 https://$http_host$request_uri;
    }

    server {
            listen 127.0.0.1:8800;
            listen 127.0.0.1:8802 http2;
            server_name mydomain.com *.mydomain.com;
            root /usr/local/softWeb;
    }

shenlijun avatar Jan 07 '22 04:01 shenlijun

回落到端口的不要加"xver": 1,要不然刷新的时候回关闭链接,我这边是这样的,不知道其他人是否一样

sock的可以

shenlijun avatar Jan 07 '22 05:01 shenlijun

我有两台机器,分别用sock和端口,好像都没有问题,不过我用的是tls return 301后面用$http_host试试?

    server {
            listen 80 default_server;
            listen [::]:80 default_server;
            server_name mydomain.com *.mydomain.com;
            return 301 https://$http_host$request_uri;
    }

    server {
            listen 127.0.0.1:8800;
            listen 127.0.0.1:8802 http2;
            server_name mydomain.com *.mydomain.com;
            root /usr/local/softWeb;
    }

xtls +tcp的不能支持https://www 的访问,以及从https://www 访问自动跳转到https://无www ,另外因为是tcp数据,xtls接手后就是未加密流量,在nginx里对php解析区块必须加fastcgi_param HTTPS "on"; 造成域名无法跳转到本地的关键我估计是所有跳转都执行再次访问https默认443端口,又走一遍vless的分流处理,导致证书或者数据本身哪里不兼容。你的301只是让对应的80访问跳转对应https的服务,这个用我提到的fastcgi_param HTTPS "on";就可以解决。 有空再折腾,或者躺着等大佬们完善教程了,其实也不是不能用,不管这些细节了。

plumn avatar Jan 07 '22 07:01 plumn

我有两台机器,分别用sock和端口,好像都没有问题,不过我用的是tls return 301后面用$http_host试试?

    server {
            listen 80 default_server;
            listen [::]:80 default_server;
            server_name mydomain.com *.mydomain.com;
            return 301 https://$http_host$request_uri;
    }

    server {
            listen 127.0.0.1:8800;
            listen 127.0.0.1:8802 http2;
            server_name mydomain.com *.mydomain.com;
            root /usr/local/softWeb;
    }

xtls +tcp的不能支持https://www 的访问,以及从https://www 访问自动跳转到https://无www ,另外因为是tcp数据,xtls接手后就是未加密流量,在nginx里对php解析区块必须加fastcgi_param HTTPS "on"; 造成域名无法跳转到本地的关键我估计是所有跳转都执行再次访问https默认443端口,又走一遍vless的分流处理,导致证书或者数据本身哪里不兼容。你的301只是让对应的80访问跳转对应https的服务,这个用我提到的fastcgi_param HTTPS "on";就可以解决。 有空再折腾,或者躺着等大佬们完善教程了,其实也不是不能用,不管这些细节了。

如果对xtls的性能提升没那么敏感的话还是简单点用tls吧……

我是vps和客户端都足够强,所以无所谓,而且感觉xtls还有一些问题要解决

shenlijun avatar Jan 07 '22 09:01 shenlijun

回落到端口的不要加"xver": 1,要不然刷新的时候回关闭链接,我这边是这样的,不知道其他人是否一样

sock的可以

vless+tls没问题,fallbak到ws就一直报错折腾了好久,删了指向ws的xver就好了,感谢~ 不知道和client配置有无关系,懒得继续看了...

Yukisaki avatar Feb 12 '22 15:02 Yukisaki

@plumn @fgggid 大佬们好,能否加个好友? 我碰到了类似问题,折腾多天了,没头绪,急死。

v2ray 回落到80 port, nginx反代, 我碰到了几乎碰到的所有问题,不是安全链接, 重定向次数过多,只能访问首页, 只能http访问,只能ip访问, 图像不显示,css样式不对,未发送任何数据等等,不一而足。

目前只成功反代了 wordpress 网站, 以及nginx本身的默认初始网站,只要有数据库的php网站,基本出各种问题。我真诚拜师学艺,谢谢!!!

csquya avatar Apr 30 '22 07:04 csquya

@plumn @fgggid 大佬们好,能否加个好友? 我碰到了类似问题,折腾多天了,没头绪,急死。

v2ray 回落到80 port, nginx反代, 我碰到了几乎碰到的所有问题,不是安全链接, 重定向次数过多,只能访问首页, 只能http访问,只能ip访问, 图像不显示,css样式不对,未发送任何数据等等,不一而足。

目前只成功反代了 wordpress 网站, 以及nginx本身的默认初始网站,只要有数据库的php网站,基本出各种问题。我真诚拜师学艺,谢谢!!!

哈哈,你这些问题我也基本都遇到过,不过我用的xray不是v2ray。遇到最多的就是刚弄完之后好好的,过一段时间莫名奇妙就网站样式全乱码了,wp后台无限重定向。我现在就是xray前置,全权接管https部分,内部wp网站改一下配置,去掉https全走http,我觉得这应该是正确的理解,最后一次改完之后一直没出什么问题8251/。

CussiusKon avatar Aug 31 '22 09:08 CussiusKon

给后来各位提供一下参考,就我个人而言,也是参考官方的whatever模板设置的。80端口是通过vless->torjan->apache这样的流向回落,fallback->80的xver是0,网页访问的时候被closed,后面看apache的access是通过h2访问,因此中间可能存在问题。

经测试,使用a2enmod http2开启apache的h2支持,然后配置相应80的virtualhost开启h2c端口支持(Protocols h2c http/1.1),然后浏览器就可以正常访问回落到apache提供的服务了~

z0ow avatar Aug 16 '23 02:08 z0ow