两种方式,让 RSSHub 用上 WARP

看了 Diygod 的新文章 优雅使用 Cloudflare WARP 应对 RSSHub 反爬难题 - DIYgod,十分激动,开始折腾,给自己的实例上 WARP,但是用了和他不太一样的方法,使用了宿主机开 socks 代理供 Docker 容器使用的方法。

本文适用于使用 docker run / docker compose 搭建的 RSSHub,以 docker compose 为例演示。

来自 DIYgod:

为什么要用 WARP ?

在开发 RSSHub 的几年中,我发现提供公共 API 的站点非常少,许多站点还会采取严格的反爬控制来限制其平台内容的获取。有些站点会屏蔽同一 IP 发出过多请求,而还有一些站点则会全面屏蔽常见云服务器厂商的 IP 地址。因此,仅仅为了获取最新几条内容更新却变得非常困难。

这种情况需要使用代理,但是专门的爬虫代理通常价格昂贵,性价比极低,如果 Cloudflare WARP 的无限流量和丰富的 IP 资源能被 RSSHub 利用就太棒了。RSSHub 已经支持了通用的代理协议,只要能将 WARP 包装为通用的 proxy 就可以。

本人对 proxy 的理解很浅,基本上本文的内容都是试出来的。如有可以改善的地方,请评论指正。

我原本写过一篇部署 RSSHub(以及 Miniflux)的文章:自建 RSSHub 与 Miniflux | Yunfi’s Blog

还写过一篇关于 RSS 的总览:RSS: 是什么?为什么?怎么用? | Yunfi’s Blog

如果还不会用 Docker 搭建应用,可以看看这篇,以 Nginx Proxy Manager 为例演示了从安装 Docker 到反向代理的全过程:Docker 系列前置技能:用 Nginx Proxy Manager 可视化管理 Nginx

有兴趣的看官可以去看看。

2023/08/26 更新:解决安全性问题

方法区别

官方方案使用 Docker 部署。

我使用的是 fscarmen/warp 这个项目的一键脚本,实际上调用了 pufferffish/wireproxy 来生成 SOCKS 代理。

对比Docker 方法脚本方法
优点简单方便,只要更新一下 compose 文件即可更灵活,可以更方便的使用 WARP+ 和团队版;可以优选 endpoint
缺点使用自定义配置较为麻烦(要自己写两个文件)直接在宿主机上操作,略显麻烦

总的来说,Docker 方案在于方便,脚本方法在于灵活。而且脚本还可以用来干其他事情,比如刷 WARP+ 的流量。

直接采用从官方仓库下载的 docker-compose.yml 的话,不再同一个 compose 里的其他 Docker 应用将不能使用该容器提供的 WARP。需要稍作修改。

由于 WARP 免费版与其他版本速度区别不大,使用 Docker 部署可能是更好的方法,但是我还是用的一键脚本的方案,因为我本来一直就用这个😂而且防火墙设置起来也相对方便一些。

Docker 版部署

快速部署

DIYgod 已经把添加了 WARP 的 docker-compose.yml 放到 RSSHub 的 main 仓库底下了,如果想直接用的话,直接按照文档 部署 | RSSHub 里的操作即可。

但是这样有两个不足之处,如果想要克服这两个问题,可以看下面的高级设置部分:

  1. 只有在同一个 compose 文件里的服务才能访问该代理。
  2. 只能使用默认的免费 WARP 账号。

值得注意的是,直接提供的 docker-compose.yml 使用的是一种更为占空间和内存的方法,可以按照文件中的注释操作,也可以直接复制一下的 yaml:

version: "3.9"

services:
  rsshub:
    image: diygod/rsshub:chromium-bundled
    restart: always
    ports:
      - "1200:1200"
    environment:
      NODE_ENV: production
      CACHE_TYPE: redis
      REDIS_URL: "redis://redis:6379/"
      PROXY_URI: "socks5h://warp-socks:9091"
      # add other environment variables below
    depends_on:
      - redis

  redis:
    image: redis:alpine
    restart: always
    volumes:
      - redis-data:/data

  warp-socks:
    image: monius/docker-warp-socks:latest
    privileged: true
    volumes:
      - /lib/modules:/lib/modules
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    sysctls:
      net.ipv6.conf.all.disable_ipv6: 0
      net.ipv4.conf.all.src_valid_mark: 1
    healthcheck:
      test: ["CMD", "curl", "-f", "https://www.cloudflare.com/cdn-cgi/trace"]
      interval: 30s
      timeout: 10s
      retries: 5

volumes:
  redis-data:

高级设置

对于上面提到的问题 1,可以添加 ports,~~但是可能会带来安全隐患(详见文末)(已经解决)~~通过把 ports 设置到 172.17.0.1 和 127.0.0.1 可以让本机应用和其他 Docker 容器访问,而其他来源 IP 不行;

对于问题 2,可以挂载自己的 conf 文件,相对复杂。

可以修改 warp-socks 部分为:(注意缩进)

  warp-socks:
    image: monius/docker-warp-socks:latest
    privileged: true
    ports:
      - "172.17.0.1:9091:9091"
      - "127.0.0.1:9091:9091" #solve problem 1
    volumes:
      - /lib/modules:/lib/modules
      - ./wireguard:/opt:ro # solve problem 2
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    sysctls:
      net.ipv6.conf.all.disable_ipv6: 0
      net.ipv4.conf.all.src_valid_mark: 1
    healthcheck:
      test: ["CMD", "curl", "-f", "https://www.cloudflare.com/cdn-cgi/trace"]
      interval: 30s
      timeout: 10s
      retries: 5

需要在 compose 文件同目录下新建一个 wireguard 文件夹,其中放入 wgcf-profile.confdanted.conf(可选)。

以下是 wgcf-profile.conf 文件的一个示例,如果自己有这些值的话(比如折腾过 Surge/Loon 等软件的 WARP),照猫画虎填进去即可;如果还没有的话,可以试着用 ViRb3/wgcf 生成一个(如果没有 WARP+ 或者团队版的就算了,会自动生成免费版,把 - ./wireguard:/opt:ro # solve problem 2 这行注释掉即可)

[Interface]
PrivateKey = SNbsrC3W7PAcIvcdUUgqdRKBjOuUby1VPtDurefGJns=
DNS = 1.1.1.1
DNS = 1.0.0.1
Address = 172.16.0.2
Address = fd01:5ca1:ab1e:815a:634d:1529:f7a0:8f32

[Peer]
PublicKey = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=
AllowedIPs = 0.0.0.0/0
AllowedIPs = ::/0
Endpoint = engage.cloudflareclient.com:2408

注意:文档里是把这两个文件挂载到 /opt/wireguard/ 下,我实测不行;DIYgod 在评论里说他看源码访问的是 /opt/ 下的这两个文件,我就这么写了,还没有实测,有问题评论踢我。

为了方便一键复制,将 [ 暴露端口 | 不使用自定义配置 | 设置了容器名称 ] 的 docker-compose.yml 贴一份在下面,也可以直接 wget 下载我放在 gist 里的。

wget https://gist.githubusercontent.com/yy4382/4f78b860fef29a7878e03a8a886a7367/raw/docker-compose.yml
version: "3.9"
# https://gist.githubusercontent.com/yy4382/4f78b860fef29a7878e03a8a886a7367/raw/docker-compose.yml
services:
  rsshub:
    image: diygod/rsshub:chromium-bundled
    restart: always
    container_name: rsshub-app
    ports:
      - "1200:1200"
    environment:
      NODE_ENV: production
      CACHE_TYPE: redis
      REDIS_URL: "redis://redis:6379/"
      PROXY_URI: "socks5h://warp-socks:9091"
      # add other environment variables below
    depends_on:
      - redis

  redis:
    image: redis:alpine
    container_name: rsshub-redis
    restart: always
    volumes:
      - redis-data:/data

  warp-socks:
    image: monius/docker-warp-socks:latest
    container_name: rsshub-warp
    privileged: true
    ports:
      - "172.17.0.1:9091:9091"
      - "127.0.0.1:9091:9091"
    volumes:
      - /lib/modules:/lib/modules
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    sysctls:
      net.ipv6.conf.all.disable_ipv6: 0
      net.ipv4.conf.all.src_valid_mark: 1
    healthcheck:
      test: ["CMD", "curl", "-f", "https://www.cloudflare.com/cdn-cgi/trace"]
      interval: 30s
      timeout: 10s
      retries: 5

volumes:
  redis-data:

使用一键脚本版部署

原理是生成一个 SOCKS 代理,然后让 RSSHub 使用这个代理。

使用项目 fscarmen/warp ,可以通过 WARP Linux Client 或者第三方项目 pufferffish/wireproxy 生成代理。

WARP Linux Clientwireproxy
免费版支持✅支持✅
WARP+支持✅支持✅
WARP Teams不支持❌支持✅
生成 0.0.0.0 的 SOCKS不支持❌支持✅,需要修改配置文件

WARP+ 需要 licence,Teams 有四种认证方案,具体参考原项目 README.md

生成代理

由于目前只有 wireproxy 可以生成 0.0.0.0:40000 的 socks,所以采用该方案。(关于 Client 的问题可以看 这个issue)

如果使用 WARP Client,则需要将 RSSHub 的网络模式改为 host,这又会影响到与 Redis 的连接,又要再花一翻功夫设置,不推荐。

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

按流程走,记下设置的端口,本文中以默认端口 40000 为例

第一次运行后,使用 warp 命令和 warp h 可以唤起两个不同的帮助列表,建议看一看。

修改代理访问权限

生成的代理是只允许 localhost 访问,而来自 Docker 容器的访问在本机看来并不是 localhost,所以需要更改。

打开 /etc/wireguard/proxy.conf,将

[Socks5]
BindAddress = 127.0.0.1:40000

改为:

[Socks5]
BindAddress = 0.0.0.0:40000

让 RSSHub 使用代理

打开老版的 docker-compose.yml,添加这一行:

PROXY_URI: 'socks://172.17.0.1:40000'

其中的 172.17.0.1 是 docker0 的 ip,一般都是这个,不放心可以运行 ip addr show docker0 看一看有没有 inet 172.17.0.1/16 这种。

完整的文件如下:

version: "3.9"

services:
  rsshub:
    image: diygod/rsshub:chromium-bundled
    restart: always
    ports:
      - "1200:1200"
    environment:
      NODE_ENV: production
      CACHE_TYPE: redis
      REDIS_URL: "redis://redis:6379/"
      PROXY_URI: "socks://172.17.0.1:40000"
      # add other environment variables below
    depends_on:
      - redis

  redis:
    image: redis:alpine
    restart: always
    volumes:
      - redis-data:/data

volumes:
  redis-data:

然后再 docker compose up -d 即可。

安全性改进

因为代理监听 0.0.0.0,有很大的安全隐患,任何知道服务器 ip 的人都可以使用这个代理。

如果你的服务提供商提供了额外的一层防火墙,如腾讯云、阿里云、AWS、hz 之类,那最好不过,只要保证它们的面板那里 9091/40000 端口关着。

而对于一些小 VPS 供应商,事情变得没那么简单,需要设置好防火墙规则,只让 docker 访问 40000 端口即可,以 ufw 为例:

sudo ufw allow from 172.17.0.0/16

尾声

其实我的 VPS 的 IP 还不错,还没有遇见被哪个网站反爬了,搞这个主要是折腾一下。

中途也遇到了不少问题,也走了一些弯路,但最终还是搞出来了。

感谢这些项目的作者和 RSSHub 群友的指导。

题外话

我最初接触 WARP 是在年初的时候为了把它提取到 Surge 里,用来解锁 ChatGPT。如果你对通过 Surge 使用 WARP 或者 注册获得团队版 WARP 感兴趣,可以看看我当时看的两篇教程:

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3