Yunfi

Yunfi

tg_channel
github
email

兩種方式,讓 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 感興趣,可以看看我當時看的兩篇教程:


本文採用 CC BY-NC-SA 4.0 許可協議
可以在我的 Hexo 博客閱讀 本文
也可以看看這個 Page 來選擇關注我各方面的更新

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。