WWW.YOUINFO.SITE
标签聚合 Caddy

/tag/Caddy

LinuxDo 最新话题 · 2026-05-21 11:37:26+08:00 · tech

前言 本文只做技术分享,禁止转载 本文分为两个章节进行讲解,这两个没有直接关系也没啥间接关系,但重复内容我就没有再复制粘贴了,需要的地方也有跳转提示,佬友根据自己情况进行查看 一、搭建自用节点(简单) 二、搭建机场(较复杂) 由于VPS选择+Cloudflare+域名配置跟我之前的文章有交叉,为了对小白友好,所以我就直接复制粘贴了,有了解的佬友可以自行选择需要的章节进行学习,右边有目录 本教程需要的技术(版本仅作为参考): 一、搭建自用节点(简单): VPS(云服务器)(地区选择:硅谷,必须海外) :2c2g(2个CPU核数2G的内存,1c1g即可) v2ray-agent (八合一脚本) :v3.5.18(latest) 二、搭建机场(较复杂) VPS(云服务器)(地区选择:硅谷,必须海外) :2c2g(2个CPU核数2G的内存,必须2g内存) Xboard (机场开源面板) :master 分支最新开发版(2026-05-03 构建)(没有具体版本号)(latest)(既然做机场了,就不用SQLite,直接上mysql+redis,所以这里至少需要2g内存) V2bX :v0.4.0(latest) Caddy :v2.11.3(latest) mysql :5.7 redis :8.6.3(latest) docker :26.1.4 docker-compose :2.27.1 本教程需要的工具: FinalShell :SSH远程连接工具 v2rayN :代理工具 clash-verge-rev :代理工具 零、VPS选择+域名配置(cf代理) 我买了腾讯云的服务器用来做教学,全程可用国内网访问 有vps的佬可以跳过这一步了 VPS选择 1、活动页 腾讯云最新活动 这个为新人优惠,2c2g一年99米 这是两个图片拼接起来的,颜色不同的大框表示不同的图片,这两个图片的截取在同一个页面,下滑即可 2、购买完毕后进入控制台 这也是两张图片拼接起来的,颜色不同的大框表示不同的图片,上面黄框是腾讯云的主页的头部标签,下面红框是点击控制台后进入控制台的页面 3、查看服务器ip 也是由黄框和红框分别不同的图片 由于腾讯云默认安全组打开了22端口(SSH服务),这里就不进安全组了,后文有讲到如何配置安全组,这里不过多赘述 4、使用FinalShell连接到服务器 填写名称、主机ip、用户名和密码即可连接到我们的服务器 FinalShell的好处就是修改文件或者上传下载文件时是可视化的,不用一遍一遍敲命令行 域名配置(cf代理) 这里我使用的是 cloudflare 做的代理,所以我按cloudflare讲解,其他的云服务商配置也是大同小异 我买的顶级域名为(严格来说这是二级域名,我习惯说这是顶级域名):wudike.online 下文有两个地方需要使用到域名 ,一个是我们搭建机场(xboard服务)还有一个是配置自用节点(可不使用域名,且不使用域名更高效、安全) 1、使用 Cloudflare 的 DNS 代理我们的域名 这里的域名是我之前买的,在阿里云上的,所以我用阿里云作为演示,各个云服务商的操作都是大同小异的 (1、进入域名与网站 (2、选择域名进行购买 查询之后下滑点击购买就可以了 域名这里买了之后要实名去备份,审核要几个工作日吧,有点忘记了 (3、登录Cloudflare,并交给Cloudflare托管 ps:Cloudflare右上角人物头像那可以切换语言 ①、添加域名 下面那个我已经注册了,上面已经有服务了,注销在注册太麻烦 ②、跟着我的步骤点点就行了 上面四个步骤结束后我们得到了下面这个页面,需要去我们的云服务商重新配置一下DNS解析 ③、我们去阿里云配置一下域名的解析 进入我们的工作台,点击域名就可以看到我们购买的域名了 进去之后我们就可以修改DNS代理了 注: 国际域名最少填写2个,最多填写13个,国内域名最多填写6个。 所以我们两个都要复制哦,把之前的替换掉 ④、回到Cloudflare 下拉后,点击我已更新名称服务器 我们等十分钟后刷新一下 如果出现这样就代表成功了,由于我已经配置了一个域名,不想再去买一个配置了,下面这张图用的小黄大佬的图 一、搭建自用节点(简单) 1、安装v2ray-agent脚本 wget -P /root -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" && chmod 700 /root/install.sh && /root/install.sh 运行完上面代码我们就得到了下面的脚本执行命令 2、根据面板选择 2.1、Xray-core + VLESS + Reality + uTLS + Vision(简单、抗探测能力强、抗封锁能力强、传输速度快、资源占用率低、无域名、不可cdn代理,推荐) 不要以为无域名无代理就不安全了,恰恰相反这是最快最安全的(之一),唯一的缺点是无法套CDN,自用够够的了 从上至下执行命令 vasma # 执行脚本 2 # 任意组合安装 1 # Xray-core 7 # VLESS+Reality+uTLS+Vision[推荐] # 后面回车即可,注意端口这里要开防火墙和安全组,所以手动填好一点 执行后就得到了下面三个字符串,最重要的是通用格式,复制通用格式的字符串 复制进我们的 v2rayN 代理工具中测试一下可使用了, 文章后面我会讲如何导入clash 回车后选择自动配置系统代理即可使用 2.2、Xray-core + VLESS + TLS + WS(复杂、抗探测能力弱、抗封锁能力弱、传输速度一般、资源占用率低、有域名、可cdn代理,不推荐) 在v2ray-agent脚本中配置域名会有 nginx 占用443端口 ,所以有服务使用了443端口,强烈不建议用这个 首先在cloudflare中配置域名时代理状态先关掉(变成灰色的云),脚本检测域名是否指向了本机 关掉代理 创建API令牌 这里是因为脚本需要通过我们的 api token 去获取SSL证书,所以我们需要先申请API token 搜索 API 令牌,点击创建令牌 使用编辑区域DNS模板,选择域名后一路确认到最后一步复制 API ,注意这里关闭后就无法找到了,记得保存 执行脚本 从上至下执行命令,我现在配置的域名为cdn.wudike.online vasma # 执行脚本 2 # 任意组合安装 1 # Xray-core 1 # VLESS+TLS+WS[仅CDN推荐] 域名:cdn.wudike.online # 你自己的域名 端口:2053 # 因为cf的https有固定的几个端口不可乱填,可以填的端口:443、2053、2083、2087、2096、8443 是否使用DNS API申请证书[支持NAT]?[y/n]:y # 后面要用到我们上面 api token 请选择[回车]使用默认:1 # cloudflare[默认] 请输入API Token:**** # 星号就是我们复制的 api token 请选择[回车]使用默认:1 # letsencrypt[默认] # 后面的操作无脑回车即可,也可以自己填,无所谓的 我们就得到了 vless 链接,注意要用ws的,使用方式如 2.1 所示 配置 cf 代理并测试 我们再去 cf 开启域名的代理,等10分钟后我们去测试 测试一下是否符合我们的预期,符合预期 PS:配置Clash 这里相当于就是把vless链接转为clash的yaml文件,为了佬友方便,我 vibe coding 了一个项目 源码放在这里了: clash-converter 也可以使用我部署的网站: Proxy ↔ Clash 双向转换器 二、搭建机场(较复杂) 1、创建文件 这里我们要创建单个文件,第一个是xboard的配置文件 .env 、一个是 docker-compose.yml 启动文件、一个是 Caddyfile (caddy的配置文件,之前的文章讲了nginx,这里就换个代理工具讲解) mkdir -p /opt/xboard && touch /opt/xboard/{.env,Caddyfile,docker-compose.yml} .env 包含 的参数是需要修改的,包含 的是可修改的,其他的可以照抄 APP_NAME=XBoard APP_ENV=production APP_KEY=base64:iH2lk8cdnIj0sLgeNzEzAa2GEhPCROrxsa5etAk35sI= APP_DEBUG=false APP_URL=http://localhost LOG_CHANNEL=stack DB_CONNECTION=mysql # ❓选择mysql服务,看样子也可以使用postgresql,这个就交给各位实践了 DB_HOST=mysql # ⚠️mysql的服务名(docker-compose文件中的服务名) DB_PORT=3306 # 用默认的就行了 DB_DATABASE=xboard # ❓数据库名 DB_USERNAME=root # 数据库用户名,用root就行了,其实该mysql也不对外,新不新增用户都行 DB_PASSWORD=123456 # ⚠️密码,就算不对外,这个还是设计的越安全越好的 REDIS_HOST=redis # ⚠️redis的服务名(docker-compose文件中的服务名) REDIS_PASSWORD= # redis不要设置密码,也可以设置,主要是麻烦 REDIS_PORT=6379 # 用默认的就行了 BROADCAST_DRIVER=log CACHE_DRIVER=redis QUEUE_CONNECTION=redis MAIL_DRIVER= MAIL_HOST= MAIL_PORT= MAIL_USERNAME= MAIL_PASSWORD= MAIL_ENCRYPTION= MAIL_FROM_ADDRESS= MAIL_FROM_NAME= MAILGUN_DOMAIN= MAILGUN_SECRET= # google cloud storage ENABLE_AUTO_BACKUP_AND_UPDATE=false GOOGLE_CLOUD_KEY_FILE=config/googleCloudStorageKey.json GOOGLE_CLOUD_STORAGE_BUCKET= # Prevent reinstallation # 这里是初始化需要的参数,没有值的时候就说明是初始化,可以使用初始化脚本,初始化脚本执行完成后会修改这个值,所以不需要手动再次修改该文件 INSTALLED= docker-compose.yml 包含 的参数是需要修改的,包含 的是可修改的,其他的可以照抄 services: # ---------- Xboard 主应用 ---------- xboard: # 服务名 image: ghcr.io/cedar2025/xboard:latest # 镜像名 restart: unless-stopped # 重启策略 container_name: xboard # 容器名 # 移除 ports 映射,因为现在通过 Caddy 代理 # ports: # - "9888:7001" expose: - "7001" # ⚠️只在内部网络暴露 希望保留给宿主机的话用上面的ports depends_on: # mysql和redis检测到健康后再启动 mysql: condition: service_healthy redis: condition: service_healthy volumes: # 卷挂载 - ./.env:/www/.env # 挂载 .env 文件 - ./.docker/.data/:/www/.docker/.data - ./storage/logs:/www/storage/logs - ./storage/theme:/www/storage/theme - ./plugins:/www/plugins environment: # 环境参数 - RESOURCE_PROFILE=balanced # minimal | balanced | performance | auto - ENABLE_HORIZON=true - docker=true networks: # docker网络 - xboard-net # ---------- MySQL 数据库 ---------- mysql: image: mysql:5.7 restart: unless-stopped container_name: xboard-mysql environment: MYSQL_ROOT_PASSWORD: 123456 # ⚠️密码改后记得后面操作还需要输入 MYSQL_DATABASE: xboard # ❓建议不改 volumes: - mysql-data:/var/lib/mysql networks: - xboard-net healthcheck: # 心跳检测机制 test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p123456"] timeout: 20s retries: 10 # ---------- Redis 缓存 ---------- redis: image: redis:latest restart: unless-stopped container_name: xboard-redis command: redis-server --appendonly yes # 启用 AOF volumes: - redis-data:/data networks: - xboard-net healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 # ---------- Caddy 反向代理 ---------- caddy: image: caddy:latest restart: unless-stopped container_name: xboard-caddy ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro # ❓就是下面的Caddyfile文件建议不改 - caddy-data:/data # 存储证书 networks: - xboard-net depends_on: - xboard networks: xboard-net: driver: bridge # 桥接模式 volumes: mysql-data: # MySQL 数据持久化 redis-data: # Redis 数据持久化(原有) caddy-data: # 存储证书 Caddyfile 这里域名需要再cf中进行配置,具体参考本文目录中, 一、搭建自用节点(简单) 中的 2.2、Xray-core + VLESS + TLS + WS(复杂、抗探测能力弱、抗封锁能力弱、传输速度一般、资源占用率低、有域名、可cdn代理,不推荐) ,看一下就会配置域名了 包含 的参数是需要修改的,包含 的是可修改的,其他的可以照抄 # 替换成你的实际域名 vpn.wudike.online { # ⚠️改成自己的域名 # 反向代理到 Xboard 容器 reverse_proxy xboard:7001 # ⚠️这里也是自己的服务名和端口 } 2、初始化 先让mysql和redis服务跑起来再初始化 docker compose up -d mysql redis # 等个10s后执行下面脚本 docker compose run -it --rm -e ENABLE_REDIS= xboard php artisan xboard:install 下面是执行后的结果,供参考 包含 的参数是需要修改的,包含 的是可修改的, xxx 是脱敏需要你们自己填,其他的可以照抄 [root@VM-0-16-centos xboard]# docker compose up -d mysql redis [+] Running 6/6 ✔ Network xboard_xboard-net Created 0.1s ✔ Volume "xboard_redis-data" Created 0.0s ✔ Volume "xboard_caddy-data" Created 0.0s ✔ Volume "xboard_mysql-data" Created 0.0s ✔ Container xboard-redis Started 0.5s ✔ Container xboard-mysql Started 0.5s [root@VM-0-16-centos xboard]# docker compose run -it --rm -e ENABLE_REDIS= xboard php artisan xboard:install [+] Creating 2/0 ✔ Container xboard-mysql Running 0.0s ✔ Container xboard-redis Running 0.0s [entrypoint] Auto-tune (profile=balanced): cpus=2 mem=1024MiB slots=9 -> octane=2 horizon(dp/biz/notif)=2/1/1 horizon_worker_mem=256MB [entrypoint] Horizon supervisors use balance=auto with minProcesses=1, so they scale up to the cap on demand and back down when idle. [entrypoint] Skipping xboard:update (not yet installed or running xboard:install). [entrypoint] Starting services (caddy=true web=true horizon=true ws=true)... __ __ ____ _ \ \ / /| __ ) ___ __ _ _ __ __| | \ \/ / | __ \ / _ \ / _` | '__/ _` | / /\ \ | |_) | (_) | (_| | | | (_| | /_/ \_\|____/ \___/ \__,_|_| \__,_| ┌ 请选择数据库类型 ────────────────────────────────────────────┐ │ MySQL │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入MySQL数据库地址 ───────────────────────────────────────┐ │ mysql # ⚠️这里是docker中mysql的服务名 │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入MySQL数据库端口 ───────────────────────────────────────┐ │ 3306 │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入MySQL数据库名 ─────────────────────────────────────────┐ │ xboard │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入MySQL数据库用户名 ─────────────────────────────────────┐ │ root │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入MySQL数据库密码 ───────────────────────────────────────┐ │ 123456 │ └──────────────────────────────────────────────────────────────┘ ┌ 是否启用Docker内置的Redis ───────────────────────────────────┐ │ 不启用 │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入Redis地址 ─────────────────────────────────────────────┐ │ redis │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入Redis端口 ─────────────────────────────────────────────┐ │ 6379 │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入redis密码(默认: null) ─────────────────────────────────┐ │ # ❓redis本来就没有设置密码,这里回车就行了 │ └──────────────────────────────────────────────────────────────┘ ┌ 请输入管理员账号 ────────────────────────────────────────────┐ │ xxxxxxxxxxxxxx # ⚠️管理员登录的账号 │ └──────────────────────────────────────────────────────────────┘ INFO Configuration cached successfully. 正在导入数据库请稍等... 🚀 开始执行流量重置任务... 🔧 修正模式 - 将重新计算next_reset_at为null的用户 ✅ 没有发现next_reset_at为null的用户 ✅ 任务完成! 📊 修正结果统计: 🔍 发现用户总数: 0 ✅ 成功修正数量: 0 ⏱️ 总执行时间: 0 秒 ✨ 无错误发生 数据库导入完成 开始注册管理员账号 正在安装默认插件... 默认插件安装完成 🎉:一切就绪 管理员邮箱:xxxxxxxxxxxxxx # ⚠️之前输入的账号,这里改不了,加感叹号号是提示这里比较重要 管理员密码:xxx # ⚠️初始密码,后面可以改 访问 http(s)://你的站点/xxx 进入管理面板,你可以在用户中心修改你的密码。 # ⚠️/xxx 要带这个path才能访问管理员的面板 3、启动Xboard cd /opt/xboard && docker compose up -d 访问我们的域名就可以看见项目已经启动部署成功了 4、配置我们的xboard(后台管理系统,跟path有关系,仔细看第二步的最后) 通过我们的域名+path登录到后台管理系统( https://域名/path ) 这里不会什么功能都讲,主要是把主流程给跑通 (1、修改名字 (2、添加节点(很重要) 在节点管理中添加节点 我们选择vless去配置就可以了,这里我把主要的以文字形式写出来,也可以直接看我的图片讲讲 协议:vless 节点名称:随意 自定义节点ID:很重要后面创建节点会用到 权限组:这个跟后面的套餐有关系,套餐又跟用户有关系,所以很重要,没有就添加一个 节点地址:ip地址 连接端口、服务端口:记得开服务端口的防火墙和安全组 安全性:Reality 伪装节点:找个大网站就行了 私钥、公钥:生成一下就行了 Short ID:生成一下就行了 uTLS:开启 传输协议:TCP 流控:xtls-rprx-vision 可以照着我的写 添加完之后记得打开显示开关 (3、套餐管理(其实还有一部权限组管理,但我们在节点里面也添加了一个权限,所以可以直接略过了) 有四个参数要填写,其他随意 名称:随意,不要和权限组管理名称重复,不好管理 服务器分组:就是我们之前填的权限组管理 流量、价格:记得设置,不然后续购买有问题 打开显示、新购、续费开关 (4、新增用户(为了后面方便测试) (5、创建ApiKey(很重要) 在系统配置的节点配置中生成一个通讯秘钥 5、使用V2bX创建脚本 (1、环境准备 # 修复 V2bX 必需文件(必须执行) mkdir -p /etc/V2bX && echo "{}" > /etc/V2bX/sing_origin.json (2、安装 V2bX wget -N https://raw.githubusercontent.com/wyx2685/V2bX-script/master/install.sh && bash install.sh # 执行到这里的时候选择n 检测到你为第一次安装V2bX,是否自动直接生成配置文件?(y/n): n (3、修改 /etc/V2bX/config.json 文件 这里面有几个参数可以修改 ApiHost:你自己的域名 ApiKey:之前在系统管理里面生成的通讯秘钥 NodeID:之前在节点中自定义的节点ID NodeType:我们之前创建节点的时候选择的Vless协议 { "Log": { "Level": "info" }, "Cores": [ { "Type": "sing", "Log": { "Level": "info" }, "OriginalPath": "/etc/V2bX/sing_origin.json" } ], "Nodes": [ { "Core": "sing", "ApiHost": "https://这里改成你的域名", "ApiKey": "这里是之前在系统管理里面生成的通讯秘钥", "NodeID": 1001, "NodeType": "Vless", "Timeout": 30, "ListenIP": "0.0.0.0", "SendIP": "0.0.0.0", "SniffEnabled": true } ] } (4、启动服务 # 重启服务 systemctl restart V2bX # 查看运行日志 如果在日志中看见 Nodes started 说明节点启动成功 journalctl -u V2bX.service -f (5、查看Xboard中节点情况 可以看见这里变黄了,就是说待使用了,下一步我们就是让他变绿,接下来就是测试步骤了 6、测试 登录我们前台的系统(就是去掉path,管用域名登录( https://域名 )) 这个页面使用过机场的佬友就很熟悉了 我用的就是之前创建的测试用户登录,给了一个100g的套餐所以直接就有一个100g的套餐 我们点一下一键订阅,并复制订阅地址到clash去试一下 去clash测试一下没有问题 去后台面板看看节点情况( https://域名/path ),变绿了,没有问题,完结撒花 ps:也可以去购买订阅中看一下,我在套餐那新增了两个套餐和提示词模板,这样就有模有样了 参考文章 V2bX 单节点(VLESS / Reality)部署指南 xboard | Limin Studio 6 个帖子 - 6 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-17 10:12:57+08:00 · tech

用到的项目 G站/crazypeace/VLESS-cracker 1. 搭一个正常工作的 Caddy 提供HTTPS服务 这里以域名 域名点康姆 为例 DNS域名解析设置 略 Caddyfile 域名点康姆 { tls [email protected] encode gzip reverse_proxy https://遵守论坛准则 { header_up Host {upstream_hostport} } } 2. 搭建一个正常工作的 Reality服务端, 特别地, "偷"证书的域名是由第1步中Caddy提供HTTP服务 这里以域名 域名点康姆 为例 curl -LO G站/crazypeace/xray-vless-reality/raw/main/install.sh || wget -O ${_##*/} $_ && bash install.sh 4 8443 域名点康姆 3. 在Docker中搭一个 Reality服务端, 使用宿主机的 Reality服务端 同样的内核和配置文件 docker run -d \ --name reality-server \ --network bridge \ -v /usr/local/bin/xray:/usr/local/bin/xray:ro \ -v /usr/local/etc/xray/config.json:/usr/local/etc/xray/config.json:ro \ ghcr.io/xtls/xray-core:latest 查询 Docker 的IP地址 docker ps -q | xargs docker inspect -f '{{.Name}} -> {{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 4. 运行 Reality客户端 对接Docker中的服务端 reality-client.json { "log": { "loglevel": "warning" }, "inbounds": [ { "port": 1080, "listen": "127.0.0.1", "protocol": "socks", "settings": { "auth": "noauth", "udp": true }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } } ], "outbounds": [ { "protocol": "vless", "settings": { "vnext": [ { "address": "172.17.0.2", //***按实际情况修改 "port": 8443, "users": [ { "id": "2046c4dc-aed9-3e35-b047-e858a827181c", //***按实际情况修改 "flow": "xtls-rprx-vision", "encryption": "none" } ] } ] }, "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { "serverName": "域名点康姆", "publicKey": "-WQvFYoH9cv3DDdEY5lPU1kj1DW7w9HgtApO7edwEmw", //***按实际情况修改 "shortId": "71790f91e17fa641", //***按实际情况修改 "spiderX": "/" } }, "tcpSettings": { "header": { "type": "none" } } } ] } 运行 Reality客户端 /usr/local/bin/xray run -config /root/VLESS-cracker/reality-client.json 5. 启动POC程序 ./vless-cracker-v1 \ -i docker0 \ -f "tcp port 8443 and host 172.17.0.1 and host 172.17.0.2" \ -P characteristic.txt \ -l info 6. 发起Reality数据包 用 curl 调用Reality客户端生成的 socks 代理. 这样 Reality客户端 会发起Reality数据包 curl -x socks://127.0.0.1:1080 google.com 7. 分析日志 将打印的日志, 复制粘贴到 vless-analyzer.html 这个日志分析工具保存在 G站/crazypeace/VLESS-cracker/blob/main/vless-analyzer.html 8. 探针文件说明 characteristic.txt 是原作者的7个探针 probes-1-10.txt probes-11-20.txt probes-21-30.txt 是 issue 29 的30个探针. 其中, 第5, 18, 30号探针情况特殊, 需要单独测试. 在 probes-*-*.txt 文件中, 对应的位置填充了数据占位. 也就是说, 当你使用 probes-1-10.txt probes-11-20.txt probes-21-30.txt 进行测试时, 并没有按issue29作者的构思正确地实施 第5, 18, 30号探针 probe-5-16385.txt 用原poc程序, 会因为探针体积大报错"probe file ‘probe-5-16385.txt’ line 1 is too long" 需要使用 probe-5-poc 程序. 在程序中调整了 #define MAX_PROBE_BYTES 32768 ./probe-5-poc \ -i docker0 \ -f "tcp port 8443 and host 172.17.0.1 and host 172.17.0.2" \ -P probe-5-16385.txt \ -l info 编译 probe-5-poc 的方法 gcc -O2 -o probe-5-poc probe-5-mimo.c -lpcap -lpthread probe-18.txt 需要使用 probe-18-poc 程序. 在程序中调整了逻辑顺序, 将探针添加到 “client-hello” 的前面, 再合并一起发送. ./probe-18-poc \ -i docker0 \ -f "tcp port 8443 and host 172.17.0.1 and host 172.17.0.2" \ -P probe-18.txt \ -l info 编译 probe-18-poc 的方法 gcc -O2 -o probe-18-poc probe-18-mimo.c -lpcap -lpthread probe-30.txt 单独测试即可 ./vless-cracker-v1 \ -i docker0 \ -f "tcp port 8443 and host 172.17.0.1 and host 172.17.0.2" \ -P probe-30.txt \ -l info 以上操作流程同时保存在 G站/crazypeace/VLESS-cracker/blob/main/如果Reality"偷"证书的域名是由Caddy提供HTTP服务-操作记录.md 9. 测试结果 原作者的7个探针 issue29 作者的30个探针 1-4, 6-10 11-17, 19-20 21-29 可以看到两轮测试的状态相同, 仅有字节数区别 以上测试日志保存在 G站/crazypeace/VLESS-cracker/blob/main/reality-caddy/characteristic.log G站/crazypeace/VLESS-cracker/blob/main/reality-caddy/probes-1-10.log G站/crazypeace/VLESS-cracker/blob/main/reality-caddy/probes-11-20.log G站/crazypeace/VLESS-cracker/blob/main/reality-caddy/probes-21-30.log 1 个帖子 - 1 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-13 10:09:44+08:00 · tech

因为强迫症,不想单独给cpa-manager单独域名。就让AI改下了。 cpa+cpm的docker compose services: cli-proxy-api: image: ${CLI_PROXY_IMAGE:-eceasy/cli-proxy-api:latest} pull_policy: always container_name: cli-proxy-api environment: DEPLOY: ${DEPLOY:-} ports: - "127.0.0.1:8317:8317" - "127.0.0.1:8085:8085" - "127.0.0.1:1455:1455" - "127.0.0.1:54545:54545" - "127.0.0.1:51121:51121" - "127.0.0.1:11451:11451" volumes: - ./config.yaml:/CLIProxyAPI/config.yaml - ./auths:/root/.cli-proxy-api - ./logs:/CLIProxyAPI/logs restart: unless-stopped networks: - cpa-network cpa-manager: image: seakee/cpa-manager:latest container_name: cpa-manager restart: unless-stopped depends_on: - cli-proxy-api ports: - "127.0.0.1:18317:18317" environment: TZ: Asia/Shanghai # CPA-Manager HTTP 监听地址 HTTP_ADDR: 0.0.0.0:18317 # 同一 docker compose 网络内访问 CLIProxyAPI CPA_UPSTREAM_URL: http://cli-proxy-api:8317 # 建议在 .env 中配置,不要直接写明文 CPA_MANAGEMENT_KEY: ${CPA_MANAGEMENT_KEY} # 数据目录,SQLite 会保存在 /data USAGE_DATA_DIR: /data # 默认配置 USAGE_RESP_QUEUE: usage USAGE_RESP_POP_SIDE: right USAGE_BATCH_SIZE: "100" USAGE_POLL_INTERVAL_MS: "500" USAGE_QUERY_LIMIT: "50000" USAGE_CORS_ORIGINS: "*" volumes: - ./cpa-manager:/data networks: - cpa-network networks: cpa-network: driver: bridge caddy的配置 cpa.example.com { encode gzip zstd # /cpm 自动补斜杠 redir /cpm /cpm/ # cpa-manager 页面走 /cpm/ handle_path /cpm/* { reverse_proxy 127.0.0.1:18317 { header_up Host {host} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} } } # cpa-manager 自身接口 handle /health { reverse_proxy 127.0.0.1:18317 } handle /status { reverse_proxy 127.0.0.1:18317 } handle /usage-service/info { reverse_proxy 127.0.0.1:18317 } handle /setup { reverse_proxy 127.0.0.1:18317 } # 用量统计接口走 cpa-manager handle /v0/management/usage* { reverse_proxy 127.0.0.1:18317 { header_up Host {host} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} } } # 其他所有请求走 CLIProxyAPI handle { reverse_proxy 127.0.0.1:8317 { header_up Host {host} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} } } } 4 个帖子 - 4 位参与者 阅读完整话题

linux.do · 2026-04-18 15:43:51+08:00 · tech

本人一直想要搭建一个中转站,偶然看见sub2api,故使用它搭建了一个,以下是步骤: 先约定 3 个你要替换的值: api.example.com :改成你的域名 [email protected] :改成你的管理员邮箱 CHANGE_ME... :改成你自己生成的随机密钥 1)登录服务器并更新系统 ssh root@你的服务器IP apt update apt -y upgrade timedatectl 这一步是基础准备,先把系统更新到当前仓库版本,并确认时间正常。时间不准会影响 HTTPS、登录态和支付回调之类的功能。Docker 官方当前 Ubuntu 安装文档仍然建议使用官方 apt 仓库安装 Docker Engine。 2)安装 Docker Engine 和 Docker Compose v2 先卸载可能冲突的旧包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do apt-get remove -y $pkg done 安装 Docker 官方仓库: apt-get update apt-get install -y ca-certificates curl install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ > /etc/apt/sources.list.d/docker.list 安装 Docker 和 Compose 插件: apt-get update apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 检查版本: docker --version docker compose version systemctl enable docker systemctl start docker systemctl status docker --no-pager Docker 官方当前安装文档给出的推荐安装包名就是 docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 。另外,Docker 也明确提醒:如果你用 UFW 或 firewalld,Docker 暴露出来的端口可能绕过防火墙表面规则,所以正式环境尽量只暴露 80/443,把 8080 留给本机反代。 3)安装 Git、openssl 和基础工具 apt-get install -y git curl wget nano openssl ufw 这些工具后面都会用到: git 拉仓库 openssl 生成密钥 nano 编辑配置 ufw 放行 80/443/22 4)准备部署目录并拉取官方文件 mkdir -p /opt/sub2api cd /opt/sub2api git clone https://github.com/Wei-Shaw/sub2api.git source cp source/deploy/docker-compose.local.yml . cp source/deploy/.env.example .env cp source/deploy/config.example.yaml config.yaml Sub2API 官方部署说明里,手动部署路径就是:克隆仓库、复制 .env.example 、创建 data postgres_data redis_data ,再用 docker-compose.local.yml 启动;并且官方明确把 local 版描述为“本地目录、易迁移”。 5)生成生产环境密钥 先生成三个随机值: openssl rand -hex 32 openssl rand -hex 32 openssl rand -hex 32 把输出保存下来,分别用于: POSTGRES_PASSWORD JWT_SECRET TOTP_ENCRYPTION_KEY 官方 .env 模板和部署说明都强调: POSTGRES_PASSWORD 必填,而 JWT_SECRET 和 TOTP_ENCRYPTION_KEY 最好固定,否则会影响持久登录态和 2FA。 6)写入最终版 .env cat > /opt/sub2api/.env <<'EOF' BIND_HOST=127.0.0.1 SERVER_PORT=8080 SERVER_MODE=release RUN_MODE=standard TZ=Asia/Shanghai POSTGRES_USER=sub2api POSTGRES_PASSWORD=CHANGE_ME_TO_A_LONG_RANDOM_PASSWORD POSTGRES_DB=sub2api DATABASE_MAX_OPEN_CONNS=50 DATABASE_MAX_IDLE_CONNS=10 DATABASE_CONN_MAX_LIFETIME_MINUTES=30 DATABASE_CONN_MAX_IDLE_TIME_MINUTES=5 REDIS_PASSWORD= REDIS_DB=0 REDIS_POOL_SIZE=1024 REDIS_MIN_IDLE_CONNS=10 REDIS_ENABLE_TLS=false [email protected] ADMIN_PASSWORD= JWT_SECRET=CHANGE_ME_TO_A_LONG_RANDOM_HEX_STRING JWT_EXPIRE_HOUR=24 JWT_ACCESS_TOKEN_EXPIRE_MINUTES=0 TOTP_ENCRYPTION_KEY=CHANGE_ME_TO_ANOTHER_LONG_RANDOM_HEX_STRING GEMINI_OAUTH_CLIENT_ID= GEMINI_OAUTH_CLIENT_SECRET= GEMINI_OAUTH_SCOPES= GEMINI_QUOTA_POLICY= GEMINI_CLI_OAUTH_CLIENT_SECRET= ANTIGRAVITY_OAUTH_CLIENT_SECRET= SECURITY_URL_ALLOWLIST_ENABLED=true SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=false SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=false SECURITY_URL_ALLOWLIST_UPSTREAM_HOSTS= UPDATE_PROXY_URL= EOF 然后编辑,把占位符改成你自己的值: nano /opt/sub2api/.env 这里我保留了 .env 里的基础白名单开关,但把域名清单放到 config.yaml 里统一管理,因为官方 config.example.yaml 里真正完整的 URL 白名单字段在 security.url_allowlist 下。 7)写入最终版 config.yaml cat > /opt/sub2api/config.yaml <<'EOF' server: host: "0.0.0.0" port: 8080 mode: "release" frontend_url: "https://api.example.com" trusted_proxies: [] max_request_body_size: 268435456 h2c: enabled: true max_concurrent_streams: 50 idle_timeout: 75 max_read_frame_size: 1048576 max_upload_buffer_per_connection: 2097152 max_upload_buffer_per_stream: 524288 run_mode: "standard" cors: allowed_origins: - "https://api.example.com" allow_credentials: true security: url_allowlist: enabled: true upstream_hosts: - "api.openai.com" - "api.anthropic.com" - "generativelanguage.googleapis.com" - "cloudcode-pa.googleapis.com" - "*.openai.azure.com" pricing_hosts: - "raw.githubusercontent.com" crs_hosts: [] allow_private_hosts: false allow_insecure_http: false response_headers: enabled: true additional_allowed: [] force_remove: [] csp: enabled: true policy: "default-src 'self'; script-src 'self' __CSP_NONCE__ https://challenges.cloudflare.com https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https:; frame-src https://challenges.cloudflare.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" proxy_probe: insecure_skip_verify: false proxy_fallback: allow_direct_on_error: false EOF 改域名: nano /opt/sub2api/config.yaml 官方当前配置示例里, frontend_url 用于生成邮件等外部链接;URL 白名单示例里也明确列出了 upstream_hosts 、 pricing_hosts 、 crs_hosts 、 allow_private_hosts 、 allow_insecure_http 。我这里把样例里的 allow_private_hosts 和 allow_insecure_http 从 true 收紧成了更适合公网生产的 false 。 8)写入最终版 docker-compose.local.yml cat > /opt/sub2api/docker-compose.local.yml <<'EOF' services: sub2api: image: weishaw/sub2api:latest container_name: sub2api restart: unless-stopped ulimits: nofile: soft: 100000 hard: 100000 ports: - "${BIND_HOST:-127.0.0.1}:${SERVER_PORT:-8080}:8080" volumes: - ./data:/app/data - ./config.yaml:/app/data/config.yaml:ro environment: - AUTO_SETUP=true - SERVER_HOST=0.0.0.0 - SERVER_PORT=8080 - SERVER_MODE=${SERVER_MODE:-release} - RUN_MODE=${RUN_MODE:-standard} - DATABASE_HOST=postgres - DATABASE_PORT=5432 - DATABASE_USER=${POSTGRES_USER:-sub2api} - DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} - DATABASE_DBNAME=${POSTGRES_DB:-sub2api} - DATABASE_SSLMODE=disable - DATABASE_MAX_OPEN_CONNS=${DATABASE_MAX_OPEN_CONNS:-50} - DATABASE_MAX_IDLE_CONNS=${DATABASE_MAX_IDLE_CONNS:-10} - DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30} - DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=${REDIS_DB:-0} - REDIS_POOL_SIZE=${REDIS_POOL_SIZE:-1024} - REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10} - REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false} - ADMIN_EMAIL=${ADMIN_EMAIL:[email protected]} - ADMIN_PASSWORD=${ADMIN_PASSWORD:-} - JWT_SECRET=${JWT_SECRET:-} - JWT_EXPIRE_HOUR=${JWT_EXPIRE_HOUR:-24} - JWT_ACCESS_TOKEN_EXPIRE_MINUTES=${JWT_ACCESS_TOKEN_EXPIRE_MINUTES:-0} - TOTP_ENCRYPTION_KEY=${TOTP_ENCRYPTION_KEY:-} - TZ=${TZ:-Asia/Shanghai} - GEMINI_OAUTH_CLIENT_ID=${GEMINI_OAUTH_CLIENT_ID:-} - GEMINI_OAUTH_CLIENT_SECRET=${GEMINI_OAUTH_CLIENT_SECRET:-} - GEMINI_OAUTH_SCOPES=${GEMINI_OAUTH_SCOPES:-} - GEMINI_QUOTA_POLICY=${GEMINI_QUOTA_POLICY:-} - GEMINI_CLI_OAUTH_CLIENT_SECRET=${GEMINI_CLI_OAUTH_CLIENT_SECRET:-} - ANTIGRAVITY_OAUTH_CLIENT_SECRET=${ANTIGRAVITY_OAUTH_CLIENT_SECRET:-} - SECURITY_URL_ALLOWLIST_ENABLED=${SECURITY_URL_ALLOWLIST_ENABLED:-true} - SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=${SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP:-false} - SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=${SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS:-false} - SECURITY_URL_ALLOWLIST_UPSTREAM_HOSTS=${SECURITY_URL_ALLOWLIST_UPSTREAM_HOSTS:-} - UPDATE_PROXY_URL=${UPDATE_PROXY_URL:-} depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - sub2api-network healthcheck: test: ["CMD", "wget", "-q", "-T", "5", "-O", "/dev/null", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 30s postgres: image: postgres:18-alpine container_name: sub2api-postgres restart: unless-stopped ulimits: nofile: soft: 100000 hard: 100000 volumes: - ./postgres_data:/var/lib/postgresql/data environment: - POSTGRES_USER=${POSTGRES_USER:-sub2api} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} - POSTGRES_DB=${POSTGRES_DB:-sub2api} - PGDATA=/var/lib/postgresql/data - TZ=${TZ:-Asia/Shanghai} networks: - sub2api-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-sub2api} -d ${POSTGRES_DB:-sub2api}"] interval: 10s timeout: 5s retries: 5 start_period: 10s redis: image: redis:8-alpine container_name: sub2api-redis restart: unless-stopped ulimits: nofile: soft: 100000 hard: 100000 volumes: - ./redis_data:/data command: > sh -c ' redis-server --save 60 1 --appendonly yes --appendfsync everysec ${REDIS_PASSWORD:+--requirepass "$REDIS_PASSWORD"} ' environment: - TZ=${TZ:-Asia/Shanghai} - REDISCLI_AUTH=${REDIS_PASSWORD:-} networks: - sub2api-network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 5s networks: sub2api-network: driver: bridge EOF 这份 compose 依然遵循官方 local 版思路:本地目录持久化、 weishaw/sub2api:latest + postgres:18-alpine + redis:8-alpine 、 /health 健康检查;另外我把 config.yaml 的挂载打开了,因为官方默认是注释状态。 9)创建数据目录并启动容器 cd /opt/sub2api mkdir -p data postgres_data redis_data docker compose -f docker-compose.local.yml up -d docker compose -f docker-compose.local.yml ps 如果一切正常,再看日志: docker compose -f docker-compose.local.yml logs -f sub2api Sub2API 官方说明里写得很明确:Compose 模式下 AUTO_SETUP=true 时,首次启动会自动连接 PostgreSQL 和 Redis、执行数据库迁移、创建管理员账号、在未提供时自动生成管理员密码。 10)取出管理员密码并做健康检查 如果你在 .env 里把 ADMIN_PASSWORD= 留空,就执行: docker compose -f docker-compose.local.yml logs sub2api | grep -i "admin password" 本机健康检查: curl http://127.0.0.1:8080/health 官方手动部署说明和命令示例里都给了从日志里查自动生成管理员密码的方法。( GitHub ) 11)安装 Caddy 并启用自动 HTTPS 先安装 Caddy 官方仓库: apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg chmod o+r /etc/apt/sources.list.d/caddy-stable.list apt update apt install -y caddy 这正是 Caddy 官方当前给出的 Debian/Ubuntu stable 安装路径。( Caddy Web Server ) 12)写入 Caddyfile cat > /etc/caddy/Caddyfile <<'EOF' api.example.com { @static { path /assets/* path /logo.png path /favicon.ico } header @static { Cache-Control "public, max-age=31536000, immutable" -Pragma -Expires } tls { protocols tls1.2 tls1.3 } reverse_proxy 127.0.0.1:8080 { health_uri /health health_interval 30s health_timeout 10s health_status 200 header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} header_up X-Forwarded-Host {host} header_up CF-Connecting-IP {http.request.header.CF-Connecting-IP} } encode { zstd gzip 6 minimum_length 256 } request_body { max_size 100MB } log { output file /var/log/caddy/sub2api.log { roll_size 50mb roll_keep 10 roll_keep_for 720h } format json level INFO } handle_errors { respond "{err.status_code} {err.status_text}" } } EOF 检查并重载: caddy fmt --overwrite /etc/caddy/Caddyfile caddy validate --config /etc/caddy/Caddyfile systemctl enable caddy systemctl restart caddy systemctl status caddy --no-pager 官方仓库当前确实自带 deploy/Caddyfile ,里面已经包含 TLS、 reverse_proxy localhost:8080 、 /health 健康检查、转发真实 IP 头和日志滚动思路,所以这条路线最省心。 13)放行防火墙 ufw allow 22/tcp ufw allow 80/tcp ufw allow 443/tcp ufw enable ufw status verbose 不要开放 8080 给公网,因为你已经通过 BIND_HOST=127.0.0.1 把应用只绑在本机,再让 Caddy 反代它。这样也符合 Docker 官方对防火墙的安全提醒。 14)最终验证 先本机验证: curl http://127.0.0.1:8080/health curl -I https://api.example.com 然后浏览器访问: https://api.example.com 用管理员邮箱和日志里拿到的密码登录。 15)部署完成后立刻执行的 5 个检查 登录后台,确认能打开首页。 到设置里确认站点 URL 是否正确。 frontend_url 如果没配对,后面邮件链接和支付回调会出错。 如果你要启用 URL 白名单,只保留自己真的要用的上游域名。官方样例里带了 OpenAI、Anthropic、Gemini、Azure OpenAI 等域名,但生产上不建议全开。 如果要开支付,后台路径是 设置 → 支付设置 ,官方当前支持 EasyPay、支付宝官方、微信官方、Stripe;多实例分流支持 round-robin 和 least-amount ,回调地址会按你的域名自动拼接。 如果你用 Stripe,记得订阅 payment_intent.succeeded 和 payment_intent.payment_failed 。 16)后续最常用的运维命令 cd /opt/sub2api # 看状态 docker compose -f docker-compose.local.yml ps # 看日志 docker compose -f docker-compose.local.yml logs -f sub2api # 重启应用 docker compose -f docker-compose.local.yml restart sub2api # 更新镜像 docker compose -f docker-compose.local.yml pull docker compose -f docker-compose.local.yml up -d # 停服务 docker compose -f docker-compose.local.yml down 官方部署说明里也给了 local 版这组常用命令,并强调 local 版最方便整目录迁移和备份。 4 个帖子 - 4 位参与者 阅读完整话题