两种方式，让 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里的操作即可。

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

只有在同一个 compose 文件里的服务才能访问该代理。

只能使用默认的免费 WARP 账号。

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

Copy
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 部分为：（注意缩进）

Copy
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.conf 和 danted.conf（可选）。

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

Copy
[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 里的。

Copy
wget https://gist.githubusercontent.com/yy4382/4f78b860fef29a7878e03a8a886a7367/raw/docker-compose.yml

Copy
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 Client | wireproxy
免费版 | 支持✅ | 支持✅
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 的连接，又要再花一翻功夫设置，不推荐。

Copy
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，将

Copy
[Socks5]
BindAddress = 127.0.0.1:40000

改为：

Copy
[Socks5]
BindAddress = 0.0.0.0:40000

让 RSSHub 使用代理

打开老版的 docker-compose.yml，添加这一行：

Copy
PROXY_URI: 'socks://172.17.0.1:40000'

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

完整的文件如下：

Copy
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 为例：

Copy
sudo ufw allow from 172.17.0.0/16

尾声

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

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

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

题外话：

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

注册 Cloudflare 并加入 ZeroTrust 教程

Zero Trust 从入门到放弃

本文采用 CC BY-NC-SA 4.0 许可协议
可以在我的 Hexo 博客阅读 本文
也可以看看这个 Page 来选择关注我各方面的更新