分享一下我的笔记数据云备份方案

本贴最后更新于 819 天前,其中的信息可能已经沧海桑田

需求

因为工作,学习需要,要对思源的中文档数据定期进行备份,转存到第三方平台,所以就有了这篇教程和一个开源的小工具 siyuanBackUp。方便地将服务端数据备份到第三方云盘(包括但不限于阿里云盘、Onedrive)

要求

  1. 一定要无感备份,即最好一键备份,或者触发了某个事件就自主备份
  2. 不修改后端源码,方便后续跟进官方更新,可以快速切换版本

最终效果

将原来的同步按钮改为备份按钮,作为备份操作的 url 触发器,一键实现数据的打包、转存

(不影响付费用户使用同步功能,仍然可以按 F9 快捷键进行同步)

也可通过公网访问此 url 进行远程触发,完成备份

后端接收到打包请求,开始异步执行打包、上传

折腾开始

提醒

  1. 本方案是针对服务器上 docker 部署的思源,如果你是本地用户,那么很抱歉帮不到你。
  2. 本备份方案不适合非常小白的同学食用,最好有过服务端部署项目的经验。如果你要跟着部署,请务必准备好下面的基础设施
    1. 一台 CentOS 服务器(我的版本是 release 8.5.2111,实际跟这个没关系,6,7 都可以)
    2. 一个阿里云盘账号

不修改源码的前提下,我想到的方案是通过中间人进行流量监控,如果有请求触发了预设的逻辑,就执行对于的操作。听起来好像就是网关路由,确实一开始想使用 Spring Gateway 做这个工作,但是我觉得为了一个自动化需求去部署一个微服务,有点杀鸡用牛刀了,所以最终选型用 mitmproxy,开发快速,完美解决我的需求。

这里不多介绍 mitmproxy,简单说是一个流量监控开源工具,常用做测试、渗透等方面,更详细的介绍可以在官网阅读 Introduction (mitmproxy.org)

在用户发送请求到达思源服务端之前,将请求通过透明代理的方式,先访问 mitmproxy 服务,再由 mitmproxy 把请求转发到服务端。

如果用户的某个请求触发了 mitm 预设的条件,就会执行相应的动作,原理很简单,下面就开始进行部署。

一、创建思源 docker

首先创建一个工作空间目录,用于映射思源的 workspace

目录位置可以自定义,后面用到的地方自行替换

mkdir -p /myapps/siyuan/workspace

然后运行一个 docker 容器,用来拷贝我们后面需要用的原文件

docker run --name=siyuan -u 1000:1000 b3log/siyuan:v2.1.6 --workspace=/siyuan/workspace/

Ctrl + C,把运行思源进程停掉

拷贝容器中前端的 js 目录

docker cp siyuan:/opt/siyuan/stage/build/desktop /myapps/siyuan/

把这个容器删了,我们运行一个新的容器,并映射本地 workspace 和 desktop 这两个目录

运行容器之前给这两个目录设上权限,不然容器起不来

docker rm siyuan
chown -R 1000:1000 /myapps/siyuan/workspace
chown -R 1000:1000 /myapps/siyuan/desktop

我指定的端口是 6807,也可以自定义,后面 iptables 规则和 mitmproxy 程序中的端口需要改成一样的

docker run --name=siyuan-2.1.6 -v /myapps/siyuan/workspace:/siyuan/workspace -v /myapps/siyuan/desktop:/opt/siyuan/stage/build/desktop -p 6807:6806 -u 1000:1000 b3log/siyuan:v2.1.6 --workspace=/siyuan/workspace/

通过测试,在网页上正常访问

二、部署 aliyunpan

想要在 Linux 上操作阿里云盘,有一个很好用的开源工具 aliyunpan,用于我们备份工作的上传

apt 安装

适用于 apt 包管理器的系统,例如 Ubuntu国产 deepin 深度操作系统等。目前只支持 amd64 和 arm64 架构的机器。

sudo curl -fsSL http://file.tickstep.com/apt/pgp | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/tickstep-packages-archive-keyring.gpg > /dev/null && echo "deb [signed-by=/etc/apt/trusted.gpg.d/tickstep-packages-archive-keyring.gpg] http://file.tickstep.com/apt aliyunpan main" | sudo tee /etc/apt/sources.list.d/tickstep-aliyunpan.list > /dev/null && sudo apt-get update && sudo apt-get install -y aliyunpan

rpm 安装

适用于 rpm 包管理器的系统,例如 CentOSRockyLinux 等。目前只支持 amd64 和 arm64 架构的机器。

sudo curl -fsSL http://file.tickstep.com/rpm/aliyunpan/aliyunpan.repo | sudo tee /etc/yum.repos.d/tickstep-aliyunpan.repo > /dev/null && sudo yum install aliyunpan -y

安装完成后用命令行登录阿里云盘

aliyunpan login

然后需要输入 RefreshToken,获取这个 RefreshToken 需要进到阿里云盘官网并登录,按照下方图片操作

获取到后,复制下来,粘贴到终端回车,登录成功

把 RefreshToken 记下来,等会自动化脚本还要用到这个

三、部署 mitmproxy 流量监控

运行 siyuanBackUp 需要机器中有 Python3 支持,没有环境可以直接 yum install python36 快速安装一个

克隆 siyuanBackUp,克隆的位置可以任意,我选择和之前的目录放在了一起 cd /myapps/siyuan

git clone https://gitclone.com/github.com/aqz236/siyuanBackUp.git

如果使用 github 克隆速度较慢,也可以克隆下面 gitee 的仓库

git clone https://gitee.com/FSHOU/siyuanBackUp.git

进入 siyuanBackUp,创建虚拟环境,并在虚拟环境中安装项目依赖

cd siyuanBackUp/
python3 -m venv siyuanEnv
source siyuanEnv/bin/activate
pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

安装完成后需要简单填写一下配置

编辑 backup.sh,如果你之前没有对映射位置做过自定义的修改,那么这里只需要填写 RefreshToken

编辑 siyuan_mitm.py,如果你的端口是设置的端口也是 6807,则此处不需要做任何修改

添加两条自定义 iptables 规则,此处的 6807 要与创建容器时设置的端口相同,8712 是设置的 mitmproxy 透明代理端口。

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 6807 -j REDIRECT --to-port 8712
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 6807 -j REDIRECT --to-port 8712

然后把当前的 iptables 配置保存到配置文件中

iptables-save > /etc/sysconfig/iptables

为了让添加的两条规则永久生效,需要执行

service iptables save

如果报错 Failed to restart iptables.service: Unit not found.,则需要安装 iptables-services

yum install iptables-services -y

查看全部的 nat 规则

iptables -t nat -L -n --line-numbers

在 DOCKER 链下看见了 6807 与 6806 之间的转发,是正在生效的

把这条规则删除,删除的行号要与查到的对应,想要让删除的规则永久生效,可以看补充 1。

这种删除方法不是彻底删除,重启 iptables 或者容器,都会失效,我正好利用这个机制来决定 siyuanBackUp 的启动与关闭,详细使用操作看后面的补充 2

iptables -t nat -D DOCKER 行号

删除规则后,页面刷新一下,已经是打不开了,此时用户访问的流量已经从原来的 6807 被转发到了 8712,如果仍然可访问,解决方法看后面的补充 3

然后以透明代理模式启动 mitmproxy

mitmdump -p 8712 --set block_global=false --mode transparent -s siyuan_mitm.py

页面正常加载,且 mitmproxy 成功捕获到了流量

补充:

  1. 如果需要让 6807->6806 的 docker 规则永久删除,可以在配置文件中将这条规则注释掉,这样再重启 iptables 都不会使其生效了

    重启 iptables,查看规则,发现只有我们自定义规则了

    不过,如果是重启了容器,规则还是会被覆盖生效,这是无可避免的,除非再写一条规则,把 docker 映射的 6807 端口映射到其他端口

  2. 如果想要停止透明代理,可以直接重启 iptables,或者重启容器,想需要再次让 6807 端口走透明代理就把 DOCKER 链下的 6807->6806 的转发规则删除,删除规则是立即生效的,不需要重启,下次再像代理,需要再手动把 docker 的规则删除。

  3. 如果添加了规则,并且删了 6807->6806 的规则,网页仍然可以访问,检查是不是网卡名称的原因,使用 ifconfig 看自己的网卡名称,像我这台虚拟机,网卡名就不是默认的 eth0,而是 ens33

    这就要修改两个地方,重新添加规则,并且修改 siyuan_mitm.py

    1. vi /etc/sysconfig/iptables 找到添加的两条自定义规则,将两处的 eth0 改成自己的网卡名
    2. 修改 siyuan_mitm.py 中 nic 的值

    修改完后重启 iptables

四、制作触发器

最后需要做一个触发器,用于触发备份请求,这里的方案是改前端代码,通过制作按钮可以发起备份请求。

也可以再额外去写一个 crontab,做一个时间触发器,比如每周六晚上十一点做一次备份

0 23 * * 6 /myapps/siyuan/siyuanShell/backup.sh

时间触发器比较简单,下面说这个手动的怎么弄,进入最开始导出来的 desktop 目录,有一个叫 main.fcaf89eaf1cee5881c1f.js 的 js 文件,要修改的就是这个。

直接修改有点困难,这个 js 是被极限压缩了,得去做代码格式化,这里直接提供修改的快捷方法

vi 编辑文件,然后斜杠向下搜关键字

<div id="barSync" class="toolbar

搜到的第一个结果就是要改的目标,把 id 的值改为其他的,我改成了 barBackupSelf,也可以自定义其他的

再继续搜关键词

${window.siyuan.config.sync.stat||window.siyuan.languages.syncNow+

搜到的第一个结果,把双引号之间的内容改成 立即备份

然后继续 vi 搜关键词

if("barSync"===t.id){if((0,f.needSubscri

if 的前面插入一段代码,这个 /api/self/backup/alipan 就是我们用于触发上传的 api

if("barBackupSelf"===t.id){(0,c.fetchPost)("/api/self/backup/alipan",{}),e.stopPropagation();const i = n(1890);if(true) void(0, i.showMessage)(window.siyuan.languages._kernel[41]);break}

最后,让 mitmproxy 跑起来,看一下效果

记得把语言改成中文 > Settings-->Appearance-->Language

上传成功!

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    22337 引用 • 89380 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...