免责声明:本文及所提供资源仅用于技术探讨或学习,严禁用于非法用途!

本文适用于熟悉Linux基本操作,熟悉Nginx建站、熟悉docker操作或爱折腾的老哥!

关联文章:
【富强系列-一键脚本】nginx + websocket + tls一键脚本
【富强系列-面板】nginx + websocket + tls + cname 控制面板

原理与架构

原理为nginx + websocket + tls,在此基础之上新增加CNAME域名用于平衡/切换服务器流量(负载均衡),玩法更加灵活。一图胜千言:

                            ...(A域名集群)
                            ---->> A域名3
                            ---->> A域名2               -->> 其他path -->> 404/403(自定义)
                            |                           |
                            |                           |
你的流量 -->> CNAME域名 -->>                            -->> 正常path -->> 网站(伪站)
                            |                           |
                            |                           |
                            ---->> A域名1 -->> Nginx -->> 
                                                        |
                                                        |   代理path1  (rewrite)
                                                        -->>代理path2 --------->> 代理根path -->> 代理工具 --->> 和谐站点
                                                            代理path3  (rewrite)
                                                            ....

既然玩这么复杂,那必定有它的好处:

  • 有一天服务器1挂了/没流量了/老板跑路等等,此时将CNAME域名指向服务器2(A域名2)即可无疼切换!客户端并不需要改任何配置!(此处有个注意事项:要实现此操作必须CNAME域名在服务器1和服务器2上同时有该CNAME域名的tls证书文件!)
  • 有一天有个哥们儿想和你一起用,但是你并不想把代理根path暴露给他,此时你只需要添加一条代理path重写到代理根path即可,该哥们儿可以愉快的用该代理path而不是dialing根path上网,如果哪天你和他闹矛盾,删除该代理path即可,不影响代理根path,简而言之,实现多用户的管理

nginx + websocket + tls实现思路

该架构适用于单服务器/单用户
这部分可简化为下图(考虑最简单情况,一个主机一个域名):

                                   -->> 其他path -->> 404/403(自定义)
                                   |
                                   |
你的流量 -->> A域名 -->> Nginx -->> -->> 正常path -->> 网站(伪站)
                                   |
                                   |   代理path1  (rewrite)
                                   -->>代理path2 --------->> 代理根path -->> 代理工具 --->> 和谐站点
                                       代理path3  (rewrite)
                                       ....

iptables关闭服务器所有端口(ssh端口除外),Nginx绑定在80和443端口以模拟真实站点,下面重点来了:
假设条件:

  • 域名为domain.com,且已经获得HTTPS证书
  • 代理根路径为(切记设置成复杂字符串,uuid那种也可以):dailiPath
    Nginx配置文件如下:(这只是样例,说明原理,切勿简单套用)
server {       
    server_name  domain.com;
    
    # 正常path,伪站设定
    location / {
        root   /usr/share/nginx/html;  # 伪站放置位置
        index  index.html index.htm;
    }
    
    # 代理根path设定
    location /dailiPath {
        proxy_redirect off;
        # proxy_pass http://代理工具IP:代理工具端口;
        proxy_pass http://127.0.0.1:51234;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;  # 此段必须要,让https请求升级为websocket
        proxy_set_header Connection "upgrade";   # 此段必须要,让https请求升级为websocket
        proxy_set_header Host $http_host;
    }

    # 监听443
    listen 443 ssl; 
    ssl_certificate /你的证书路径/fullchain.pem;
    ssl_certificate_key /你的证书路径/privkey.pem;
    ssl_dhparam /你的证书路径/ssl-dhparams.pem;

}

# 80 端口跳转443
server {
    if ($host = domain.com) {
        return 301 https://$host$request_uri;
    }
    listen       80;       
    server_name  domain.com;
    return 404; # 其他访问跳转404/403  随你定义
}

细心的你已经看出来了,上面只是配置了代理根路径的反向代理设置而已,那谁来接收这些流量呢?当然是代理工具,此处用酸酸+v兔锐插件实现,酸酸配置文件如下

{
    "server":["::1", "127.0.0.1"],      # 酸酸IP,即为上面Nginx配置中的代理工具IP
    "mode":"tcp_and_udp",
    "server_port":51234,                # 酸酸监听端口,即为上面Nginx配置中的代理工具端口
    "local_port":1080,
    "password":"pwd",                   # 密码
    "timeout":60,
    "method":"chacha20-ietf-poly1305",  # 加密方式
    "plugin":"v2ray-plugin",            # 加载v2ray插件
    "plugin_opts":"server;path=/dailiPath;loglevel=none"    # v2ray插件配置,注意path要和上面的代理根path一致
}

此处就已经实现了ws + tls流量传递给代理工具的服务端设置

添加代理path,避免暴露代理根path

如果新加代理path呢?注意代理根path是不需要暴露出去的,添加代理path实现思路是将要添加的代理path重写到代理根path,Nginx配置如下:

server {       

    ...
    
    
    # 代理path添加
    location /your-new-proxy-path$ {
        rewrite /your-new-proxy-path$ /dailiPath;
    }
    ...
}

重加载下配置文件nginx -s reload,此时访问your-new-proxy-path和访问dailiPath效果相同,你甚至可以这样玩:

server {       

    ...
    
    # 包含该文件夹下面所有.path结尾的文件
    include /etc/nginx/proxy_conf/*.path;
    ...
}

这样添加路径

cat > /etc/nginx/proxy_conf/your-new-proxy-path.path <<EOF
rewrite /your-new-proxy-path$ /dailiPath;
EOF

添加完成后重新加载配置文件nginx -s reload就可以,这样的好处是可以用脚本很方便的添加路径!

CNAME负载均衡实现思路

此部分主要实现原理中的CNAME域名用于平衡/切换服务器流量(负载均衡)的部分。

此部分实现相对简单,主要是在域名控制台进行操作,假设你的域名为domain.com,你可以这样规划:

                                                  ---->> A域名:1.domain.com(服务器1)
                                                  |
                                                  |
你的流量 ----->> CNAME域名:service.domain.com -->>--->> A域名:2.domain.com(服务器2)
                                                  |
                                                  |
                                                  ---->> A域名:3.domain.com(服务器3)

需要注意的是CNAME域名在每个服务器上都要有HTTPS证书,这样才能实现切换,否则网络连不通,也就是说service.domain.com这个域名需要在服务器1、服务器2、服务器3上都有HTTPS证书且Nginx已经配置好,服务器1配置1.domain.com的HTTPS证书就可以,以此类推,服务器2有2.domain.com的证书,服务器3有3.domain.com的证书。

这样比如说1.domain.com这台机器没有流量了,service.domain.com切换到2.domain.com,那么service.domain.com就可以继续使用,客户端无需配置任何东西,只需要在域名控制台更改CNAME指向就可以。

当然在实际使用中一般一个CNAME域名对应一个A域名,所有CNAME域名全部提供出去,这样更加灵活配置,相当于将客户端配置与服务器解耦。

如果是用cloudflare之类可以进行代理的CDN,甚至可以用他们提供的代理隐藏IP,这样相当于你的流量-->>CNAME域名-->>cloudflare-->>A域名(服务器)-->>代理工具-->>和谐站点,这样多了一层,虽然更加安全,但是速度相对较慢,救急也许可以考虑一下,更多玩法请按参考具体环境。

实现

上面说的都是原理架构以及配置样例,能说这么多那肯定是已经实现这套流程了,否则就是光说不练假把式唬人而已,所涉及操作这边全部封装成了docker镜像/一键脚本(其中还包括添加用户,删除用户,流量统计,限速等功能,甚至还包含了一个控制面板,这些后面专门开文章说),从0到1简化步骤如下:

  1. 需要至少一台服务器(这不废话么),KVM(支持docker)虚拟化的VPS(有独立公网ip,有80/443端口),假设系统为CentOS7,其他系统不保证能成功!
  2. 需要至少一个域名(这不废话么)
  3. 域名控制台添加A记录指向服务器ip,假设为a.domain.com
  4. ssh到服务器执行:(根据提示输入即可,提示中的请输入v兔瑞路径即为代理根路径,不输入则随机生成!这个记着后面有用
bash <(curl https://raw.githubusercontent.com/scriptwang/SSoverTLS/master/sh/SSoverTLS_Adv.sh) -i

上面四个步骤已经实现了nginx + websocket + tls,打开对应平台客户端导入即可:

  • 安卓:小飞机v兔瑞插件
  • PC:小飞机v兔瑞插件(将v兔瑞-plugin.exe下载改名为v兔瑞.exe放到酸酸文件夹里,谐音请自动转换)
  • IOS:版本在2.1.37及以上的小火箭(收费版本此处不予分享)
  • MAC:小飞机加v兔瑞插件(有人编译了插件,有需要自行谷歌吧)

下面是实现CNAME负载均衡

  1. 在域名控制台添加A记录将service.domain.com指向服务器
  2. ssh到服务器执行:(1:域名填写service.domain.com 2:路径填写代理根路径,写错了不生效!
bash <(curl https://raw.githubusercontent.com/scriptwang/SSoverTLS/master/sh/AddDomain.sh)
  1. 到域名控制台删除A记录service.domain.com,添加CNAME记录service.domain.com指向a.domain.com

此时,你就可以通过service.domain.com来上网了,如果你还有b.domain.com,到域名控制台将service.domain.com切换到b.domain.com即可无痛切换服务器。