分享一下我的 RSS 方案

最近把之前 Feedly 上的订阅源薅了下来,自己搭了个 RSS 服务器,在自己的主力机(Arch Linux)、笔记本(Windows 11),以及手机(iPhone)上实现了多端同步还有查看,故在此做一个简单的记录。

背景

RSS 作为我日常生活比较稳定的信息来源,我之前一直是在使用 Feedly 的,但是因为需要打开浏览器,现在也不像在老东家的时候那样,常年开着浏览器窗口了,所以我就想着,折腾一个可以多端同步的解决方案。

我最终选择的方案如下图所示:

在上图中,电脑和手机通过 Fresh RSS 提供的 API(Fever 或者原生的 Greader),进行数据同步,由于是自己在用,数据传输方面就自己弄个 SSL 证书即可,不需要使用商业的 HTTPS 证书,挂载出来的卷可以进行定期备份,如果有必要(比如说源非常重要,或者说想加固自己的数据),可以考虑使用第三方的 RDS 服务。

搭建 Fresh RSS 服务

首先,在自己的服务器上简单创建一个 compose.yaml 文件,用于存储相关的服务清单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
services:
freshrss:
image: freshrss/freshrss:latest
hostname: freshrss
restart: always
logging:
options:
max-size: 10m
volumes:
- ./data:/var/www/FreshRSS/data
- ./extensions:/var/www/FreshRSS/extensions
ports:
- 12382:80
environment:
TZ: Asia/Shanghai
CRON_MIN: "2,32" # <1> cron
FRESHRSS_ENV: development
LISTEN: 0.0.0.0:80
TRUSTED_PROXY: 172.16.0.1/12 192.168.0.1/16
OIDC_ENABLED: 0
# <2> freshrss-install
FRESHRSS_INSTALL: |-
--api_enabled
--base_url 192.168.1.123
--db-base freshrss
--db-host db
--db-password dbpassword
--db-type pgsql
--db-user freshrss
--default_user freshrss
--language en
# <3> freshrss-user
FRESHRSS_USER: |-
--api_password apipassword
--email username@gmail.com
--language en
--password password
--user freshrss
healthcheck:
test: timeout 10s bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1
interval: 30s
timeout: 5s
retries: 3
depends_on:
db:
condition: service_healthy
restart: false

db:
image: postgres:16
hostname: db
restart: always
logging:
options:
max-size: 10m
volumes:
- ./db:/var/lib/postgresql/data
environment:
POSTGRES_DB: freshrss
POSTGRES_USER: freshrss
POSTGRES_PASSWORD: dbpassword
expose:
- 5432
healthcheck:
test: pg_isready -U postgres -d "dbname=$$POSTGRESQL_DB" -h 127.0.0.1 -p 5432
interval: 30s
timeout: 5s
retries: 3

在上述清单中,有如下的内容需要注意:

  1. CRON_MIN 环境变量指 RSS 源拉取的时间,这里 2,32 表示在每个小时的第二分钟和第 32 分钟进行拉取。
  2. FRESHRSS_INSTALL 中定义了安装相关的参数,要注意的是数据库的密码需要和下面数据库服务保持一致。
  3. FRESHRSS_USER 中定义了用户的信息,主要是 用户名密码,以及 API 密码。

使用 docker compose up -d 运行,通过映射出来的端口号来访问服务。

使用自己的 SSL 证书

签发自己的 SSL 证书

关于签发证书,为了方便,我直接使用 mkcert [1] 来生成证书,并备份收藏好它生成出来的 rootCA 证书,分发到各个客户端中,这样就可以在不同的电脑和手机上用 HTTPS 来访问自己的网站了。

注意

非常不推荐用 HTTP 的形式进行网站的访问,如果是自己使用而没有商业用途或者多人使用的情况,完全可以自己签发证书。另外,如果是小批量多人使用的情况,也不推荐把 CA 证书开放下载的时候提供,会有更大的安全隐患。

可以使用如下命令生成自己想要的证书,另外如果你没有绑定域名,直接不用带域名参数即可:

1
mkcert -cert-file cert.pem -key-file cert.key domain.example.com 192.168.1.123

小贴士

可以定义 CAROOT 环境变量,用于方便查找自己的 CA 证书,如果没有定义,默认 CA 证书的位置可以通过 mkcert -CAROOT 查看。

配置服务使用 SSL 证书

对我们的 compose.yaml 进行修改,添加一个 Nginx 服务进行 HTTPS 流量转发:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
services:
endpoint:
image: nginx:alpine
hostname: endpoint
restart: always
logging:
options:
max-size: 10
ports:
- 12382:443
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./cert.pem:/etc/nginx/ssl/cert.pem:ro
- ./cert.key:/etc/nginx/ssl/cert.key:ro
depends_on:
freshrss:
condition: service_healthy
restart: false

注意,你需要关闭 Fresh RSS 服务的端口映射,方便端口释放,然后上述的证书文件是上个章节生成的,而 nginx.conf 文件,只是做了简单的流量转发:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
upstream freshrss {
server freshrss:80;
keepalive 64;
}

server {
listen 80;

location / {
return 301 https://$host$request_uri;
}
}

server {
server_name 47.122.61.12;
listen 443 ssl http2;

ssl_certificate ssl/cert.pem;
ssl_certificate_key ssl/cert.key;

location / {
proxy_pass http://freshrss/;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 90;

proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
}
}

上述的配置直接使用就可以,有两个要点需要说明:

  1. proxy_pass 中,最后的斜杠 / 是必需的。
  2. 最后的 Authorization 请求头主要是用于 Google Reader API 的兼容。

配置完毕之后,可以直接 docker compose up -d 开启服务。

安装自己的 CA 证书

下载自己的证书,重命名为 crt 格式,打开它之后进行安装,安装的时候选择 “将所有的证书都放入下列存储”,并选择 “受信任的根证书颁发机构”,就可以安装并信任自己的 CA 证书了。

直接使用 trust [1] 命令安装就可以:

1
sudo trust anchor --store rootCA.crt

  1. https://wiki.archlinux.org/title/User:Grawity/Adding_a_trusted_CA_certificate ↩︎

首先先把自己的证书发送给自己的手机,可以使用邮件(需要用系统邮箱软件打开),或者直接用 python -m http.server 启动一个临时的 Web 服务器,然后用系统自带的 Safari 打开,安装证书,并在通用 -> 关于本机 -> 证书信任设置中,信任自己的 CA 证书。

客户端对接

在 Windows 11 和 Arch Linux 中,我选择使用 Fluent Reader[1] 作为我的阅读器,可以做简单的过滤,而且颜值还行。

安装完 Fluent Reader 之后,直接在设置中选择服务,添加 Fever API 服务,端点是自己的服务器地址,加上 /api/fever.php 后缀,比如说 https://192.168.1.123:12382/api/fever.php,用户名密码是自己之前配置的用户名,以及 API 密码(注意不是登录密码)。


  1. https://github.com/yang991178/fluent-reader/ ↩︎

在 iPhone 上,我暂时使用的是 NetNewsWire 和 Fluent Reader Lite[1] ,后面可能会考虑其它家的代替品。NetNewsWire 可以在软件中可以直接添加一个 Fresh RSS 账号,使用 /api/greader.php 作为后缀,并且还是用上述的用户名以及 API 密码访问,而 Fluent Reader Lite 的配置和桌面端一致。


  1. https://github.com/yang991178/fluent-reader-lite ↩︎


  1. https://github.com/FiloSottile/mkcert ↩︎