本文使用“署名-非商业性使用-相同方式共享 4.0 国际(CC BY-NC-SA 4.0)”进行许可。
商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接。 如果您再混合、转换或者基于本作品进行创作,您必须基于相同的协议分发您贡献的作品。
看了 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 部署可能是更好的方法,但是我还是用的一键脚本的方案,因为我本来一直就用这个😂而且防火墙设置起来也相对方便一些。
DIYgod 已经把添加了 WARP 的 docker-compose.yml 放到 RSSHub 的 main 仓库底下了,如果想直接用的话,直接按照文档 部署 | RSSHub 里的操作即可。
但是这样有两个不足之处,如果想要克服这两个问题,可以看下面的高级设置部分:
值得注意的是,直接提供的 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.conf
和 danted.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 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 的连接,又要再花一翻功夫设置,不推荐。
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
打开老版的 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 感兴趣,可以看看我当时看的两篇教程:
本文使用“署名-非商业性使用-相同方式共享 4.0 国际(CC BY-NC-SA 4.0)”进行许可。
商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接。 如果您再混合、转换或者基于本作品进行创作,您必须基于相同的协议分发您贡献的作品。