星期日, 四月 26, 2026

195 Telegram 的极简网页版 mpgram-web

20260528 更新: 这东西半个月的时间在我的 php-cli docker 里创建了两千三百多个 sh 僵尸进程... 扔了. 

 

2026 年 4 月, 机场经历了巨大的动荡, 大量中转机场的国内中转出口被清退、通报, 这里我吐槽那些还在用 SS、Trojan 协议的 SB 机场, 我认为这些能被识别的过时协议和国内出口清退通报有很大关联, 而且从中转迁移到直连还在用这些 SB 协议的 SB 机场, 后续会继续祸害直连. 

为了防止可能到来的 2026 年 5 月或者 6 月直连断网, 以及之后可能彻底和 Telegram 失去联系, 我做了个最终应急方案, esim 海外流量套餐 + 省流量的极简 Telegram 网页版 mpgram-web, 手机和电脑都可以使用. 

提一嘴 esim, 卡是骗多多上卖的二十几块的白卡, LPA(写入工具)走大部分安卓自带的 OMAPI 协议, 安卓上用闭源 Nekoko2(可刷 magisk 给 apk 提权成系统应用, 以支持 telephony api, 此软件功能多些) 或者开源 EasyEUICC (https://easyeuicc.org https://gitea.angry.im/PeterCxy/OpenEUICC/releases 这两个是同一个东西), 这两 LPA 只写卡, 二十几块的白卡自带 stk (SIM 卡工具箱) 切卡删卡功能. 流量买 eskimo 的, 走 aff 新注册有 500MB Global, 随后购买 10GB China 折扣成半价 $13.5, 再购买一次折扣成 $1 的 1GB China, 这是两个券的最优用法, 写卡连上信号后有效期两年. 如果你没见到券或者不是这个价格, 不要购买, 买最低的保卡就行. 

一些入门教程: 

https://www.leavesongs.com/THINK/using-euicc-card-to-support-esim.html

https://euicc-manual.osmocom.org/

https://iecho.cc/posts/convert-esim-to-physical-sim

https://www.muooy.com/417.html


下面是正文.  

项目地址: https://github.com/shinovon/mpgram-web

大概就是 3GQQ 那样, 这是纯网页版, 作者还有一个 j2me 的客户端, 你可以打开 api 功能, 和客户端 (https://github.com/shinovon/mpgram-client)一起使用, 也可以单使用网页版. 


 
图片来自 http://nokiahacking.pl/mpgram-web-telegram-w-kazdej-przegladarce-vt35348.htm

没错, 你没看错, 基于 java 的 j2me 的客户端, 也就是二十年前功能机使用的 jar, 截至发文的 20260426, 依旧在维护更新. 此作者似乎是 j2me 的忠实粉丝, 还接手了早已遁入虚空的 kemulator 项目继续维护 (https://github.com/shinovon/KEmulator/releases)...

本文讲的是自建 mpgram-web, 而不是使用公共服务器, 一是之前有一定数量的封号(All public instances are closed because many people getting their accounts banned by telegram flood prevention system), 二是自己的账号用别人的服务器也不安全. 

这套东西的文档做得其实很烂, 踩了很多坑, 下面是自己倒腾出来的经验. 

1, 安装 docker 并查看 docker compose 的版本号: 

curl -fsSL https://get.docker.com | bash -s docker
docker --version
docker compose version

我本来想自己编译个命令行的版本, 但折腾了几个小时都失败了, 于是就用作者带的 docker-compose.yml 了. 

2, 安装好 docker 之后, 按照教程所说, 编辑 api_values.php 和 config.php 两个文件, 如果你没有申请过 Telegram apps (api_id 和 api_hash), 那么需要打开 https://my.telegram.org/apps 来申请. 将其填入 api_values.php, 下面讲解 config.php 主要的配置及含义. 

define('sessionspath', 'session_dir/'); //和 locale img 这些目录平级, 设置一个保存登录数据的路径
define('PNG_STICKERS', true); //透明贴纸, 用不上
define('FORCE_HTTPS', false); // http 重定向到 https, 有 traefik 等反向代理, 用不上, 127.0.0.1 反代就行
define('CHROME_HTTPS', false); //
当识别到 chrome user-agent 请求头的时候, http 重定向到 https, 用不上, 同上, 走反代
define('CONVERT_VOICE_MESSAGES', false);
define('VOICE_TMP_DIR', sys_get_temp_dir().'/mp/');
define('FFMPEG_DIR', '');  //这三项和语音有关, 需要下载 ffmpeg 可执行文件, 平时我根本用不到语音, 所以跳过了
define('LOGIN_CAPTCHA', false); //登录时输入验证码, 在执行网页登录的时候, 多一步输入验证码的操作, 但我实际测试发现设置为 0 验证码照样出现... 
define('INSTANCE_PASSWORD', 'admin_password'); //登录时输入密码, 如果你的自建 mpgram-web 暴露在公网, 设置这个以防被他人滥用
define('FILE_REWRITE', false); //获取图片等文件时使用目录, 用不上, 我看默认都是 file.php?abc=def 这样请求图片或文件
define('CONVERT_TGS_STICKERS', false);
define('LOTTIE_DIR', '');
define('TGS_TMP_DIR', sys_get_temp_dir().'/mp/');
define('LOTTIE_TO_GIF', true); //和贴纸有关, 用不上, 没开. 这东西需要引入其它 GitHub 项目, 懒得折腾了
define('ENABLE_API', false);
define('ENABLE_LOGIN_API', false); //没折腾这个, 应该是开放给 j2me 客户端 mpgram-client 来使用的
define('DOWNLOAD_SIZE_LIMIT', 1024 * 1024 * 1024);
define('IMAGE_SIZE_LIMIT', 30 * 1024 * 1024);
define('UPLOAD_SIZE_LIMIT', 20 * 1024 * 1024); //限制 file.php 最大获取的大小, 保持默认了
define('ENABLE_PEER_DB', false); //设置为 false 可 
sessionspath 中的登录数据文件大小, 但无法显示好友名称, 会显示 deleted account, 如果你的号聊天特别多, 建议关闭成 false 状态, 不然 sessionspath 底下的 safe.php 文件可以来到 170MB+ 的大小, 这会造成 vendor 也就是 MadelineProto 会抛出 Amp\TimeoutException: Timeout while waiting for help.getConfig 超时报错的异常

3, 改好这两个文件之后, 开始使用 git clone 命令下载源码: 

git clone https://github.com/shinovon/mpgram-web.git

4, 随后进入项目的 docker 文件夹并执行一键编译:  

cd docker

docker compose up --build -d

5, 编译完成之后, 就可以把这几个 container 和 image 都删了, 我用的 lazydocker 在图形界面终端操作的, 如果需要命令删除自己查一下删除 container 和 image 的命令. 

git clone 的目录不要删, 留下, 因为刚才它在 compose 编译的时候引入了另一个项目 MadelineProto 放在了 vendor 目录下, 并且对这个引入的项目打了文件补丁, 所以整个克隆的目录不要动. 

6, php-cli 的 docker, 和 traefik (反向代理)

php-cli 有一些依赖要启用, 所以我重做了 dockerfile, 整合了 mpgram-web 所需的一些东西, 重新编译出一个 image 了. 具体操作如下: 

新建一个 dockerfile 空文件, 里面写入: 

FROM php:8.5.5-cli

# =========================
# 系统依赖
# =========================
RUN apt-get update && apt-get install -y --no-install-recommends \
        libyaml-dev \
        libpng-dev \
        libjpeg-dev \
        libfreetype6-dev \
        libgmp-dev \
        libffi-dev \
        libxml2-dev \
        libonig-dev \
        curl \
        procps \
        vim \
        ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# =========================
# GD 扩展配置
# =========================
RUN docker-php-ext-configure gd \
        --with-freetype \
        --with-jpeg

# =========================
# PHP 内置扩展
# =========================
RUN docker-php-ext-install -j$(nproc) \
        gd \
        mbstring \
        ffi \
        gmp \
        xml \
        fileinfo

# =========================
# PECL yaml 扩展, 这段可以不要, mpgram-web 用不到
# =========================
RUN pecl install yaml \
    && docker-php-ext-enable yaml

# =========================
# Browscap, 这是 mpgram-web 里的功能
# =========================
RUN curl -fsSL \
    http://browscap.org/stream?q=Lite_PHP_BrowsCapINI \
    -o /usr/local/etc/browscap.ini

# =========================
# 自定义 php.ini, 
mpgram-web 自带的 php.ini, 我以 conf.d 的形式加载了
# =========================
RUN curl -fsSL \
    https://raw.githubusercontent.com/shinovon/mpgram-web/refs/heads/master/docker/mpgram_web/php.ini \
    -o /usr/local/etc/php/conf.d/90-php.ini 

7, 随后使用命令编译成 image, 注意末尾有个小数点:

docker build --no-cache -t php-cli:8.5.5 .

再清理编译缓存: 

docker builder prune

最后运行, 注意指定正确的路径, 我是 /root/www: 

docker run -d -p 127.0.0.1:9000:80 --name php-cli --restart=unless-stopped -v /root/www:/var/www/html php-cli:8.5.5 php -S 0.0.0.0:80 -t /var/www/html

8, traefik 的配置, 之前自己写的 index.yaml 配置, 放在 config 文件夹下面自动加载的那种, 访问 mpgram-web 的时候总是卡住很长时间, 我判断是 http 请求被 Traefik 强行重定向到 https 了(127.0.0.1 内部), 所以我就让 ChatGPT 重写了一版, 以下是 index.yaml: 

http:
  routers:

    # =========================
    # ① HTTP → HTTPS 重定向
    # =========================
    us-http:
      entryPoints:
        - "http"
      rule: "Host(`你的网站域名, 如abc.com`)"
      middlewares:
        - redirect-https
      service: noop

    # =========================
    # ② HTTPS 正式入口
    # =========================
    us-https:
      entryPoints:
        - "https"
      rule: "Host(`你的网站域名, 如abc.com`) && PathPrefix(`/`)"
      tls:
        certResolver: "letsencrypt"
      service: us
      middlewares:
        - adrules-cors

  services:
    us:
      loadBalancer:
        servers:
          - url: "http://127.0.0.1:9000" #这里是 php-cli 开放的 9000 端口

    # 必须存在的“虚拟 service”(用于 redirect)
    noop:
      loadBalancer:
        servers:
          - url: "http://127.0.0.1"

  middlewares:

    # =========================
    # HTTPS 强制跳转
    # =========================
    redirect-https:
      redirectScheme:
        scheme: https
        permanent: true

    # =========================
    # CORS
    # =========================
    adrules-cors:
      headers:
        accessControlAllowOriginList:
          - "*"
        accessControlAllowHeaders:
          - "*"

以上是 Traefik 的 php-cli 反代配置, 如果你用 nginx 或者 apache 都可以参考. 

至于你的 mpgram-web, 建议放在一个含有随机字符的路径, 如 abc_4138u90i9tqwkrioew3894A, 这样就能防止爬虫遍历目录, 这种东西漏洞应该不少. 暴露在公网的服务器可以访问: https://abc.com/abc_4138u90i9tqwkrioew3894A/ 


这套源码跑起来是没问题, 号码登录可能不行, 使用二维码登录. 收发消息就靠刷新网页, 完完全全就是当年 3GQQ 的体验, 而且我在火狐上都没有自动刷新这一说. 

不过有一个很大的问题, 它是和进程交互的, 当一段时间没有访问后, 再去唤醒进程就会超时一次, 等待时间非常长, 可能达三~五分钟之久, 所以我想到了一个保活方法, 就是定时访问自身来保活, 也就是在 crontab -e 中添加任务. 

首先你要保证浏览器正常登录过一次, 后端才能在 sessionspath 中保存数据, 可以看到文件夹类似: 

qr_942cbc3ef5..........e5bfec.madeline

把 .madeline 之前的文件夹名复制出来. qr_942cbc3ef5..........e5bfec

构造请求. 在 crontab -e 中添加: 

*/5 * * * * /usr/bin/curl 'https://你的域名/abc_4138u90i9tqwkrioew3894A你的mpgram-web路径/chats.php?lang=en&timeoff=-18000&theme=6主题ID自己试去,或者在网页设置好去cookies里找&updint=10&user=qr_942cbc3ef5..........e5bfec你刚才复制的文件夹名' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:150.0) Gecko/20100101 Firefox/150.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Connection: keep-alive'
3 5 * * * /usr/bin/docker restart php-cli

#20260522 更新, 这个东西有屎山, 半个月的时间会积压两千三百多个 sh 僵尸进程没有结束, 所以加上了每天 php-cli 重启.  

如果有多个需要保活, 就添加多行. 如果需要直接编辑 crontab 文件, 去 /var/spool/cron/crontabs 编辑文件.  


至此, 一整套 mpgram-web 就搭好了, 你可以直接使用上面 crontab -e 里的链接访问(前提是必须在此浏览器登录过, 后端存有 session, 浏览器存有 cookies 才行), 哈哈, 是不是有 3GQQ sid 的感觉了? 也不用怕长时间不用下次唤醒超时报错了. 用起来其实还是挺麻烦的, 但这屎山折腾好了以后就会非常舒服, 你甚至还可以使用作者写的 j2me 客户端 mpgram-client 在安卓 j2me loader 模拟器, 或电脑的 kemulator 模拟器中使用. 

 

星期五, 四月 17, 2026

194 bitwarden 转 vaultwarden 自建后, creationDate 和 revisionDate 不能写入数据库的 created_at 和 updated_at 问题处理

bitwarden 简称 bw, vaultwarden 简称 vw

思路:  

1, 先将 bw 的数据导出成 bw.json. 

2, 将 bw.json 导入你自建的 vw. 

3,  将你自建的 vw 也导出一个 vw.json

4, 把 vaultwarden 的 docker / 主程序 停止, 启动, 再停止, 以保证 sqlite wal 全部写入数据库 db.sqlite3 文件.  

5, 可以把 db.sqlite3 文件下载到本地, 用 navicat 或者 dbeaver 等工具打开, 这时你看到 vw 的 sqlite 数据中,  created_at updated_at 全部变成了清一色导入的时间, 奇葩行为..

6, 使用 ai 生成代码, 寻找两个 json 中 id 的对应关系, id 是不同的, 如何一一对应呢?
我使用的是 name + username 的组合对应关系. 除此之外, 当没有 username 的时候(银行卡类型), 用 name + notes 来组合, 以防止重复的情况. 

也就是: 

两个不同的数据库 json 导出文件内容相同, id 不同, bw.json 的两个时间 creationDate 和 revisionDate 是对的, vw.json 中的两个时间是错的. 通过 name+username (没有 username 就用 name+notes) 来找到两个 json 的 "id" 对应关系. 

随后根据这个 id 的对应关系, 将 bw.json 中的 creationDate 和 revisionDate 读取出来, 写到数据库对应 id 中的 created_at 和 updated_at 中去. 

7, 我使用 ChatGPT 生成的代码如下: 

<?php

$bwFile = 'bw.json';
$vwFile = 'vw.json';
$dbFile = 'db.sqlite3';

$bwJson = json_decode(file_get_contents($bwFile), true);
$vwJson = json_decode(file_get_contents($vwFile), true);

if (!$bwJson || !$vwJson) {
    die("JSON 解析失败\n");
}

$bwItems = $bwJson['items'] ?? [];
$vwItems = $vwJson['items'] ?? [];

/**
 * key = name + username/notes
 */
function buildKey($item) {
    $name = $item['name'] ?? '';

    $username = $item['login']['username'] ?? null;
    $notes = $item['notes'] ?? '';

    $second = $username;
    if ($second === null || $second === '') {
        $second = $notes;
    }

    return $name . '|' . $second;
}

/**
 * SQLite connect
 */
$pdo = new PDO("sqlite:" . $dbFile);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

/**
 * =======================
 * 1. BW index
 * =======================
 */
$bwMap = [];

foreach ($bwItems as $item) {
    if (!isset($item['name'])) continue;

    $key = buildKey($item);

    $bwMap[$key] = [
        'creationDate' => $item['creationDate'] ?? null,
        'revisionDate' => $item['revisionDate'] ?? null,
    ];
}

/**
 * =======================
 * 2. Update DB
 * =======================
 */
$updateStmt = $pdo->prepare("
    UPDATE ciphers
    SET created_at = :created_at,
        updated_at = :updated_at
    WHERE uuid = :uuid
");

$updated = 0;
$skipped = 0;
$skippedList = [];

foreach ($vwItems as $item) {

    if (!isset($item['name'], $item['id'])) {
        $skipped++;
        $skippedList[] = [
            'reason' => 'missing name or id',
            'item' => $item
        ];
        continue;
    }

    $key = buildKey($item);

    if (!isset($bwMap[$key])) {
        $skipped++;
        $skippedList[] = [
            'reason' => 'bw not found',
            'id' => $item['id'],
            'key' => $key
        ];
        continue;
    }

    $bw = $bwMap[$key];

    if (empty($bw['creationDate']) || empty($bw['revisionDate'])) {
        $skipped++;
        $skippedList[] = [
            'reason' => 'missing bw dates',
            'id' => $item['id'],
            'key' => $key,
            'bw' => $bw
        ];
        continue;
    }

    try {
        $updateStmt->execute([
            ':created_at' => $bw['creationDate'],
            ':updated_at' => $bw['revisionDate'],
            ':uuid' => $item['id'],
        ]);

        $updated++;

    } catch (Exception $e) {
        $skipped++;
        $skippedList[] = [
            'reason' => 'sql error',
            'id' => $item['id'],
            'error' => $e->getMessage()
        ];
    }
}

/**
 * =======================
 * 3. Output
 * =======================
 */
echo "UPDATED: {$updated}\n";
echo "SKIPPED: {$skipped}\n";

echo "\n=== SKIPPED DETAILS ===\n";

if (empty($skippedList)) {
    echo "NONE\n";
} else {
    foreach ($skippedList as $s) {
        echo json_encode($s, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
    }


运行代码之前, 要把 php.ini 中的两个插件启用, 也就是把这两行前面的分号去掉, 然后重启 php: 

extension=pdo_sqlite
extension=sqlite3 

如果你的 extensions 里面甚至都没有这两个 dll, 那么改 php.ini 也没有用了, 推荐使用类似 wamp 的一键端, 它有很多名字: uniform server, unicontroller, miniserver, 都是同一个软件. 内含 apache mysql php, 只启用 php 就行. 链接: https://sourceforge.net/projects/miniserver/


最终输出如下: 

UPDATED: 成功的数量 SKIPPED: 1 === SKIPPED DETAILS === { "reason": "bw not found", "id": "这里是uuid序号", "key": "这里是json里的name字段|这里是json里的username字段" }  

没找到就说明 bw 里面没有, 这是你自建了以后新增的记录. 

再去看看数据库里面的 created_at 和 updated_at 已经写好了, 但是格式不对, 简单替换下, sql 执行: 

UPDATE ciphers
SET
  created_at = REPLACE(REPLACE(created_at, 'T', ' '), 'Z', ''),
  updated_at = REPLACE(REPLACE(updated_at, 'T', ' '), 'Z', '');


* 如果你需要 备份/同步 数据库, 如使用 mega sync 同步 .db 文件而不同步 wal, 那需要在 crontab -e 中加上: 

0 5 * * * /usr/bin/docker restart vaultwarden

来保证数据库 wal 能自动写入 .db, 而触发同步. 

星期二, 二月 24, 2026

193 docker 迁移目录和数据 包括 docker 和 containerd | 解决迁移之后依旧存储在原目录的问题

首先来讲 docker 和 containerd, docker 是个第三方软件, 它依赖于系统的 containerd, 类似于早些年的套壳 ie 浏览器, ie 坏了, 套壳浏览器也会打不开. 这两块的数据也是分开的, 也就是按照很多网上教程设置完 docker 的 json 之后, docker pull 依旧被拉取到了原目录的根本原因. 

docker 配置路径文件:  /etc/docker/daemon.json

docker 默认数据目录: /var/lib/docker/

containerd 配置路径文件: /etc/containerd/config.toml

containerd 默认数据目录: /var/lib/containerd 

所以这两个配置文件, json 和 toml 要配置好, 再把数据目录复制或移动走, docker 才能完整地运行起来


之前干了件蠢事, 由于小鸡只给了 10GB 的固态硬盘空间, 所以我把 docker 迁移到机械盘了, 机械盘很大, 有 1000GB, 但迁移过去后悔了, 在机器重启之后, 从 docker 服务开始启动到正常运行, 花了至少五分钟, 这还是只有三个容器的情况下, 如果再跑大型的 浏览器微信 qq 客户端 docker 那得花十分钟以上, 重启容器也要花费大量时间, 后来 也不需要挂着微信和 qq 了, 就打算迁移回来. 10GB 完全够用. 


现在, docker 是运行中的状态. 目前的状态: 

docker 数据: /mnt/hdd/root/docker 

containerd 数据: /mnt/hdd/root/docker/containerd

我想要迁移回 /var/lib/ 也就是系统默认的地方去. 

从这一步开始, 我详细讲解 docker 带着数据迁移的方法. 大家如果是从默认目录迁移至别处, 注意目录的颜色, 蓝色字体是 原目录, 红色字体是 目标目录, 要迁移到的地方. 

1, 确认目录位置:

docker info | grep "Docker Root Dir"

2, 停止 service 和 socket

systemctl stop docker.socket
systemctl stop docker.service
service containerd stop

3, 复制 docker 文件, 这里排除了 containerd, 因为我放到一起了: 

rsync -a \
 --exclude='containerd' \
 /mnt/hdd/root/docker/ \
 /var/lib/docker/

复制 containerd 中的文件, 由于 containerd 文件极多, rsync 效率会很低, 使用内存中转的方式在后台运行, 这种操作不会在磁盘上生成多余文件, 注意 tar -xf - -C 后面跟的是上级目录, 如果目标已存在不用的 containerd 记得删除: 

nohup bash -c 'cd /mnt/hdd/root/docker && tar -cf - containerd | tar -xf - -C /var/lib' > /root/containerd.log 2>&1 &

再使用命令对比目录大小: 

nohup bash -c 'du -sh /mnt/hdd/root/docker/containerd/ > /root/mnt.txt 2>&1' &
du -sh /var/lib/containerd/

4, 修改 docker 配置文件: 

echo '{"data-root": "/var/lib/docker"}' | sudo tee /etc/docker/daemon.json
cat /etc/docker/daemon.json

5, 修改 containerd 配置文件, 打开 /etc/containerd 文件夹, 修改 config.toml: 

root = "/var/lib/containerd"

再看一眼是否改好: 

cat /etc/containerd/config.toml

6, 先启动 containerd 再启动 docker

service restart containerd
service restart docker

7, 删除旧的 docker 文件夹和 containerd 文件夹.  

 

如果你在启动 docker 之后, 看不到 images, 看到 containers 变成了类似 md5 的名字, 那就是 containerd 的目录没设置对, 检查 toml 配置文件和实际存放的位置是不是一致, 如果你用 tar -xf - -C 一定要注意后面跟上级目录. 不然会变成 /var/lib/containerd/containerd, 变成这样也没关系, 移动一下就行. 

我没有使用 docker compose, 如果你使用它, 迁移方法可能会有不同. 

星期五, 十一月 21, 2025

192 Chrome Firefox 谷歌浏览器 火狐浏览器 最后一个支持 Flash 的版本 | 最后一个支持 Windows 7 的版本 | 最后一个支持 Manifest V2 的版本

直接上链接: 

Firefox 84 是支持Adobe Flash Player NPAPI 插件的最终版本
32位: https://ftp.mozilla.org/pub/firefox/releases/84.0.2/win32/zh-CN/Firefox%20Setup%2084.0.2.exe
64位: https://ftp.mozilla.org/pub/firefox/releases/84.0.2/win64/zh-CN/Firefox%20Setup%2084.0.2.exe

Chrome 87.0.4280.141
Chromium 历史版本下载: https://vikyd.github.io/download-chromium-history-version/#/
32位: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win/811961/
64位: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win_x64/811961/
(下载地址里的版本稍低于87.0.4280.141)

===========

Firefox 115 是支持 windows 7 的最终版本, 截至 2025 年 11 月博文发布之时, ESR 115 系列还在持续更新: 
32位: https://ftp.mozilla.org/pub/firefox/releases/115.30.0esr/win32/en-US/Firefox%20Setup%20115.30.0esr.exe
64位: https://ftp.mozilla.org/pub/firefox/releases/115.30.0esr/win64/en-US/Firefox%20Setup%20115.30.0esr.exe

Chrome 109.0.5414.120
32位: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win/1067904/
64位: https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win_x64/1068050/
(下载地址里的版本稍低于109.0.5414.120)

===========

Chrome 最后一个支持 Manifest V2 的版本: 139.0.7258.155 注意以下两个链接非官方链接: 
32位: https://github.com/Bush2021/chrome_installer/releases/download/139.0.7258.155/x86_139.0.7258.155_chrome_installer_uncompressed.exe
64位: https://github.com/Bush2021/chrome_installer/releases/download/139.0.7258.155/x64_139.0.7258.155_chrome_installer_uncompressed.exe

Firefox 最后一个支持 Manifest V2 的版本: 未知, 火狐目前依旧支持 Manifest V2 ... 去 FTP 下载最新版即可. 

=========== 

星期六, 十一月 15, 2025

191 VLESS 偷域名证书的自动化 shell 检测脚本 | 使用 Mihomo 内核搭建 VLESS xtls-rprx-vision

首先上检测代码, 灵感来源于 Xray Reality 自建教程 - Vless + Reality 协议 + Vision 流控

#!/bin/bash
# check_tls_cdn.sh
# 彩色输出 TLS1.3 / ALPN:h2 / X25519 / OCSP 支持情况 + CDN 检测
# 用法: ./check_tls_cdn.sh https://example.com https://another.com
# 颜色定义
GREEN="\e[32m"
RED="\e[31m"
YELLOW="\e[33m"
RESET="\e[0m"
check_url() {
 local url="$1"
 local domain
 domain=$(echo "$url" | sed -E 's#^https?://([^/]+).*#\1#')
 echo -e "=============================="
 echo -e "检测目标: $domain"
 echo -e "------------------------------"
 # ================= TLS 检测 =================
 local output
 output=$(echo | openssl s_client -connect "${domain}:443" -servername "$domain" -alpn "h2,http/1.1" -status 2>&1)
 # TLS 1.3
 echo "$output" | grep -qE 'TLSv1\.3'
 local tls_supported=$?
 # ALPN h2
 echo "$output" | grep -qiE 'ALPN[^:]*:.*\bh2\b'
 local h2_supported=$?
 # X25519
 echo "$output" | grep -qiE '\bX25519\b|\bx25519\b|mlkem[0-9]*x25519'
 local key_supported=$?
 # OCSP
 echo "$output" | grep -qiE 'OCSP (Response|response).*successful|OCSP Response Status: successful'
 local ocsp_supported=$?
 # ===== TLS 输出结果(带颜色) =====
 echo -e "检测结果:"
 [[ $tls_supported -eq 0 ]] && echo -e "  ✓ TLSv1.3: ${GREEN}支持${RESET}" || echo -e "  ✗ TLSv1.3: ${RED}未检测到${RESET}"
 [[ $h2_supported -eq 0 ]] && echo -e "  ✓ ALPN:h2: ${GREEN}支持${RESET}" || echo -e "  ✗ ALPN:h2: ${RED}未检测到${RESET}"
 [[ $key_supported -eq 0 ]] && echo -e "  ✓ X25519/含x25519密钥: ${GREEN}支持${RESET}" || echo -e "  ✗ X25519/含x25519密钥: ${RED}未检测到${RESET}"
 [[ $ocsp_supported -eq 0 ]] && echo -e "  ✓ OCSP stapling: ${GREEN}成功${RESET}" || echo -e "  ✗ OCSP stapling: ${RED}未检测到${RESET}"
 if [[ $tls_supported -eq 0 && $h2_supported -eq 0 && $key_supported -eq 0 ]]; then
   echo -e "${GREEN}✅ $domain TLS 完全符合要求${RESET}"
 else
   echo -e "${RED}❌ $domain TLS 存在问题,请查看上方具体项${RESET}"
 fi
# ================= CDN 检测 =================
echo -e "------------------------------"
echo -e "🔍 CDN 检测中..."
cdn_flag=0  # 0 = 没有检测到 CDN, 1 = 检测到任意 CDN
cdn_list=() # 保存检测到的 CDN
# 1. Cloudflare trace
CF_TRACE=$(curl -s -m 5 "https://$domain/cdn-cgi/trace")
if [[ "$CF_TRACE" == *"fl="* && "$CF_TRACE" == *"ip="* ]]; then
   echo -e "  Cloudflare detected via /cdn-cgi/trace"
   cdn_flag=1
   cdn_list+=("Cloudflare")
fi
# 2. 获取响应头
HEADERS=$(curl -s -I -m 5 "https://$domain")
# 3. CloudFront
if echo "$HEADERS" | grep -qi "X-Amz-Cf-Id\|X-Cache:.*from cloudfront"; then
   echo -e "  Amazon CloudFront detected via HTTP headers"
   cdn_flag=1
   cdn_list+=("CloudFront")
fi
# 4. Fastly
if echo "$HEADERS" | grep -qi "X-Served-By\|X-Timer\|Via:.*varnish"; then
   echo -e "  Fastly detected via HTTP headers"
   cdn_flag=1
   cdn_list+=("Fastly")
fi
# ===== 彩色输出 CDN 总评 =====
if [[ $cdn_flag -eq 1 ]]; then
   echo -e "${RED}❌ $domain 使用了 CDN: ${cdn_list[*]}${RESET}"
else
   echo -e "${GREEN}✅ $domain 没有检测到 CDN${RESET}"
fi

 # ================= 输出原始信息 =================
 echo -e "------------------------------"
 echo -e "🔍 原始 openssl 输出(供调试):"
 echo "$output" | sed 's/^/  /'
 echo -e "------------------------------"
 echo -e "🔍 原始 HTTP 响应头(供调试):"
 echo "$HEADERS" | sed 's/^/  /'
 echo
}
# 主流程
if [[ $# -eq 0 ]]; then
 echo -e "用法: $0 https://example.com [https://another-site.com ...]"
 exit 1
fi
for url in "$@"; do
 check_url "$url"
done

* 代码大部分由 ChatGPT 生成. 

这三种写法都可以: 

/root/1.sh https://docs.aws.amazon.com/ example.com https://test.com

效果如下: 

 

注意: 根据灵感来源的博文介绍, ocsp stapling 是加分项, 不是必需项! 

==========

使用 Mihomo 内核搭建 VLESS xtls-rprx-vision 的配置代码

使用内核搭建是运行在 Ubuntu 的小鸡上的, 所以开机自启使用系统自带的 serviced 就行, 不细讲了, 把配置粘贴出来, 只粘贴关键配置. 

服务端: 

listeners:
  - name: 起个名字
    type: vless
    port: 443 # 端口随意, 我喜欢用 443, 支持使用ports格式, 例如200,302 or 200,204,401-429,501-503
    listen: 0.0.0.0
    users:
      - username: 1
        uuid: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa #UUID
        flow: xtls-rprx-vision
    reality-config:
      dest: 偷的域名:443
      private-key: 私钥 #可由 mihomo generate reality-keypair 命令生成
      short-id:
        - aaaaaaaa
      server-names:
        - 偷的域名, 不要带冒号和端口号

客户端: 

  - name: vless 节点
    server: 节点 IP 或域名, 如果是 IPv6 不要带 [] 中括号
    port: 443 #上面 port 中的端口号
    ip-version: dual #双栈, 如果你的小鸡只有 IPv6 或者双栈但倾向 IPv4, 请看官方文档
    type: vless
    uuid: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa #UUID
    udp: true
    skip-cert-verify: false
    tls: true
#    dialer-proxy: proxy #可选, 前置代理的意思, 家宽 - proxy - vless 节点 - 谷歌, 类似一个丐版 tor, 可以绕过机场审计, 不知道什么是 dialer-proxy 就把这行注释或删掉
    flow: xtls-rprx-vision
    client-fingerprint: firefox #其它选项请看官方文档, 不建议填写 chrome, 之前出过漏洞
    servername: 偷的域名, 不要带冒号和端口号
    reality-opts: 
      public-key: 私钥对应的公钥 #可由 mihomo generate reality-keypair 命令生成
      short-id: aaaaaaaa

网络上基本没见着有教程用 mihomo 搭建 VLESS xtls-rprx-vision 的, 我喜欢用 Mihomo 内核, 所以就把配置粘贴出来了, 测试正常, 网上基本都是一键脚本, 要不就是写 json, 看着头疼. 

你要自己去找一个域名, 不要用我示例的那三个, 然后用 shell 脚本去测试. 也不要去偷大厂域名, 实测会有断流情况, 一断就是好几分钟...

搭建好测试正常之后, 也要记得去检查一下浏览器是否能正常访问: 用浏览器 检测Reality伪装效果 是否搭建成功 排错Troubleshoot

星期四, 十月 09, 2025

星期六, 九月 20, 2025

189 Lineage crDroid prop 隐藏模块 2 款 reset los props 和 sensitive_props

淘宝已经在 9 月初开始加强了风控, 检测到安卓的 Lineage 系统就会触发一个提示框, 忘了具体是什么了, 好像是禁止访问. 

用的是 crdroid a15, 这个问题导致我没办法使用淘宝了, 淘宝特价版目前还正常. 降回 crdroid a13 的同时, 我安装了 snake-4 写的 reset los props, (这位大佬也是 zygisk assistant 的作者, assistant 和 shamiko 是同样的功能同样的使用方法, 但我感觉更好用) 测试发现, 带 lineage 的参数均已被移除, 但 crdroid 的参数保留, 淘宝测试正常. 以我的 crdroid a13 举例: 

resetprop 是列出当前 prop 各设置项的命令, 所以我使用了 resetprop > /sdcard/1.txt 的命令来输出前后对比效果. 发现 reset los props 删除了以下参数: 

[init.svc.vendor.lineage_health]: [running] -> 删除

[init.svc_debug_pid.vendor.lineage_health]: [进程PID] -> 删除

[ro.boottime.vendor.lineage_health]: [数字] -> 删除

[ro.build.flavor]: [lineage_机型代号-userdebug] -> [ro.build.flavor]: [机型代号-userdebug]

[ro.lineage.build.version.plat.rev]: [0] -> 删除

[ro.lineage.build.version.plat.sdk]: [9] -> 删除

[ro.lineage.device]: [机型代号] -> 删除

[ro.product.bootimage.name]: [lineage-机型代号] -> [ro.product.bootimage.name]: [机型代号]

[ro.product.name]: [lineage_机型代号] -> [ro.product.name]: [机型代号]

[ro.product.odm.name]: [lineage_机型代号] -> [ro.product.odm.name]: [机型代号]

[ro.product.product.name]: [lineage_机型代号] -> [ro.product.product.name]: [机型代号]

[ro.product.system.name]: [lineage_机型代号] -> [ro.product.system.name]: [机型代号]

[ro.product.system_ext.name]: [lineage_机型代号] -> [ro.product.system_ext.name]: [机型代号]

[ro.product.vendor.name]: [lineage_机型代号] -> [ro.product.vendor.name]: [机型代号]

[ro.product.vendor_dlkm.name]: [lineage_机型代号] -> [ro.product.vendor_dlkm.name]: [机型代号]


因为脚本是遍历的, 所以 prop 里面有多少它就改多少. 以上是我这个机型列出来的修改项. 另外作者还修改了: 

resetprop_if_diff ro.boot.flash.locked 1
resetprop_if_diff ro.boot.vbmeta.device_state locked
resetprop_if_diff ro.boot.verifiedbootstate green
resetprop_if_diff ro.boot.veritymode enforcing
resetprop_if_diff vendor.boot.verifiedbootstate green
resetprop_if_diff vendor.boot.vbmeta.device_state locked

但是这些东西对于淘宝以 Lineage 为关键词风控的绕过来说, 意义不大, 而且国内一些银行应用不靠这些参数也能检测出来 root / magisk. 


另外我看到一款, 只是觉得它修改得更全面, 没有实际测试, 安装模块前, 一定要检查源码: 

https://github.com/Magisk-Modules-Alt-Repo/sensitive_props

lineage_ aosp_ 这两个关键词都会删除, 而且其它的参数也比 snake-4 的多一些, 但对于系统配置来说, 多不一定是好事, 我用 snake-4 的已经足够了, 如果你在看到本文时, 测试无效, 可以看看上面 shìwēi nguyen 大佬的版本, 因为简介中说取自 MagiskHide. 

 

记得在开启/关闭模块后, 重启生效. 直接用 MT 管理器执行 sh 脚本应该也行. 

星期日, 九月 07, 2025

188 IPv6 only 服务器上 Mihomo 入站 + 安装 WARP

环境与需求: 

IPv6 only 小鸡, 想上双栈 warp, 同时开放一个 socks5 端口, 用于 Mihomo 连入. warp 不要像 tun 那样来占用我的整个小鸡网络. 

流程: 

目标网站 - warp - socks5 - Mihomo - 机场 - 我的设备 

 

1, 运行脚本

wget -N https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh && bash menu.sh

2, 选

3. 为 IPv6 only 添加 WARP 双栈网络接口
1. wireguard 内核 (默认)
2. 非全局
1. 使用免费账户 (默认)
3. 使用 VPS 初始设置 (默认)

3, 选 13 安装 wireproxy 和进行设置, 最后可能会出错, 会显示如下信息, 看起来像是安装完成, 但是 wget 解析域名的时候解析到了 IPv4 的地址, 所以返回了 Network is unreachable: 

 进度 1/3: 安装系统依赖……

--2025-09-07 09:11:58--  https://github.com/pufferffish/wireproxy/releases/download/v1.0.9/wireproxy_linux_amd64.tar.gz
Resolving github.com (github.com)... 20.205.243.166
Connecting to github.com (github.com)|20.205.243.166|:443... failed: Network is unreachable.
--2025-09-07 09:11:58--  https://gitlab.com/fscarmen/warp/-/raw/main/wireproxy/wireproxy_linux_amd64.tar.gz
Resolving gitlab.com (gitlab.com)... 172.65.251.78
Connecting to gitlab.com (gitlab.com)|172.65.251.78|:443... failed: Network is unreachable.
0% [Working]
gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
0% [Waiting for headers]
 进度 2/3: 已处理好 WARP 配置文件

Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]
Hit:3 http://archive.ubuntu.com/ubuntu jammy-security InRelease
Fetched 128 kB in 8s (16.3 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
157 packages can be upgraded. Run 'apt list --upgradable' to see them.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
openresolv is already the newest version (3.12.0-2).
iptables is already the newest version (1.8.7-1ubuntu5.2).
net-tools is already the newest version (1.60+git20181103.0eebece-1ubuntu5.4).
dnsutils is already the newest version (1:9.18.30-0ubuntu0.22.04.2).
0 upgraded, 0 newly installed, 0 to remove and 157 not upgraded.

 进度 3/3: 寻找 MTU 最优值已完成

 创建快捷 warp 指令成功
 WireProxy 还未安装

4, 直接去下载 wireproxy 的 amd64 包, 放入 /usr/bin/ 下, 给 0755 权限, 注意不是放在 /usr/local/bin/ 里面

https://github.com/whyvl/wireproxy/releases

5, 修改 /etc/wireguard/ 下的各项配置文件, 保证 dns 不为 IPv4. 不然 wireproxy 服务会报错:

journalctl -xeu wireproxy.service


-- Support: http://www.ubuntu.com/support
--
-- A start job for unit wireproxy.service has finished successfully.
--
-- The job identifier is 3900.
Sep 07 09:46:52 HK-LXC wireproxy[13136]: 2025/09/07 09:46:52 lookup engage.cloudflareclient.com on 8.8.8.8:53: dial udp 8.8.8.8:53: connect: network is unreachable
Sep 07 09:46:52 HK-LXC systemd[1]: wireproxy.service: Main process exited, code=exited, status=1/FAILURE
-- Subject: Unit process exited
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- An ExecStart= process belonging to unit wireproxy.service has exited.

修改 warp.conf 底下的 DNS 和 Endpoint 为 IPv6, 改 Endpoint 是因为域名不知道去哪个弱智 IPv4 DNS 请求导致不能解析, 所以就直接写成固定的 IPv6 地址:

DNS = 2606:4700:4700::1001,2606:4700:4700::1111
Endpoint = [2606:4700:d0::a29f:c001]:2408

修改 proxy.conf 底下的 DNS 和 Endpoint 为 IPv6, 如上.

5, 再次执行 warp 命令, 选 2.连接 Wireproxy (warp y) 或者直接执行 warp y

如果还启不来, 看看是否有 wireproxy 的服务:

systemctl list-unit-files | grep wire

如果没有服务, 手动添加一个, 注意从 /lib/systemd/system/wireproxy.service 添加, 不知道为什么, 我记得脚本里就是添加到这了. 注意 MemoryLimit=256M 这个参数, 是我手动加的, 实际使用中发现有 wireproxy 内存泄漏的情况, 1GB 的内存半天就占满失联了, 如果你也有 wireproxy 内存泄漏, 建议将内存限制手动加到 service 文件中. 另外, RemainAfterExit=yes 这个参数也不要, 否则, wireproxy 意外退出了之后 systemd 无感知, 还以为它在运行: 

[Unit]
Description=WireProxy for WARP
After=network.target
Documentation=https://github.com/fscarmen/warp-sh
Documentation=https://github.com/pufferffish/wireproxy
[Service]
ExecStart=/usr/bin/wireproxy -c /etc/wireguard/proxy.conf
Restart=always
MemoryLimit=256M [Install] WantedBy=multi-user.target
systemctl daemon-reload

service 命令如果启动还有报错, 尝试手动运行

/usr/bin/wireproxy -c /etc/wireguard/proxy.conf

可能会看到

2025/09/07 09:59:06 lookup engage.cloudflareclient.com on 8.8.8.8:53: dial udp 8.8.8.8:53: connect: network is unreachable

这样的报错, warp 或者一键脚本擅自修改了 resolv.conf 也就是系统 DNS, 改回 IPv6 的即可, 如

nameserver 2606:4700:4700::1001
nameserver 2606:4700:4700::1111

另外可能有端口占用的问题, 从 netstat -lntpu 会看到哪个进程占用, 干掉端口占用的进程或者用脚本换新的 socks 端口. 


Mihomo 入站只需提一嘴, 会搓配置的人一看就懂

#config.yaml
log-level: silent
ipv6: true
tcp-concurrent: true
listeners:
  - name: myvmess
    type: vmess
    port: 80
    listen: 0.0.0.0
    users:
     - username: 1
       uuid: c441dae3-1176-4640-9c51-666e2f80d92c
       alterId: 0
       udp: true
       cipher: auto
proxies:
  - name: warp
    type: socks5
    server: 127.0.0.1
    port: 1080
    udp: true
dns:
  enable: true
  listen: 127.0.0.1:53
  ipv6: true
  nameserver:
    - https://[2606:4700:4700::1001]:443/dns-query#DIRECT
    - https://[2606:4700:4700::1111]:443/dns-query#DIRECT
  default-nameserver:
    - https://[2606:4700:4700::1001]:443/dns-query#DIRECT
rules:
  - MATCH,warp

注意 proxies 里面 udp 要开, 查看 udp 是否能通, 去 https://networktest.twilio.com/ 网站检测一下就行, 如果 udp: true 忘记写了的话, twilio 里面第一条  NTS: TURN UDP Connectivity 会显示 failed. 

nameserver 我用了 Cloudflare 的两个 doh 来查询, warp 只管和 ip 之间的流量, warp 用的是 udp 53 的传统 dns, 我完全不信任这种协议. 

星期三, 六月 11, 2025

187 使用 header editor 将搜索引擎中的 steam reddit epic play 自带语言参数去除

现在搜索引擎根据搜索关键词的语言爬到带语言参数的链接, 比如 
https://www.reddit.com/abc?hl=zh-Hans
https://store.steampowered.com/abc/?l=tchinese
https://store.epicgames.com/zh-Hant/p/abc
https://play.google.com/abc/abc/?hl=zh_HK

有时候要看英文, 还得去网页里切换语言, 但是它下次从搜索引擎点进来又带链接参数, 就又是目标语言. 这样很烦. 

可能还有别的方法, 但我喜欢使用 header editor 来重定向请求. 如果你熟悉这款插件, 直接复制粘贴规则就可以, 如果你期望能找到更简单的方法, 那么这篇博文不适合. 

Name 起个规则名字
Rule Type 是操作类型, 注意这里是 请求重定向 Redirect request, 而不是 修改请求头 Modify request header.
Match Type 选择第二个, 正则表达式 Regular expression. 
执行类型选常规, 也就是 normal. 
右边可以新建一个组 Save Group
其它的照着填. 

Reddit:
https:\/\/www.reddit.com\/(.*)((tl=zh\-hans)|(tl=zh\-hant))(.*)
https://www.reddit.com/$1$5 

Steam:
https:\/\/store\.steampowered\.com\/(.*)((l=tchinese)|(l=schinese))(.*)
https://store.steampowered.com/$1$5

Epic:
https:\/\/store\.epicgames\.com\/((zh\-CN)|(zh\-Hant))\/p\/(.*)
https://store.epicgames.com/en-US/p/$4

Play: 
https:\/\/play\.google\.com\/(.*)(hl=[a-z]{2}(_[A-Z]{2})?)(.*)
https://play.google.com/$1$4

当然这些正则不一定是最优解, 但我用着还不错, 尤其是 reddit, 机翻看着十分难受, 有时候需要双语对照着翻译, 老美逛论坛用俚语或者开玩笑玩梗的有很多. 

星期五, 四月 25, 2025

186 3D 泳池 手机壁纸 电脑壁纸 下载

 
来源拼多多, 一分钱买的. 都是引流的垃圾商家, 推广字节旗下的悟空浏览器.
图片应该都是拿 ai 生成的, 分辨率很高, 可以自己用画图工具缩放至 30%, 就是正常大小了, 原图链接在博客顶部的链接中. yandex 网盘和 mega 网盘任选一个下载. 因为 yandex 网盘限制 1GB 单文件, 所以分卷了, 三个都要下载, 约 2.67 GB 大小. 不要点 download all 下载打包 zip, 这种方式是单线程, 速度很慢. 另外, 不知道解压的人直接滚出我的博客.
如果此文对你有帮助, 请留下评论, 无需注册.

星期四, 二月 27, 2025

185 Firefox 火狐浏览器 原生 profiles 便携启动

先发我之前用的旧方法, 用 portable.exe 启动 + vbs 脚本将 portable.exe 设置成默认浏览器, 由 portable.exe 接管浏览器的启动. 

Firefox portable.exe: https://portableapps.com/apps/internet/firefox_portable

Firefox vbs 脚本: https://gist.github.com/winhelponline/057064a1dadb3eb9b0aa2b6f05a0331a

(Firefox 可自动升级或手动升级, 不需要离线包)

Chrome portable.exe: https://portableapps.com/apps/internet/google_chrome_portable

Chrome vbs 脚本: https://gist.github.com/winhelponline/5ba152dd99e41a9cd4e1b2eb79085fd5

Chrome 离线包(可解压出 chrome-bin): https://github.com/Bush2021/chrome_installer/releases

这个方法我认为不好, 每次启动依赖 portable.exe 有时候此进程异常会导致从其它软件点链接点不开, 而且浏览器打开的时候后台还会有一个 firefoxportable.exe 监视 firefox.exe 的启动和退出. 所以在网上找了 Firefox 火狐浏览器原生使用 profiles 来进行便携启动的方法.

1, 备份好当前的浏览器数据, 在 %LocalAppData%\mozilla 和 %AppData%\mozilla 里面.

2, 将浏览器数据移动到一个非 C 盘的地方, 比如 D:\Software\Firefox\Data (可选)

3, 浏览器打开 about:profiles 点击 Create a New Profile 按钮 (浏览器是英文的, 按钮就那么几个, 简中的自己找就行) 

4, Enter new profile name 这里给用户起一个名字, 目录就选第二步浏览器数据所在文件夹, 比如 D:\Software\Firefox\Data

5, 如果有 set as default 之类的按钮, 将新的 profile 设置成默认. 其它乱七八糟的 profiles 可以删除+删除文件. 删除之前自己做好备份.

6, 浏览器主程序 firefox.exe 创建快捷方式到桌面, 双击打开即可. 


如果还要多开, 以实现不同用户同时使用浏览器: 

1, 打开 about:profiles 创建多个 profiles, 名字不能相同, 相同不让创建. 比如 名称为 abc.

2, Firefox 主程序 firefox.exe 右键发送快捷方式到桌面, 更改目标为 D:\Software\Firefox\App\firefox.exe -P abc -no-remote

这个 no remote 就是为了防止浏览器识别互斥体, 从而实现不同用户同时使用浏览器, 这里的用户指的是不同的 Firefox 浏览器 profiles, 至于火狐账号, 登不登都无所谓, 看自己喜好. 

 

注意, 不要创建了新的 profiles 目录之后(文件夹为空, 无数据), 再从别的地方把浏览器数据拷过来, 这样的话大量扩展会失效, 因为找不到路径, 直接在创建 profiles 的时候, 指定已经存在的浏览器数据文件夹就行了. 

另外, profiles 的配置存放在 %AppData%\mozilla\firefox\ 底下, installs.ini 和 profiles.ini, 如果想要带着浏览器数据到处走, 这两个文件一并带上, 新电脑上先放好这两个文件才能继续进行下一步.


感觉这个功能做得不如 Chrome 方便.

星期五, 一月 17, 2025

184 Oracle VirtualBox 最后一个能够安装任意目录的版本

今天要在一台新电脑上用虚拟机, 官网下载了最新版的安装包, 发现安装不上, 目录不正确, Invalid installation directory 什么的错误, 网上查了下, 发现是 v7.0.14 以及之前的版本有一个漏洞可以进行提权, 所以它就限制了只能装 C 盘(或者把 C 改成 D 才安装), 要么就是改安全选项卡里的继承权限... 

所以根据攻防社区链接的信息来看, 最后一个能 任意目录安装 virtualbox 的版本是 v7.0.14, 实际测了一下发现确实是这样, 14 的下一个版本是 16, 中间没有 15, 安装 16 的时候就不能选择任意目录了. 

注意了, 本人是个人使用, 平时也就临时用用毒瘤软件, 或者测测可疑的执行文件, 并不是正规生产环境, 如果你是正规生产环境或者安全级别较高的环境, 不要使用旧版本, 再次强调它有提权漏洞.

水一篇博文, SB 龟壳真是越来越厦碧了, 听说它不交 JavaScript 的版权之类的东西, 也被社区骂了, 不过骂没什么用, 屎还是那坨屎 🖕 .

星期二, 一月 14, 2025

183 回退到 Telegram 第一个支持 "引用回复 + 高亮选中的局部文字" 的版本

目前 Telegram 的客户端越来越像史, 安卓端的强制显示官方动态, 全端的送礼物和星星, 频道内容中间穿插的垃圾广告 等等, 所以我有回退到旧版本的需求.

 

支持引用回复+高亮的第一个版本: 

Windows v4.11.2 (https://github.com/telegramdesktop/tdesktop/releases/tag/v4.11.2) 其实 v4.11.1 也可以引用回复, 只是不支持高亮选中的局部文字. 
Android v10.2.0 (https://www.apkmirror.com/apk/telegram-fz-llc/telegram/telegram-10-2-0-release/) 是第一个版本, 而且 引用回复 + 高亮选中的局部文字 两个需求都支持. 

感谢蓝点网 Telegram 版本更新功能及变化的文章, 节省了大量一个个版本安装测试的时间.


如果你只需要图片遮罩, 可以参考互联网上的 Telegram 新闻, 比如这篇:

Telegram 更新, 可以為相片/影片加防劇透特效

星期六, 十二月 21, 2024

182 Firefox 火狐浏览器 清除 console 控制台中的历史执行记录

从 Google Chrome 切到 Mozilla Firefox 已经有一年了, 除了网络异常的错误代码非常沙比以外, 火狐用起来感觉还不错. 

最近碰到一个问题, 由于在 console 控制台下跑了 JavaScript 脚本, 发现无法清除历史记录, 就像 cmd 上下键和 ssh 上下键那样可以直接恢复回来, 很烦. 

网上搜了一下, 开发者们大概在五年前就在烦恼这个问题了, 解决方法也非常简单, 在 console 中执行:

clearHistory()

就这么简单. 

 

感谢以下来源:

https://stackoverflow.com/questions/58021428/delete-firefox-javascript-console-history

https://support.mozilla.org/en-US/questions/1269646

 

星期一, 十二月 09, 2024

181 向日葵插座在 mihomo 内核控制的局域网下无法联网的问题 | override-destination 参数是否需要打开 | 关于 Encrypted Client Hello (ECH) 的一些实际使用经验和见解

最近折腾的东西有点多, 只讲和文章有关的吧, 编译了一个 OpenWrt 包给路由器刷上, 抛弃openclash 这个臃肿的插件, 使用 OpenWrt-mihomo, mihomo 插件需要 OpenWrt >= 23.05, Linux Kernel >= 5.10, firewall4, 我比较懒就直接重装系统了, 新系统是自带插件的. nftables (firewall4) 涉及系统核心防火墙, openclash 又是屎山, 所以升级失败是很正常的.

如标题所说, 向日葵插座和米家设备一样, 需要跳过域名嗅探的. 

根据我的测试, c1pro 型号和 c2 型号(多了个电量显示和电量统计的功能) 是不一样的, c1pro 需要多加一个域名. 

如果是 c1pro 插座, sniffer 这样写:

sniffer:
  enable: true
  force-dns-mapping: true
  parse-pure-ip: true
  override-destination: true
  skip-domain:
    - '+.oray.com'
    - '+.oray.net'

如果是 c2 的, 把 com 域名去掉, 这样写: 

sniffer:
  enable: true
  force-dns-mapping: true
  parse-pure-ip: true
  override-destination: true
  skip-domain:
    - '+.oray.net'
  sniff: #这里我比较激进, 嗅探了所有端口, 以防漏网之鱼
    HTTP:
      ports: [1-65535]
    TLS:
      ports: [1-65535]
    QUIC:
      ports: [1-65535]

为什么 c1pro 的会多一个? 因为在我实际测试中, 如果不加, 在配对的时候添加成功, 但设备重启后无法联网, 在 app 里面就会显示离线. 

另外, 我记得向日葵的插座在通信时连接的不止一个域名, 好像是不定期切换的, 所以我直接用了 +. 来匹配所有, 懒得一个个添加了, 不然三天两头离线. 


如果关闭 override-destination 其实也行, 但我为了防止漏网之鱼, 尤其是伪造域名 sni 请求(比如 cloudflare+浏览器doh 组合而成的 Encrypted Client Hello (ECH), 其实原理也是伪造一个 sni 是 cloudflare-ech.com 有没有子域名具体忘记了, 这样的话, 如果我开启 override, 我的 mihomo 内核就成了一个内网的"墙", 伪造域名的网就不通, 一定程度上拦截了伪造域名, 主要是防国内毒瘤), 所以就打开了. 

提到了 ECH, 那就再讲讲目前 ECH 的实际使用形式, 截至我发文的 2024年12月9号, 必须是浏览器打开 DNS over HTTPS ( DoH ), 然后才能在开启 ECH 功能的网站上使用, 墙看到的就是一个固定的域名(目前是这样的), cloudflare-ech.com, 那这个特征也非常明显, 不排除以后墙掉. 说是 Encrypted 我是质疑的, 这其实是伪造, 和 vless + xtls-rprx-vision 那种伪造是一样的. 只不过后者是个代理协议, 能指定伪装域名罢了. 我测试过, 不能以在路由器上使用 doh 的形式形成 ech, 哪怕是在使用的电脑上设置一个 AdguardHome 服务, 再让它去请求 doh 服务器也不行. 必须是浏览器本身. Google Chrome 或者 Mozilla Firefox 都可以, 中间不能有中介. 如果你的上网环境没有 Mihomo 的保护, 那这个 ech 算是一种保护的手段, 即使不要 ech 只用 doh 也是很好的保护, 但我在局域网内的设备是有去广告和阻止数据收集的需求的, 综上所述, 我选择 override-destination: true 以及不用 Encrypted Client Hello.

星期四, 十月 17, 2024

180 Telegram 养号日记

忘了在哪听说 DC1 的号很容易死, 所以想注册一个 DC1 区的账号. 打算注册后自己日常使用.

2024-09-30 02:31:51, 在 sms-activate 上使用美国真实号码接码注册, 期间私聊了一个检测 dc 区的机器人, 添加了我的大号并互为好友, 并用大号发了消息, 小号回了消息. 二十几分钟就死了. 

2024-10-02 02:10:39 买了一个成品号. 在 sms-activate 的 Ready made accounts 模块下, 购买了合作商 hStock 平台上商家的成品号(直接去 hstock 买或者多选几家这种交易平台货比多家其实也行, 那样更好, 因为我在 sms-activate 有余额不想浪费钱, 所以就以贵一倍的价格买了),  "Canadian Telegram account, including 2fa+session+tdata+json". 
首登信息也就是 session 如下:
Meizu PRO 7 Plus
Application: Telegram Android 10.15.1
System version: 12 (31)
Location: Toronto, Canada, 2024/9/29 at 20:29
二登信息如下:
****(计算机设备名)
Application: Telegram Desktop 5.5.5 x64
System version: Windows 10
Location: ****, Hong Kong, 2024/10/2 at 02:15
三登信息如下:
****(我的某台常用实体安卓手机, 上面登了两个老号, 是一个客户端同时登三个号, 没有多开或分身)
Application: Telegram Android 10.14.0
System version: 13 (33)
Location: ****, Hong Kong, 2024/10/10 at 4:24 (我的 IPv4 和 IPv6 均为代理地址, 是固定的, 二登和三登期间无 IP 变化, 此 IPv4 和 IPv6 地址上还有我的另外两个大号, 日常使用. 另外, 此手机+此双栈 IP 地址上还死过两个 dc1 账号)

哪个时间点干了什么事, 我都会非常详细地写在下面, 如果没写就是没做. 

时间线和流水账:  
2024-10-02 ~02:15, 二登. 改 2FA 密码. (用户名有, 卖号的早就设置好了, 我没动它) 设置了头像、自我介绍. 随便翻了翻设置, 没动. 
期间, 置顶了"收藏夹", 偶尔打开看一下, 然后点 X 关掉, 收进系统托盘(桌面右下角托盘图标). 
2024-10-04 ~16:00, 设置了姓名、退出了电脑版(没有退账号, 只是 Windows 版客户端右键托盘图标的退出), 于 18:24 重新打开.
期间, 时间过了八天, 依旧是偶尔打开看一下, 然后点 X 关掉. 
2024-10-10 04:24, 三登. 三登时安卓客户端要求我必须设置邮箱(注意这里的设置邮箱不是两步验证邮箱), 即这个账号以后是主邮箱号, 而非手机号. 随后收应用内验证码登录成功. 将 隐私 - 谁可以看见我的手机号码 设置为 "不允许任何人", 谁可以通过手机号码找到我 设置为 "我的联系人", 出生日期 设置为 "不允许任何人", "同步通讯录" 在三登时就未开启. 在安卓端搜索 durov 并关注了他的频道, 往上翻了翻频道动态. 在 Windows 端也翻了翻频道动态. 
期间, Windows 端长期挂着, 依旧是偶尔打开看一下, 往上翻翻 durov 的频道动态, 然后点 X 关掉. Android 端日常使用两个大号, 小号偶尔切过来看一下, 同样往上翻 durov 的频道动态. 
2024-10-17 05:38, 换绑手机为 英国某实体卡. 将最早的首登 session 踢下线. 修改了自动终止旧会话的时间为 "3个月". 设置了两步验证邮箱.
2024-10-21 05:35, DC5 大号主动添加其为联系人, 并在 windows 客户端上也添加了 DC5 大号为联系人, 互发了一条消息.
2024-11-01 05:45 使用 @where_is_my_dc_bot 机器人, 并发送自己手机里的一张下载的图片, 来检测自己所在的 DC 区. 返回 DC1 Miami, Florida, United States. (注意, 发图片不要发贴纸 Sticker, 否则会返回错误的地区)
2024-11-05 01:22, 由于把 tdata 误删除, 在二登设备上重新再用 应用内验证码 登录. 登录成功. 随后用手机把之前旧的二登 session 终止会话了. 

 

至此, Telegram 养号我认为就已经完成了, 由于我的大号关注了很多频道, 打算于 2025 年 1 月再操作大批量关注的事情, 并且将会以每天关注 10 个的进度进行. 如果账号正常, 此文将不再更新.


卖号的提供的 Windows 版 tdata 为最简结构, 有这些文件就可以双击打开即可自动登录: 

📂tdata
 ├─📂账号十六位, 16 进制字母数字
 │    └─📄maps
 ├─📄key_datas
 └─📄账号十六位后面跟 s

如果你也追求极简, 日常需要数据迁移时, 带着这些文件走即可. 

==============

又买了一个 DC2 的小号, 懒得记录详细日志了, 说下关键操作. 

2024-11-01 卖家机器注册+2FA启用, 位置 里斯顿-维吉尼亚州-美国, 首登登录机器 win7.
2024-11-02 卖家 tdata 二登登录, 2FA改密码, 位置 巴格达-伊拉克.
2024-11-05 我买到手, tdata 三登, 改名字改头像, 改用户名, 改2FA密码. 位置 香港.
2024-11-07 @where_is_my_dc_bot 检测自己账号所在区, 为 DC2, 属实. 关注 durov 的频道.
2024-11-08 苹果手机四登, 安卓手机五登, 位置为同一 IP 的香港.
2024-11-10 安卓手机上改绑定的手机号为实体手机号.
2024-11-11 大号主动加其联系人并私聊, 小号同时也加大号. 
2024-12-09 没问题, 号没死, 长期在线. 偶尔点开看一眼. 此号同上面那个号一样, 打算于 2025 年 1 月再操作大批量关注的事情, 并且将会以每天关注 10 个的进度进行. 如果账号正常, 此文将不再更新.

现在 DC 1245 都集齐了^_^ (DC3 早已关闭)

星期三, 九月 04, 2024

179 JavaScript 书签, 生成指定位数随机字符密码, 并自动复制到剪贴板

为什么没有用 Bitwarden 自带的密码生成功能呢? 因为这货会存储在历史记录里, 每次还得去清除掉 :'( 


需求和 Bitwarden 一样, 生成一个 18 位的密码(这个可以自己调整), 要求如下:

  • A-Z  (I O 除外, 因为它们容易和 小字母l 和 数字0 混淆)
  • a-z
  • 0-9
  • !?@+-*/=  (这些是手机上常见的符号, 没有加上 # 号是因为 Firefox 有个 Bug, 包含 # 后面的代码中的空格会被转换成 %20, 使用上没影响但是跨浏览器不方便, 所以就把 # 去掉了, 这个 Bug 在 Chrome 上不存在)
  • 这四组必须都要出现至少一次 (也就是说, 密码必定是包含 大小写字母、数字、特殊符号)
  • 点击书签即可生成, 并自动复制到剪贴板中


可读版本:

javascript: (function() {
    function shuffle(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]];
        }
        return array;
    }
    function generatePassword() {
        const lowerCharset = "abcdefghijklmnopqrstuvwxyz";
        const upperCharset = "ABCDEFGHJKLMNPQRSTUVWXYZ";
        const numberCharset = "0123456789";
        const specialCharset = "!?@+-*/=";
        const allCharset = lowerCharset + upperCharset + numberCharset + specialCharset;
        let password = [lowerCharset[Math.floor(Math.random() * lowerCharset.length)], upperCharset[Math.floor(Math.random() * upperCharset.length)], numberCharset[Math.floor(Math.random() * numberCharset.length)], specialCharset[Math.floor(Math.random() * specialCharset.length)]];
        for (let i = 4; i < 18; i++) {
            password.push(allCharset[Math.floor(Math.random() * allCharset.length)]);
        }
        return shuffle(password).join('');
    }
    const password = generatePassword();
    const textBox = document.createElement("textarea");
    textBox.value = password;
    document.body.appendChild(textBox);
    textBox.select();
    document.execCommand("copy");
    document.body.removeChild(textBox);
    alert(password);
})();


压缩版本:

javascript:(function(){function shuffle(array){for(let i=array.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[array[i],array[j]]=[array[j],array[i]];}return array;}function generatePassword(){const lowerCharset="abcdefghijklmnopqrstuvwxyz";const upperCharset="ABCDEFGHJKLMNPQRSTUVWXYZ";const numberCharset="0123456789";const specialCharset="!?@+-*/=";const allCharset=lowerCharset+upperCharset+numberCharset+specialCharset;let password=[lowerCharset[Math.floor(Math.random()*lowerCharset.length)],upperCharset[Math.floor(Math.random()*upperCharset.length)],numberCharset[Math.floor(Math.random()*numberCharset.length)],specialCharset[Math.floor(Math.random()*specialCharset.length)]];for(let i=4;i<18;i++){password.push(allCharset[Math.floor(Math.random()*allCharset.length)]);}return shuffle(password).join('');}const password=generatePassword();const textBox=document.createElement("textarea");textBox.value=password;document.body.appendChild(textBox);textBox.select();document.execCommand("copy");document.body.removeChild(textBox);alert(password);})();


注意, 存为书签使用的 JavaScript 脚本不能有注释, 至少 Firefox 不能有, 不然 // 后面的代码会被 urlencode 掉. 

存成书签, 需要使用的时候点击一下就行了, 截至发文之时, Firefox 可以在扩展页内使用(比如 moz-extension:// 或者某个扩展的新标签页), Chrome 必须在正常网页中使用(比如 https:// http://网站).

代码由 ChatGPT 生成, 版本为免费用户的 GPT-4o.

星期二, 八月 06, 2024

178 mihomo (clash meta) 内核在访问 gstatic.com 和 googleapis.com 非大陆域名 / IP 走 DIRECT 直连 的问题

一直使用 openclash + mihomo (原 clash meta) 内核运行在路由器上, 最近似乎规则有些问题, 谷歌的 cdn 总是直连. 过一会又发现它在走代理, 而且基本都是这几个域名: 

ssl.gstatic.com
www.gstatic.com
*.googleapis.com

最早怀疑是 IPv6 的问题, 因为我最近把它打开了, 后面发现不是. 

然后是怀疑 geoip 出了问题, 我用的是 https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-only-cn-private.dat 这个只有 cn 和 private 的 dat, 关键代码如下: 

geodata-mode: true
geox-url:
   geoip: "https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-only-cn-private.dat"
   geosite: ~
   mmdb: ~
   asn: ~

因为它是 dat, 内容不可见, 我就换成了纯文本的 ipcidr + rule-set 的形式, 这种规则的好处是, ip 段可见, 方便排查. 代码如下: 

rule-providers:
  CN4:
    type: http
    path: cn4.txt
    url: "https://raw.githubusercontent.com/gaoyifan/china-operator-ip/ip-lists/china.txt"
    interval: 604800
    proxy: Tunnels
    behavior: ipcidr
    format: text

  CN6:
    type: http
    path: cn6.txt
    url: "https://raw.githubusercontent.com/gaoyifan/china-operator-ip/ip-lists/china6.txt"
    interval: 604800
    proxy: Tunnels
    behavior: ipcidr
    format: text
rules:
  - IP-CIDR,255.255.255.255/32,REJECT
  - IP-CIDR6,ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128,REJECT
  - GEOIP,PRIVATE,DIRECT
  - RULE-SET,CN4,DIRECT
  - RULE-SET,CN6,DIRECT
  - MATCH,Tunnels

像上面这样的配置, 跑了几天, 依旧不行, 有时候使用谷歌正常, 也有时候浏览器在转, 一转我就知道这二币又去直连了:

然而我的 ipv4 段里面, 根本没有 172.217.31.10: 

172.81.192.0/18 = 172.81.192.0 - 172.81.255.255

那特码的就怪了, 没有规则你凭什么匹配成 DIRECT 直连? 排查过 openclash 的运行配置, 和我写的 rules 一样, 就那么几条, 没有加别的.

后来被折腾得烦了, 直接上 rule-set 看看吧, 于是就多加了一段,  代码如下: 

rule-providers:
  GOOGLE:
    type: http
    path: google.yaml
    url: "https://******/google.yaml"  #配置在下面, 自己简单写的, 本地加载的话上面改成 type:file 具体看配置手册
    interval: 604800
    proxy: Tunnels
    behavior: classical
    format: yaml
rules:
  - IP-CIDR,255.255.255.255/32,REJECT
  - IP-CIDR6,ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128,REJECT
  - GEOIP,PRIVATE,DIRECT
  - RULE-SET,GOOGLE,Tunnels
  - RULE-SET,CN4,DIRECT
  - RULE-SET,CN6,DIRECT
  - MATCH,Tunnels

写在了 cn4 和 cn6 (或者是 geoip,cn) 的上面, 观察了几天, 问题解决了, 那几个撒币域名解析的香港地址也不直连了... 注意, 不要加 no-resolve, 因为这些 IP 大部分是由域名解析过来的, 哪怕是拦截用的 255 和 fffff 也是一样. 

以下是谷歌配置 google.yaml: 

payload:
  - DOMAIN-SUFFIX,ytimg.com
  - DOMAIN-SUFFIX,amp.dev
  - DOMAIN-SUFFIX,android.com
  - DOMAIN-SUFFIX,api.ai
  - DOMAIN-SUFFIX,app-measurement.com
  - DOMAIN-SUFFIX,app-measurement.net
  - DOMAIN-SUFFIX,appspot.com
  - DOMAIN-SUFFIX,material.io
  - DOMAIN-SUFFIX,recaptcha.net
  - DOMAIN-SUFFIX,gstatic.com
  - DOMAIN-SUFFIX,google.com
  - DOMAIN-SUFFIX,googleapis.com
  - DOMAIN-SUFFIX,g.co
  - DOMAIN-SUFFIX,flutter.dev
  - DOMAIN-SUFFIX,flutterapp.com
  - DOMAIN-SUFFIX,firebaseapp.com
  - DOMAIN-SUFFIX,firebaseio.com
  - DOMAIN-SUFFIX,blogspot.com
  - DOMAIN-SUFFIX,youtube.com
  - DOMAIN-SUFFIX,youtu.be
  - DOMAIN-SUFFIX,g.co
  - DOMAIN-SUFFIX,withgoogle.com
  - DOMAIN-SUFFIX,googleusercontent.com
  - DOMAIN-SUFFIX,ggpht.com
  - DOMAIN-SUFFIX,googlevideo.com
  - DOMAIN-KEYWORD,gvt
  - DOMAIN-KEYWORD,ampproject
  - DOMAIN-REGEX,^gvt\d\.com
  - DOMAIN-REGEX,^.*\.goog

以上是我根据自己的使用习惯和需求写的, 参考了 https://github.com/blackmatrix7/ios_rule_script/blob/master/rule/Clash/Google/Google_No_Resolve.yaml 但没有完全使用, blackmatrix 作者的这个版本算是懒人配置, 里面还有 cn 域名. 我为了防止自己的服务器送中, 把所有谷歌大陆域名都屏蔽掉了, 还有一些广告域名也是. 规则这个东西, 千人千面, 根据自己的需求来我觉得最好不过了. 

对了, 上面的规则里有正则 DOMAIN-REGEX, ≤1.18.1 的版本是用不了的. 发布博文时, 使用的版本是 1.18.7

星期六, 四月 20, 2024

177 解决 安卓电视盒子 开机后无法联网 的问题

早先买了一个 HK1RBOX R2 安卓电视盒子, 这种外贸盒子的优点是, 任意安卓软件都可以装, 相对电视板载芯片而言, 配置较高, 可以单独换, 电视只当显示器即可. 系统版本还是 a11 的 armv8. 


(不得不提一嘴, 有的安卓盒子芯片是 armv8 的, 但系统不是, 这就 tm 的很草丹了, 比如 魔百盒九联UNT413A 这一款, 一定一定要避雷. 你想想你的电脑, win10 装个 32 位, 肯定不利于以后扩展, 国内应用商店这几年都强制 64 位应用了, 过两年你买这么个破 armv7 系统的盒子就没法装软件了... 系统倒是有 root 但刷机不好刷, 且懒得折腾)


前几天折腾 AdguardHome, 精简掉了一些自己写的规则, 晚上就发现我的电视盒子就连不上网了... 有域名请求, 但就是连不上, 试过: 

1, 卸载重装 adguardhome luci-app, 不行

2, 卸载重装 openclash, 不行

3, 重置路由器设置重新配置, 不行

4, 重置安卓盒子的系统, 不行

5, fakeip 或 redirhost 外加 udp-tun (混合模式), 不行

起初以为是 mihomo (meta) 内核的 fakeip 问题, 最后排查了也不是... 特码的, 局域网里其它设备都能正常联网, 就这破玩意不行...


这时候已经折腾了五个小时, 突然在 metacubex 面板中发现, 家里的一台傻逼苹果设备, 一直在连接 time.apple.com, 几乎是每分钟都有一条新连接, 于是按照这个方向去查了查, 然后才想起来, 之前在精简规则的时候, 把常用 ntp 重定向到阿里云 ntp 的规则删了, 就是这条: 

/(\S*pool\.ntp\.org)|(ntp\.ubuntu\.com)|(\S*nist\.gov)|(time\.cloudflare\.com)|(time[0-9]*\.apple\.com)|(time[0-9]*\.google\.\S*)|(time[0-9]*\.android\.com)|(\S*\.stdtime\.gov\.tw)|(time\.windows\.com)/$dnsrewrite=NOERROR;CNAME;ntp1.aliyun.com

但是我 udp 特码的没有问题啊, discord 网页版, 还有 webrtc 测试, 都是好的... 


也不知道为什么, 总之加上重定向了之后, 就稀里糊涂地把问题解决了.

那为什么时间校准服务影响了盒子联网? 我觉得这类 sb 盒子都是一个德性, 时间校准后, 系统才能 "激活", 一位博主也碰到了同样的问题: 

https://www.monoko.jp/androidtv-activate-online/

感谢这篇文章

星期五, 十二月 29, 2023

176 CCTV 央视视频 获取 m3u8

截至发文之日, 一年之后的 2024年12月21号, 依旧是没有绿屏现象的.

JavaScript: jQuery.getJSON("https://vdn.apps.cntv.cn/api/getHttpVideoInfo.do?pid=" + guid,

function(result) {

    var content = result.hls_url.link(result.hls_url);

    var match = content.match(/<a href="(.*?)">.*?<\/a>/);

    if (match && match.length === 2) {

        var fullUrl = match[1];

        var modifiedUrl = fullUrl.replace(/maxbr=\d+/, 'maxbr=2000');

        var textarea = document.createElement("textarea");

        textarea.value = modifiedUrl;

        document.body.appendChild(textarea);

        textarea.select();

        var successful = document.execCommand("copy");

        document.body.removeChild(textarea);

        if (successful) {

            console.log("文本已成功复制到剪贴板")

        } else {

            console.error("无法复制文本到剪贴板")

        }

        console.log(modifiedUrl)

    } else {

        console.log('error')

    }

});


在 console 里粘贴此代码回车. m3u8 地址会自动粘贴至剪贴板, 感谢 google bard 的帮助. 
根据 网上的方法 修改而来