Nginx SNI 分流使Xray的回落(fallback)功能与博客网站完美并存

linken 1,952 2022-07-13

Xray的功能想必不用过多介绍,但我们自行架设部署的服务器如果仅用于跑这一个软件那就太过浪费了。

很多人都有建立个人博客或其他网站的需求,但问题是Xray最完美的配置是VLESS+XTLS+fallback从而伪装为一个正常的站点,而达到这个效果自然需要占用443端口,这就导致了443端口只能选择分配给Xray或者Nginx之一。

前者官方的文档中已经有fallback功能的具体说明,确实可以做到以Xray为最前端进行分流,但毕竟它的本职工作不是web代理,fallback功能做到的分流又不是那么的简洁易懂,所以我认为最佳的选择仍然是使用Nginx控制443端口,进行分流与代理,做到两种功能的并存。

同时,在我尝试的过程中逐渐发现,虽然XTLS不能与CDN配合,但我们仍然可以通过多域名跳转的方式将做了CDN缓存的网站与Xray合并,即在保持网站全部功能的情况下起到伪装站的作用。

下面我将详细说明。

Xray配置

这部分很简单,与你选择使用什么协议无关,因为我们选择使用Nginx作为前端的分流,所以在这部分只需要简单配置fallback的回落地址即可。

回落可以选择任意端口甚至不同IP的任意端口,但目前我们同服务器多业务共存的情况下,最佳的回落端口是本机的80端口,这么配置的效果下面可以体现到,就不在这里做详细说明了。

"inbounds": [
  {
    "port": 30000,
    
...

    "settings": {
    
...

      "fallbacks": [
        {
          "dest": 80
        }
      ]
    },
    "streamSettings": {
      "network": "tcp",
      "security": "xtls",
      "xtlsSettings": {
        "allowInsecure": true,
        "minVersion": "1.2",
        "alpn": [
          "http/1.1"
        ],
        "certificates": [
          {
            "certificateFile": "/data/certs/fullchain.cer",
            "keyFile": "/data/certs/cert.key"
          }
        ]
      }
    }
  }
],

上述配置中,选择Xray的本地服务端口为【30000】,回落端口为【80】,https证书存放目录为【/data/certs】,省略部分随意配置,如有需要请根据实际情况进行更改。

Nginx配置

首先打开Nginx主配置文件【nginx.conf】,在http段的上方添加如下:

stream {
    map $ssl_preread_server_name $example_xray {
        xtls.example.com xtls; # Xray使用的域名
        www.example.com www; # 正常站点,同时为伪装站点
        test2.example.com blog; # 正常站点
    }
    upstream xtls {
        server 127.0.0.1:30000;
        # Xray服务端口
    }
    upstream www {
        server 127.0.0.1:30001;
        # 网站的ssl端口
    }
    upstream test2 {
        server 127.0.0.1:30002;
        # 网站的ssl端口(可以是第二个网站,也可以是网站的第二个域名,端口按情况填写即可)
    }
    server {
        listen 443      reuseport;
        listen [::]:443 reuseport;
        proxy_pass      $example_xray;
        ssl_preread     on;
    }
}

然后在conf.d目录下添加文件【www.conf】并包含以下内容(当然直接添加在主配置文件中亦可,只是便于后续维护的习惯罢了),配置文件内容为:

server {
        listen 80;
        server_name www.example.com;
        server_name xtls.example.com;
        if ($host != www.example.com) {
                return 301 https://www.example.com$request_uri;
        }
        return 404;
}

server {
        listen 30001 ssl;
        ssl_certificate       /data/certs/fullchain.cer;
        ssl_certificate_key   /data/certs/cert.key;
        ssl_protocols         TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        server_name           www.example.com;
        server_name           xtls.example.com;
        if ( $host != www.example.com) {
                return 301 https://www.example.com$request_uri;
        }

    location / {
        ...
        ...
    }

}

这两个配置调整完毕后,Nginx基本就已经算是配置好了。在配置文件中可以很清楚地看到,无论是http还是https我们都是将xtls.example.com域名的访问重定向到www.example.com,并且使http的全部访问默认跳转到https。

这里最重要的逻辑是http也就是80端口对应的配置中,将xtls跳转到www的https。

因为xtls这个域名对应的其实是Xray的业务端口,普通访问的流量则会被Xray筛选后回落到本地的80端口。又因为有域名则这部分流量最终会回落到xtls的http对应的配置文件所管控的部分。然后这次访问会被重定向到正常网站www的https端口,并且显示出www.example.com的正常页面。

这样最终的效果呈现给外界的就是:你现在的站点是一个双域名站点,做到了整站http强制跳转https,且保持对外显示的域名一致。

在这种情况下,如果再给www.example.com这个域名套上CDN,那么就达到了我们最初设想的效果。

参考资料

Nginx SNI 分流(端口复用)使用Xray+VLESS+XTLS

通过 SNI 回落功能实现伪装与按域名分流


# xray # nginx