233脚本 WebSocket + TLS 模式 Caddy V2 反代 v2ray 反代伪装网站

233 脚本一直是使用 Caddy V1。我想用 Caddy V2 实现 反代 v2ray 反代伪装网站。

先说一句闲话,我比较喜欢 233 脚本的设计:

在 Caddy 这一层把 path 去掉了,v2ray 设置的是空 path 的 Websocket。
在 Caddy 这一层把 TLS 验证也做了,v2ray 设置与证书无关。

这样 v2ray 的配置变得更简单和稳定,不管你的域名换不换,path换不换,都和 v2ray 没关系。不用修改配置文件,也就少了出错的机会。

这样还有一个好处是,可以用多个域名或 path 来给多个用户提供互相隔离的节点。而这个实现在 Caddy 层,与 v2ray 无关。参见我的具体实践:多域名+多路径的v2ray多用户使用方案

233 脚本的Caddy V1 的 Caddyfile 是写成这样的:

你的域名
{
    tls 一个邮箱@gmail.com
    gzip
    timeouts none
    proxy / https://你反代伪装的网站/ {
        except /v2ray的path
    }
    proxy /v2ray的path 127.0.0.1:v2ray的端口 {
        without /v2ray的path
        websocket
    }
}

我们要改成 Caddy V2 格式的,一点一点来。

tls 部分,Caddy V2 支持一个 on_demand 模式,等到有请求的时候再去申请证书。

    tls 一个邮箱@gmail.com {
        on_demand
    }

gzip 变成了 encode gzip。

timeouts none 不支持,去掉。

proxy 命令,在 V2 变成了 reverse_proxy。不再用 except 去区分 path。without 也变成了uri strip_prefix。 这里是最让人搞不清楚的地方。在看了无数遍文档和搜索了无数的其它人的实践以后,直到我在 handle 的文档中看到了下面这个示例

handle /foo/* {
file_server
}
handle {
reverse_proxy 127.0.0.1:8080
}

终于明白了 V2 如何对不同的 path 分流。再参考了 handle-path 的文档以后改写成下面这个样子。

    handle_path /v2ray的path {
        reverse_proxy localhost:v2ray的端口
    }
    handle {
        reverse_proxy https://你反代伪装的网站 {
            header_up Host {upstream_hostport}
            header_up X-Forwarded-Host {host}
        }
    }

这样确实更合理,对比 V1 的配置文件,V2 的配置文件中,v2ray的path 这个数据只出现在一个分支中。

对了,websocket 在 V2 中是默认打开的了,所以不用写了。而 reverse_proxy 时,默认是 transparent 的。如果去了另一个域名,就需要修改 header_up。

至此,来看看我们的结果吧。

你的域名
{
    tls 一个邮箱@gmail.com {
        on_demand
    }
    encode gzip

    handle_path /v2ray的path {
        reverse_proxy localhost:v2ray的端口
    }
    handle {
        reverse_proxy https://你反代伪装的网站 {
            header_up Host {upstream_hostport}
            header_up X-Forwarded-Host {host}
        }
    }
}


===================
update

Caddy V2.5.0

你的域名     # 改这里
{
    tls Y3JhenlwZWFjZQ@gmail.com
    encode gzip

    handle_path /分流path {     # 改这里
        reverse_proxy localhost:你的v2ray内部端口     # 改这里
    }
    handle {
        reverse_proxy https://你反代伪装的网站 {     # 改这里
            trusted_proxies 0.0.0.0/0
            header_up Host {upstream_hostport}
        }
    }
}


===================
延伸,无限域名的方案

V2Ray梯子 前置Caddy V2使用Cloudflare泛域名15年证书 相当于有无限的域名

V2Ray梯子 前置Caddy V2使用on_demand模式 自动申请证书 相当于有无限的域名

评论

  1. 注意反代网站地址的末尾没有 / 符号
    参考:https://caddyserver.com/docs/caddyfile/directives/reverse_proxy

    回复删除
  2. 注意 handle_path 与 handle 的区别. handle_path 是一种快捷写法, 用于自动移除 path, 比如 a.com/abc 想要代理 b.com, 想要访问 b.com/b 的等效地址为 a.com/abc/b, 这时就会使用 handle_path.

    在做 v2ray 代理的时候, 一般不需要 handle_path, handle 即可.

    回复删除
    回复
    1. 你说的每个字都是正确的。

      但是我的思路(出发点)和你不一样,而且我写在了正文中。
      “先说一句闲话,我比较喜欢 233 脚本的设计:
      在 Caddy 这一层把 path 去掉了,v2ray 设置的是空 path 的 Websocket。
      在 Caddy 这一层把 TLS 验证也做了,v2ray 设置与证书无关。
      这样 v2ray 的配置变得更简单和稳定,不管你的域名换不换,path换不换,都和 v2ray 没关系。不用修改配置文件,也就少了出错的机会。”

      你愿意在修改path的时候,既修改caddy配置文件caddyfile也修改v2ray配置文件config.json,那是你的自由。

      删除
  3. 能否把您的v2ray服务端的配置也一并贴出来?便于理解

    回复删除
    回复
    1. 比如服务端ws的path是留空还是设置为/
      tls是开还是关

      删除
    2. 请见 https://zelikk.blogspot.com/2022/05/v2ray-websocket-tls-caddy-path-data-flow.html
      path设置为/,因为在我的Caddy配置文件写法中,把path去掉了。别人的方案中,有可能v2ray服务端的配置中,path不应设置为 /
      tls设置为关, 因为在Caddy这一层把tls解开了。

      删除
    3. 好吧,搞半天我发现我的协议用的是vmess。那请问你这种配置方式支持vmess吗?

      删除
    4. 当然支持vmess, 理论知识还是见此教程
      https://zelikk.blogspot.com/2022/05/v2ray-websocket-tls-caddy-path-data-flow.html
      你把v2ray服务端配置文件里的 protocol 改为 vmess 就行了。
      caddy这一层并不理解websocket里面装着什么。所以caddy只是解开tls,我的方案还会清理掉path,然后就转到v2ray服务端去了。
      所以v2ray服务端设置数据协议为vmess还是VLESS, 和caddy这一层的设置没有关系。

      删除
  4. 请教一个问题。不知道caddy是否能实现一个功能,我当前有两个服务器,一个在国内CN,一个在外国SG。CN服务器上面有一些服务我是使用cloudflare 的tunnel来访问的一个类似导航页面(页面上的所有链接也是CF tunnel的),这样能避免一些备案方面的问题。

    但是大陆这边访问使用cf 的tunnel的网站的话,是绕一圈美国再回来,我现在想用SG机器上用caddy(域名SG.COM)来反代CN机器上的网页(CN.COM),用你上面写的方法可以了。

    不过我想让CN.COM页面上的其他链接也能通过SG的caddy来一起反代
    例如:(CN.COM页面里面有下面几个链接)
    A.CN.COM
    B.CN.COM
    D.CN.COM
    Z.OTHER.NET
    需要怎么设置?
    感谢

    回复删除
    回复
    1. 你的意思是, cn.com上面的网页,内容是 a.cn.com; b.cn.com; ...
      你希望用sg.com反代以后,内容变成 a.sg.com; b.sg.com; ...
      是吗?

      删除
    2. 可能我前面表述不太清晰,请见谅。
      我当前的情况是这样:
      1、CN机器上面有自己学习建的一些服务,现在是通过cloud flare tunnel,来访问这些服务。

      2、我在这机器上弄了个导航页的网站CN.COM(用了CF tunnel),来放这些服务的链接。包括导航页本身也是走的CF tunnel。 但是我在本地ping这个cn.com,近300的延迟。 网上的资料说是免费CF用户的tunnel,从大陆访问是需要先绕美国。

      3、而我在SG的机器上ping这个cn.com,是10以内的延迟。我本机访问这个SG机器,是50左右的延迟。

      所以我想实现一个目标,就是通过在SG网站上的caddy,用SG.COM域名来反代CN.COM,包括CN.COM网页上的那些链接,都是想通过SG反向代理来访问,这样能达到降低延迟的目的。

      至于通过SG反代之后,那些链接是否会变成A.SG.COM,倒是没有想过。目标是要访问 SG.COM时,通过SG代理访问了 CN.COM(已按你的实现了),然后进一步目标时,我在访问SG.COM的时候看到的链接(CN.COM页面上的其他链接),点进去也能通过SG服务器来访问。

      不知道我这样表述能否清晰,caddy能否实现这样的功能。期待并感谢你的回复!

      删除
    3. 你好!欢迎交流!
      如你所说“我在访问SG.COM的时候看到的链接(CN.COM页面上的其他链接),点进去也能通过SG服务器来访问。” 在访问这个链接时,还是要通过域名解析等步骤,也就是说如果是访问一个 a.cn.com的链接,你会解析成哪个IP呢?肯定还是 cn.com的IP对吧?
      你再回想一下,你是因为访问了SG.COM速度才变快的对观吧?
      -
      不过我在想一个方案,你把页面上的链接写成 ./linka ./linkb ./linkc
      这样,在你访问的是SG.COM时,你访问 ./linka 就是访问 SG.COM/linka; 在你访问的是CN.COM时,你访问 ./linka 就是访问 CN.COM/linka

      删除
    4. 有一点不符合【如果是访问一个 a.cn.com的链接,你会解析成哪个IP呢?肯定还是 cn.com的IP对吧?】,

      CN.COM是走cf tunnel的访问,然后页面上的全部链接的域名(也是国内其他机器)都是走cf tunnel的访问的,比如说页面上的url:A.CN.COM这个链接,不一定是跟CN.COM在同一个服务器上的,也不一定解析到同一个ip,因为我也不清楚cftunnel里面怎么走的。我看CF里面的DNS记录:CN.COM , A.CN.COM这些域名是cname到cf内部的域名地址。

      所以我才想通过SG服务器上反向代理来访问这些域名,因为会比国内直接访问这些域名要快。比如我在国内电信ping这个CN.COM,延迟在260ms左右,我在SG的机器上ping,延迟在5ms以内,然后我国内电信ping这个SG的机器在50ms以内,所以感觉通过这样中转一下比较快。

      而且我是个新手,不太理解你这个方案是如何实现。我是使用Heimdall的docker来做的导航页。

      谢谢!

      删除
    5. 你现在的反代就是通过通过访问 SG.COM 来返回 CN.COM 的内容对吧?
      那不是同样的操作, 你用 一个 A.SG.COM 反代 A.CN.COM,然后你访问 A.SG.COM 就返回 A.CN.COM 的内容?
      所以问题还是在于:你访问 CN.COM 返回的内容里面链接是 A.CN.COM 而不是 A.SG.COM 啊。

      所以我的想法是使用 Relative URLs 参考 https://www.w3schools.com/html/html_links.asp
      中文环境下叫 相对路径 参考 https://www.w3school.com.cn/html/html_filepaths.asp

      删除
  5. 谢谢回复。

    em……我这个CN.COM(在VPS2)上面的所有URL,链接的都不是在VPS2里面的URL,都是VPS3/4/5的链接,而且这些链接都是通过cloudflare tunnel 获得的(目的是不需要备案,用户访问这个内地的VPS都能使用https)。

    我看你介绍的【相对路径】的文章,按我的理解,好像只能使用跟CN.COM在同一个VPS2上的url,才能用相对路径吧,我的理解对吗?

    也就是说,按我现在的情况,好像无法通过更改CN.COM上面那些URL为相对路径,来实现在SG.COM统一反代。

    我尝试使用chatgpt(3.5版本)来找解决方案,它提供了一个在caddy配置文件里,通过rewrite的方式来处理。但是它给出的所有配置示例,我放在SG.COM(vps1)上面都会造成caddy无法运行。我也提示了chatgpt,我的caddy版本是v2.6.2。因为个人水平有限,我暂时看不明白错误信息提示的是什么意思,只是把全部错误信息反馈给chatgpt了,它修改了几次我发现都是反反复复的,总是运行不起来caddy。

    回复删除

发表评论

The Hot3 in Last 30 Days

RackNerd VPS搭Hysteria2 HY2梯子 年付 $10.98 1G端口 3T流量 17G存储 1GB内存

强行重装 233boy的sing-box脚本 取消脚本报错退出的逻辑