春有百花秋有月

春有百花秋有月

夏有凉风冬有雪

X-UI + Reality + WARP 全栈代理配置指南

本文详细记录利用 X-UI 面板搭建 VLESS-Reality 节点,配合 Cloudflare WARP SOCKS5 分流解锁 AI 服务的完整方案。适用于具备一定 Linux 操作基础的用户。

在跨境网络访问场景中,IDC 机房 IP 容易被目标网站(OpenAI、Claude、Gemini、X 等)识别并限制(1020 错误或直接拒绝访问)。同时,移动端(尤其是 iOS)依赖 Apple APNs 推送服务,代理路由配置不当会导致 Telegram 等 App 推送失效。

本文方案:

                        ┌─────────────────────┐
  Client                │   Linux Server       │
  ┌──────┐              │  ┌───────────────┐   │
  │ QX / │───HTTPS─────▶│  │  X-UI Panel   │   │
  │ SR   │              │  │  (TLS + 443)  │   │
  └──────┘              │  └───────┬───────┘   │
                         │          │           │
                         │  ┌───────▼───────┐  │
                         │  │ Xray-core      │  │
                         │  │ VLESS Reality  │  │
                         │  └───────┬───────┘  │
                         │          │           │
                         │   ┌──────▼──────┐   │
                         │   │ warp-cli     │   │
                         │   │ SOCKS5 :1234 │   │
                         │   └──────┬──────┘   │
                         │          │           │
                         └──────────┼───────────┘
                                    │
                              CF WARP Edge IP
                               (解锁 AI 服务)

核心协议选型说明:

阅读剩余部分 →

OpenClaw Cron 任务 EmbeddedAttemptSessionTakeoverError 排查与修复记录

背景:近期服务器每日备份(02:00)和每日 Dashboard 早报(06:01)等多个定时任务频繁报错 EmbeddedAttemptSessionTakeoverError,导致任务无法正常执行。经过详细排查,发现这是一个配置冲突导致的问题。

OpenClaw 日志中反复出现:

EmbeddedAttemptSessionTakeoverError

多个 cron 任务随机失败,有时备份能跑但早报失败,有时反过来。看起来像是资源竞争的问题。

检查所有 cron 任务的 jobs.json 配置后发现一个致命的矛盾配置

{
  "sessionTarget": "isolated",      // ← 说:请用独立会话运行
  "sessionKey": "agent:main:telegram:default:direct:5595946736"  // ← 又说:强制绑定到同一个 TG 会话
}

这两个配置同时存在时,OpenClaw 优先使用 sessionKey,导致所有 10 个定时任务都在抢同一个 Telegram DM 会话锁

sessionKey 是「绑定到指定会话」的硬链接,所有任务指向同一个 Telegram DM 会话。并发时只有一个任务能持有该会话,其他全部失败。

二选一,不能混用:

方案 A(我们使用的):isolated + announce

阅读剩余部分 →

OpenClaw 故障排查:EmbeddedAttemptSessionTakeoverError 解决方案

OpenClaw 故障排查:EmbeddedAttemptSessionTakeoverError 解决方案

cron 任务(每日Dashboard早报、服务器每日备份)反复失败,错误信息如下:

EmbeddedAttemptSessionTakeoverError: session file changed while embedded prompt lock was released: 
/home/openclaw/.openclaw/agents/main/sessions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.jsonl

FailoverError: session file changed while embedded prompt lock was released

问题原因

技术原理

OpenClaw 的 Pi embedded runner 在执行 cron 任务时采用双锁机制:

当锁在步骤2释放期间,如果有其他进程修改了同一个 session 文件(fingerprint 指纹变化),重新获取锁时会检测到文件被篡改,抛出 EmbeddedAttemptSessionTakeoverError。

cp ~/.openclaw/agents/main/sessions/sessions.json ~/.openclaw/agents/main/sessions/sessions.json.bak.$(date +%Y%m%d)

步骤 2:识别故障 cron job 的 sessionKey

从 cron runs 日志中找到 sessionId,例如:

/home/openclaw/.openclaw/agents/main/sessions/6d127bc5-cdf9-4c03-97fd-761bb7dd55d7.jsonl

对应的 sessionKey 为:

阅读剩余部分 →

跑步自动归档 Watcher 两次 Debug 实录:从轮询到 inotify 的本地 OCR 优化之路

🤖 本文由 OpenClaw + DeepSeek 自动生成

一次从远程 OCR 降级到本地 Tesseract 的架构痛史,顺便干掉三个隐蔽 Bug。

我平时跑步用 Nike Run Club(NRC),跑完后截个图发到自己的 Telegram Bot,Bot 会自动把图片存入服务器。我有一个后台 Watcher 脚本,专门监控这个图片目录,一旦发现新图片就 OCR 提取运动数据(距离、时长、配速、卡路里),然后自动归档到 Notion 的 Sports 数据库,实现"跑完截个图,一切自动归档"的极简体验。

本来这套流程跑得好好的,直到前天,突然崩了。

截图发过去,Bot 这边显示图片已保存,但 Notion 里就是没有新记录。手动跑脚本测试,发现 OCR 一直超时,偶尔跑出来也是空结果。

开始排查。

起初 Watcher 的 OCR 链路是这样的:图片 → image 工具调用外部视觉 API → 返回文本。这套链路的核心问题在于:

一张截图 OCR 要等 30 秒以上,频繁超时。

阅读剩余部分 →

OpenClaw + 私人中台优化实录

OpenClaw + 私人中台优化实录(2026-06-04 ~ 2026-06-05)

最近对个人 OpenClaw 中台做了一次系统性优化,解决了几个长期痛点,记录一下。

原来的早报只有天气、待办、股票、新闻四大块,这两天新增了两个模块:

1. 昨日复盘修复
之前的「已完成任务」里混入了历史积压任务,只要在 Notion 里标记过就算进来,不管实际完成了多久。现在改为以 last_edited_time 为唯一判定锚,只显示昨天实际完成的任务。

2. 情感温度计
新增「💓 活跃度」区块,扫描最近 7 天对话记录中敏感关键词出现频率,映射为 🔥 / 📊 / 💤 三档输出,完全不暴露具体内容。阈值:≥15 次 → 🔥,≥5 次 → 📊,<5 次 → 💤。

之前 9:30 检测未触发预警时还会发一条「无声模式退出」消息,纯粹噪音。改造了两点:

改造后只有触发 6% 股息率预警时才推送,其余时间完全静默。

两个待办 cron(9:00 早间提醒 + 17:30 下班前催办)同样改为:脚本内部无内容时 return 静默退出,cron delivery 全部改为 none。零噪音原则:正常状态不发任何消息,有事才推。

阅读剩余部分 →

榨干甲骨文VPS:从全局卡顿到满血4K

Xray + Cloudflare WARP 完美智能分流 · 解锁 ChatGPT/Gemini 保姆级教程

自建节点的小伙伴常常会遇到一个两难抉择:为了解锁 ChatGPT、Gemini 或 Claude 等对机房 IP 封锁极严的 AI 服务,我们通常会在 VPS 上套一层 Cloudflare WARP。

然而,如果使用传统的"全局 WARP(WGCF模式)",整台服务器的所有出站流量都会被强制拉进 WARP 的虚拟网卡。由于 Cloudflare 免费公用节点的带宽处于全球网民"公地悲剧"的状态,晚高峰或网络抽风时,原本可以跑满几百兆的甲骨文原生网络,会被活生生限速到 1 Mbps(连 YouTube 1080P 都卡)

本文将分享一套企业级/生产标准的分流架构:让服务器恢复纯净原生公网(YouTube 直连秒开 4K 几万 Kbps),同时让 Xray 像智能交通警察一样,只把去往 AI 网站的流量精准踢给 WARP 转发,完美兼顾极致网速流媒体/AI完美解锁

我们要做的第一步,就是把 WARP 从"接管全局网卡的流氓"变成"只在后台默默监听的备用通道"。

cf

2.卸载全局 WARP:在弹出的菜单中,先输入 4 彻底卸载当前运行的 WGCF-WARP(防止新旧模式冲突)。

3.安装 Socks5-WARP:重新输入 cf 进入菜单,选择 2. 方案二:安装 Socks5-WARP

4.记录本地端口:一路回车保持默认安装。安装成功后,脚本会在屏幕上提示一个关键的本地监听端口,通常默认为 40000(本地 IP 为 127.0.0.1)。

阅读剩余部分 →

服务器备份体系搭建全记录

本文记录于 2026-05-28,基于 Oracle ARM Ubuntu 20.04 LTS 环境,折腾了一整个下午才搞定。

服务器上跑着一堆服务:两个 Typecho 博客、一个 OpenClaw AI 中台、各种 Docker 容器(PhotoPrism、BitWarden、alist 等),还有 Java/Python 微服务。每天凌晨把这些东西自动备份到 OneDrive,并且要求:

/mnt/onedrive/bak/
├── Mon/          ← 周一备份(7天循环)
├── Tue/          ← 周二备份
├── Wed/          ← 周三备份
├── Thu/          ← 周四备份 ← 今天生成的
├── Fri/          ← 周五备份
├── Sat/          ← 周六备份
└── Sun/          ← 周日备份

每个工作日目录内,包含以下备份文件:

Thu/
├── backup_server.sh      ← 备份脚本本身(核心!)
├── crontab.txt          ← Cron 任务配置导出
├── docker_volumes.tar.gz ← Docker 数据卷(待 Docker 可用后生效)
├── dockers.tar.gz       ← /opt/dockers 容器配置
├── install_software.sh   ← 快速安装脚本(可在新机跑)
├── nginx_conf.tar.gz    ← Nginx conf.d 配置
├── nginx_ssl.tar.gz     ← SSL 证书目录
├── openclaw.tar.gz      ← OpenClaw 整个主目录
├── packages.txt         ← 系统已装软件完整清单
├── service.tar.gz       ← /opt/service 微服务
├── typecho.tar.gz       ← 主博客(SQLite 安全打包)
└── typecho_sex.tar.gz   ← 第二个博客

单轮次总大小约 786M,7 天循环总共约 5.5G,对 OneDrive 来说毫无压力。

阅读剩余部分 →

从windows拷贝到Mac上的堡垒机私钥无法使用问题解决方案

输入口令后报错信息:Keys(Pkcs1(Pkcs8(Asn1(Error

 SSH  Connecting to portal-pro
 SSH  Host key fingerprint:
 SSH   ssh-rsa  SHA256:K2YjDYXsD5ehqZvvBfxvW0voThaKT9nRqXtXVQxu1yQ 
 SSH   !  Failed to load private key file:///Users/zgz/Documents/dev/server_file/0.197_luojugang: Error: Keys(Pkcs1(Pkcs8(Asn1(Error { kind: Length { tag: Tag(0x6e: APPLICATION [14] (constructed)) }, position: None }))))

查看私钥文件:

cat /Users/zgz/Documents/dev/
<!--more-->
server_file/0.197_luojugang

如下信息:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,557572BEACB4BC74

这说明:
• 这是一个 PEM 格式、RSA 私钥
• 加密过,密码保护的
• 加密方式是 DES-EDE3-CBC
→ 新版 OpenSSH 和许多 Rust SSH 库默认不再支持这种旧式加密 PEM 私钥格式了

📌 解决方法:

✅ 方法 1:解密私钥并转成不加密的 PEM 格式

在 Mac 上执行:

阅读剩余部分 →

从 MacBook Air M1 迁移到 M4:完整迁移助手记录

最近入手了 MacBook Air M4,顺利把原来的 MacBook Air M1 上的数据迁移过来,记录一下整个过程和遇到的小坑,给后来者参考。

📦 设备配置

设备 配置
旧设备 MacBook Air M1 2020, macOS Sequoia 15.0.1
新设备 MacBook Air M4 2024, macOS Sequoia 15.3
迁移方式 迁移助理(Migration Assistant)
连接方式 Thunderbolt 4 数据线直连
数据量 约 180 GB

📃 迁移前准备

.5
👉 避免版本不一致导致迁移助手卡顿/断连的问题。

📦 迁移步骤

1️⃣ 打开迁移助手
• 应用程序 → 实用工具 → 迁移助理
• 新机选择「从 Mac、Time Machine 或启动磁盘转移数据」

2️⃣ 连接设备
• 插上雷雳4线,或连同一 Wi-Fi
• 等待两台设备互相识别

阅读剩余部分 →

MySQL Client 8.0.42 安装过程记录(内网服务器)

在可访问外网的服务器,前往 MySQL官网 下载以下 RPM 包:

保存到目录:

/home/appadmin/2025/

2️⃣ 上传 RPM 包到内网服务器

⚠️ 注意:

使用 rz 上传发现 上传后 MD5 值与源文件不一致,导致安装异常。

📌 解决方法:

改用 scp 方式上传,确保文件完整。

示例命令:

阅读剩余部分 →

配置uWSGI

应用背景

本配置文档适用于基于 Flask 的 file_upload 应用。应用所在目录为 /opt/service/python_prj/fileUpload/upload/ver3,并使用 uWSGI 提供服务。通过系统服务管理器 systemd 启动和管理 uWSGI。

在虚拟环境 pictoHub.env 中安装 uWSGI:

source /opt/service/python_prj/pictoHub.env/bin/activate
pip install uwsgi
deactivate

2. 创建 uWSGI 用户

为 uWSGI 服务创建独立的运行用户 uwsgi:

sudo useradd -r -s /bin/false uwsgi

3. 授权相关目录

确保 uwsgi 用户对必要目录有权限:

sudo mkdir -p /var/log/uwsgi
sudo mkdir -p /run/uwsgi

sudo chown -R uwsgi:uwsgi /opt/service/python_prj/fileUpload/upload/ver3
sudo chown -R uwsgi:uwsgi /var/log/uwsgi
sudo chown -R uwsgi:uwsgi /run/uwsgi

4. 创建 uWSGI 配置文件

在 /opt/service/python_prj/fileUpload/upload/ver3/ 中创建 uwsgi.ini 文件,内容如下:

[uwsgi]

<!--more-->
# uWSGI 运行用户和组
uid = uwsgi
gid = uwsgi

# 启动服务监听的地址和端口
http-socket = 0.0.0.0:8066

# 指定虚拟环境路径
virtualenv = /opt/service/python_prj/pictoHub.env

# 指定 Flask 应用文件的路径
wsgi-file = /opt/service/python_prj/fileUpload/upload/ver3/app.py

# 设置 Flask 的应用实例
callable = app

# 设置静态文件目录映射
static-map = /static=/opt/service/python_prj/fileUpload/upload/ver3/static

# 日志文件路径
logto = /var/log/uwsgi/uwsgi.log

# 设置进程数
processes = 4

# 确保应用正常启动
touch-reload = /opt/service/python_prj/fileUpload/upload/ver3/app.py

5. 创建 Systemd 服务文件

在 /etc/systemd/system/ 目录下创建 file_upload-uwsgi.service,内容如下:

阅读剩余部分 →

Mac install Erlang and RabbitMQ

以下是如何在 Mac 上安装 Erlang 和 RabbitMQ,并启用 RabbitMQ 可视化监控插件的详细步骤。

阅读剩余部分 →

推送(git push)操作在向 GitHub 发送数据时遇到了问题

您遇到的 Git 错误日志表明,推送(git push)操作在向 GitHub 发送数据时遇到了问题。具体错误信息如下:

error: RPC failed; HTTP 400 curl 22 The requested URL returned error: 400
send-pack: unexpected disconnect while reading sideband packet
fatal: the remote end hung up unexpectedly

这些错误通常与以下几个原因相关:

这部分显示了您提交的文件大小(54.45 MB)。Git 默认推送限制较小的文件,如果您上传的文件太大,可能会导致超时或断开连接。

解决办法:
• 您可以通过调整 Git 的 http.postBuffer 设置来增加上传限制。运行以下命令来增加缓冲区大小:

git config --global http.postBuffer 524288000

这将把上传缓冲区的大小设置为 500MB。

解决办法:
• 如果您的文件太大,您可能需要使用 Git LFS(Git Large File Storage)来管理大文件。您可以按照 GitHub 官方文档 设置 Git LFS 来解决这个问题。

网络问题:
• 有时网络中断或不稳定也会导致上传过程中断。您可以尝试重新提交或者在网络更稳定的环境下再试一次。

分支名称问题:
• 您的命令是 git push -u master master,看起来像是想将本地的 master 分支推送到远程的 master 分支,但 master 分支在 GitHub 上可能已经更名为 main。

阅读剩余部分 →

使用jVectorMap工具为typecho增加足迹功能

本文部署后的足迹地图如下:
https://313390.xyz/index.php/51.html

github参考地址:
https://github.com/HelloWuJiaYi/jVectorMap-Footprint

注意事项:

    # Map info
    location /map {
        index index.html;
        #try_files $uri $uri/ =404;
        add_header X-Frame-Options "ALLOWALL";
    }
<!--more-->
  • 2.修改index.html,可根据注释修改使用中国地图或者世界地图,然后增加自已的足迹点,足迹坐标可参考:
    https://jingweidu.bmcx.com/

    3.新建独立页面,引入如下代码:

    !!!
    <iframe style="max-width: 100%" 
                frameborder="no" 
                border="0" 
                marginwidth="0" 
                marginheight="0" 
                width="100%" 
                height="600px" 
                src="https://313390.xyz/map/index.html">                                        
          </iframe>
    !!!
  • 4.收工,访问新建的独立页面即可。

    阅读剩余部分 →

调整Mac book中Launchpad启动台的行、列数量

具体办法:

打开终端,复制并执行以下4行命令:

defaults write com.apple.dock springboard-columns -int 12
defaults write com.apple.dock springboard-rows -int 8
defaults write com.apple.dock ResetLaunchPad -bool TRUE
killall Dock
  • 说明:

    以上每行的含义:
    1、调整每一列显示图标数量,9表示每一列显示9个,数字部分可根据个人喜好进行设置。
    2、调整多少行显示图标数量,这里我用的是6,数字部分你也可以改成8或其他
    3、重置Launchpad
    4、重启Dock
  • 恢复默认设置的方法,在终端Terminal中执行以下4行命令(全部复制):

    阅读剩余部分 →
  • 控制typecho首页不显示全文,只显示摘要的方法

    虽然在Typecho的文章撰写里面可以使用

    <!--more-->

    来控制首页显示文章的内容,但有时候码完字后忘记添加了又需要进去编辑添加。为了能达到一劳永逸的效果,以下将采用修改Typecho模版来实现全局控制文章显示的内容:

    阅读剩余部分 →

    为typecho文中代码增加一键复制功能

    Update header.php,add codecopy,eg:

    vi /var/www/typecho/usr/themes/single/header.php

    在header之前增加如下js脚本:

    <script>
            // 在代码块右上角添加复制按钮
            document.addEventListener('DOMContentLoaded', initCodeCopyButton);
            function initCodeCopyButton() {
                function initCSS(callback) {
                    const css = `
                        .btn-code-copy {
                            position: absolute;
                            line-height: .6em;
                            top: .2em;
                            right: .2em;
                            color: rgb(87, 87, 87);
                        }
                        .btn-code-copy:hover {
                            color: rgb(145, 145, 145);
                            cursor: pointer;
                        }
                        `;
                    const styleId = btoa('btn-code-copy').replace(/[=+\/]/g, '');
                    const head = document.getElementsByTagName('head')[0];
                    if (!head.querySelector('#' + styleId)) {
                        const style = document.createElement('style');
                        style.id = styleId;
                        if (style.styleSheet) {
                            style.styleSheet.cssText = css;
                        } else {
                            style.appendChild(document.createTextNode(css));
                        }
                        head.appendChild(style);
                    }
                    callback();
                };
                function copyTextContent(source) {
                    let result = false;
                    const target = document.createElement('pre');
                    target.style.opacity = '0';
                    target.textContent = source.textContent;
                    document.body.appendChild(target);
                    try {
                        const range = document.createRange();
                        range.selectNode(target);
                        window.getSelection().removeAllRanges();
                        window.getSelection().addRange(range);
                        document.execCommand('copy');
                        window.getSelection().removeAllRanges();
                        result = true;
                    } catch (e) { console.log('copy failed.'); }
                    document.body.removeChild(target);
                    return result;
                };
                function initButton(pre) {
                    const code = pre.querySelector('code');
                    if (code) {
                        const preParent = pre.parentElement;
                        const newPreParent = document.createElement('div');
                        newPreParent.style = 'position: relative';
                        preParent.insertBefore(newPreParent, pre);
                        const copyBtn = document.createElement('div');
                        copyBtn.innerHTML = 'copy';
                        copyBtn.className = 'btn-code-copy';
                        copyBtn.addEventListener('click', () => {
                            copyBtn.innerHTML = copyTextContent(code) ? 'success' : 'failure';
                            setTimeout(() => copyBtn.innerHTML = 'copy', 250);
                        });
                        newPreParent.appendChild(copyBtn);
                        newPreParent.appendChild(pre);
                    }
                };
                const pres = document.querySelectorAll('pre');
                if (pres.length !== 0) {
                    initCSS(() => pres.forEach(pre => initButton(pre)));
                }
            };
    </script>
    阅读剩余部分 →

    acme网站证书更新

    /root/.acme.sh/acme.sh  --upgrade
  • 2.使用acme.sh更新服务器本地所有SSL证书
    /root/.acme.sh/acme.sh  --renew-all

    如果你的服务器有多个网站的SSL证书,而你只想更新其中一个网站的SSL证书,可以使用“-d 域名”参数,例如

    /root/.acme.sh/acme.sh  --renew -d domain
  • 二、自动更新

    • 1.编写自动更新脚本,将更新后的证书替换nginx中使用的证书

        #!/bin/bash
      
        # 定义变量
        ACME_HOME="/root/.acme.sh"
        CERT_TARGET_DIR="/etc/nginx/ssl"
        NGINX_SERVICE="nginx"
      
        # 停 Nginx
        echo "Stoping Nginx service..."
        systemctl stop "${NGINX_SERVICE}"
      
        # 更新所有证书
        echo "Updating all certificates..."
        "${ACME_HOME}/acme.sh" --cron --home "${ACME_HOME}"
      
        if [ $? -eq 0 ]; then
          echo "Certificates updated successfully. Processing each domain..."
      
          # 遍历所有域名目录
          for domain_dir in "${ACME_HOME}"/*_ecc; do
            if [ -d "${domain_dir}" ]; then
              # 获取域名
              domain_name=$(basename "${domain_dir}" | sed 's/_ecc$//')
      
              # 检查证书和密钥是否存在
              cert_file="${domain_dir}/fullchain.cer"
              key_file="${domain_dir}/${domain_name}.key"
      
              if [ -f "${cert_file}" ] && [ -f "${key_file}" ]; then
                # 确保目标目录存在
                target_dir="${CERT_TARGET_DIR}/${domain_name}"
                mkdir -p "${target_dir}"
      
                # 拷贝证书和密钥
                cp "${cert_file}" "${target_dir}/fullchain.cer"
                cp "${key_file}" "${target_dir}/${domain_name}.key"
      
                echo "Certificates for ${domain_name} copied to ${target_dir}."
              else
                echo "Certificate or key file missing for ${domain_name}. Skipping."
              fi
            fi
          done
      
          # 重启 Nginx
          echo "Restarting Nginx service..."
          systemctl restart "${NGINX_SERVICE}"
      
          if [ $? -eq 0 ]; then
            echo "Nginx restarted successfully. Certificates are now active."
          else
            echo "Failed to restart Nginx. Please check the configuration."
          fi
        else
          echo "Failed to update certificates. Check acme.sh logs for details."
        fi
    • 2.手动执行测试

      阅读剩余部分 →

    修改系统配置和v2ray配置支持fast-open和udp-relay

    查看系统是否支持fast-open

      sysctl net.ipv4.tcp_fastopen
  • 备份配置文件

      cp /etc/sysctl.conf /etc/sysctl.conf.bak
      vi /etc/sysctl.conf
  • 新增支持fastopen conf

      net.ipv4.tcp_fastopen = 3
  • 应用设置

      sysctl -p

    2.修改v2ray支持fastopen

      vi /etc/v2ray/config.json
  • 修改进站支持udp

      {
        "port": ****,
        "protocol": "dokodemo-door",
        "settings": {
          "address": "0.0.0.0",          // 捕获所有地址的 UDP 流量
          "port": 0,                     // 捕获所有端口的 UDP 流量
          "network": "udp",              // 指定网络类型为 UDP
          "timeout": 0,                  // 超时时间,0 表示不超时
          "followRedirect": true         // 允许重定向
        }
      }
  • 修改出站支持fastopen

    阅读剩余部分 →
  • debian&ubuntu info

    1.修改nginx欢迎页,一般默认路径为/usr/share/nginx/html/index.html

    by:onedrive/myser/index.html

    2.通过nginx代理静态文件,使用python上传文件:

    by:onedrive/myser/upload_service.py

    3.v2ray info

    by:onedrive/myser/v2ray/*

    阅读剩余部分 →