在云服务器上安装Trilium打造个性化的笔记系统(3):安装SSL证书启用TLS实现https加密访问

上一篇介绍了怎么在云服务器上安装 trilium 的服务端(《在云服务器上安装Trilium打造个性化的笔记系统(2):如何在云服务器上通过 docker 安装Trilium的服务端》),如果你不介意安全的问题,那么就可以这么一直用着了,对于 trilium 的各项功能完全没有任何影响。

甚至,你连域名都不用申请,省下一年7块钱,直接用IP地址:端口号(如 http://116.127.138.149:777)的方式来访问和使用 trilium,没毛病。但是如果你用笔记来记录一些个人的东西,那么最好还是加个密,使用https来访问得好。

假设你已经完成了上一篇中的步骤,搞定了服务器空间申请、域名解析和服务端的安装,可以正常地使用 http://abc.com:777来访问 trilium了,那么这一篇告诉你,如何启用 trilium 的TLS,从而使用SSL加密的https://abc.com:777来使用 trilium。

官方文档(TLS配置)的说明摘录如下,如果你能看懂且知道如何操作,那可以直接跳过我这一篇:

TLS配置是服务器安装所必需的,它与桌面端的使用无关。

首先要做的是获取TLS证书。您有两种选择:

  • 推荐 - 获取由根证书颁发机构(root certificate authority)签名的TLS证书。对于个人用途,最好的选择是Let's encrypt。它是免费的、自动化且容易的。
  • 生成自己的自签名证书。将证书导入到您连接到服务器安装的所有计算机中时会遇到额外的麻烦,因此不建议这样做。

修改config.ini

现在您已经有了证书,我们需要修改数据目录中的config.ini,以便Trilium使用它:

[Network]
port=8080
# true for TLS/SSL/HTTPS (secure), false for HTTP (unsecure).
https=true
# path to certificate (run "bash bin/generate-cert.sh" to generate self-signed certificate). Relevant only if https=true
certPath=/[username]/.acme.sh/[hostname]/fullchain.cer
keyPath=/[username]/.acme.sh/[hostname]/example.com.key

上面仅是当我使用Let's encrypt程序生成证书时如何在环境中设置的示例。您的路径可能完全不同。(请注意,如果您使用的是Docker安装,则这些路径应位于docker容器对应的分区或其他路径中。)

设置完之后,您可以重新启动Trilium,然后就可以使用"https"访问主机名。

从上面的说明我们可以知道,要启用 https 访问,至少需要两方面的工作:获取 TLS证书、修改config.ini启用TLS。

步骤一:获取TLS证书

对于网站证书,可以使用免费的acme.sh 工具,可以参考《acme.sh申请证书的说明》。主要步骤是:

  1. 安装 acme.sh
  2. 生成证书
  3. copy 证书到 nginx/apache 或者其他服务
  4. 更新证书
  5. 更新 acme.sh

1. 安装 acme.sh

安装很简单, 一个命令:

curl https://get.acme.sh | sh -s email=admin@abc.com 

普通用户和 root 用户都可以安装使用。安装过程进行了以下几步工作:

  • 把 acme.sh 安装到你的 home 目录下:
  • ~/.acme.sh/

    并创建 一个 shell 的 alias, 例如 .bashrc,方便你的使用:

    alias acme.sh=~/.acme.sh/acme.sh
  • 自动为你创建 cronjob, 每天 自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书。
  • 安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中: ~/.acme.sh/

    2. 生成证书

    acme.sh 实现了 acme 协议支持的所有验证协议。一般有两种方式验证: http 和 dns 验证。因为证书都是有有效期的,dns 验证无法自动更新证书,每次证书到期续期都需要手动再次重新解析验证域名所有权,所以我们采用 http 验证方式。

    http 方式需要在你的网站根目录下放置一个文件,来验证你的域名所有权,完成验证,然后就可以生成证书了。

    acme.sh --issue -d abc.com --webroot /home/wwwroot/mydomain.com/

    注意:
    1. 上面的 abc.com,是你的域名,如果有多个,就写多个 -d,每个后面跟一个域名。
    2. 上面的 /home/wwwroot/mydomain.com/,是指网站根目录的地址,因为是 docker 安装,所以这个目录地址可以随便写一个。
    3. trilium是node启动的,可以用这种方式验证,但要使用后面的 --standalone 方式。

    只需要指定域名, 并指定域名所在的网站根目录。 acme.sh 会全自动的生成验证文件,并放到网站的根目录, 然后自动完成验证。 最后会聪明的删除验证文件, 整个过程没有任何副作用。

    因为我们使用了 docker 安装 trilium 的服务端,既没用 apache 也没用 nginx,所以以下这段了解即可。

    如果你用的 apache服务器, acme.sh 还可以智能的从 apache的配置中自动完成验证, 你不需要指定网站根目录:

    acme.sh --issue -d mydomain.com --apache

    如果你用的 nginx服务器, 或者反代, acme.sh 还可以智能的从 nginx的配置中自动完成验证, 你不需要指定网站根目录:

    acme.sh --issue -d mydomain.com --nginx

    注意, 无论是 apache 还是 nginx 模式, acme.sh在完成验证之后, 会恢复到之前的状态, 都不会私自更改你本身的配置. 好处是你不用担心配置被搞坏, 也有一个缺点, 你需要自己配置 ssl 的配置, 否则只能成功生成证书, 你的网站还是无法访问https. 但是为了安全, 你还是自己手动改配置吧.

    acme.sh脚本默认ca服务器是zerossl,经常出错,会导致获取证书的时候一直出现:
    Pending, The CA is processing your order, please just wait.

    只需要把ca服务器改成letsencrypt 即可,虽然更改以后还是有概率出现pending,但基本2-3次即可成功

    acme.sh --set-default-ca --server letsencrypt

    上面这步很重要,因为 zerossl 确实是基本连接不上。

    因为我们是 docker 安装的 trilium,不知道网站根目录的地址,且开放的端口是777,所以 80 端口是空闲的没有 web 服务,所以需要使用acme的 --standalone模式,让 acme.sh 假装自己是一个webserver,临时监听在80 端口,以 完成验证:

    acme.sh --issue -d abc.com --standalone

    经过以上操作,正常的话 acme 就会在自身安装目录下生成你所需的证书了。

    如果没有的话,再执行一遍生成命令:

    acme.sh --issue -d abc.com --webroot /home/wwwroot/mydomain.com/

    3. copy/安装 证书

    前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方。注意: 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件,例如:不要直接让 nginx/apache 的配置文件使用这下面的文件。这里面的文件都是内部使用,而且目录结构可能会变化。正确的使用方法是使用 --install-cert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置,例如:

    acme.sh --install-cert -d abc.com \
    --cert-file      ~/trilium/trilium-data/cert.pem  \
    --key-file       ~/trilium/trilium-data/key.pem  \
    --fullchain-file ~/trilium/trilium-data/fullchain.pem
    

    至此,获取证书这一步的操作,就已经全部完成了。使用以下命令,可以查看已经安装的证书:

    acme.sh --info -d abc.com

    下一步修改配置文件后重启 trilium ,就可以 https 访问了。但是因为证书是会过期的,acme本身也会升级,所以设置一下证书的自动更新和 acme 的自动升级是非常必要的。

    4. 更新证书

    目前证书在 60 天以后会自动更新,你无需任何操作。今后有可能会缩短这个时间,不过都是自动的,你不用关心。

    acme安装的时候,会自动新建一个计划任务,使用 crontab -l 命令查看,请确保 cronjob 正确安装,看起来是类似这样的:

    crontab  -l
    56 5 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
    //上面这行表示每天的5:56会自动执行 acme.sh 检查证书更新

    5. 更新 acme.sh

    目前由于 acme 协议和 letsencrypt CA 都在频繁的更新,因此 acme.sh 也经常更新以保持同步。

    升级 acme.sh 到最新版:

    acme.sh --upgrade

    如果你不想手动升级, 可以开启自动升级:

    acme.sh --upgrade --auto-upgrade

    之后,acme.sh 就会自动保持更新了。

    你也可以随时关闭自动更新:

    acme.sh --upgrade --auto-upgrade  0

    步骤二:修改 config.ini 文件

    docker 安装的 trilium,可以在你定义好的数据目录(如前例:~/trilium/trilium-data)中找到 config.ini 文件,按照自己的实际编辑以便Trilium使用它:

    [Network]
    port=777
    # true for TLS/SSL/HTTPS (secure), false for HTTP (unsecure).
    https=true
    # path to certificate (run "bash bin/generate-cert.sh" to generate self-signed certificate). Relevant only if https=true
    certPath=/root/trilium/fullchain.pem
    keyPath=/root/trilium/key.pem
    

    要设置的地方有:

    prot=777(你安装时设置开放访问的端口号 777)
    https=true(启用 https)
    certPath=/root/trilium/fullchain.pem(注意目录是容器内的数据目录,即docker-compose.yml配置文件中 TRILIUM_DATA_DIR=/root/trilium-data 设置的目录,也就是证书被复制到的目录)
    keyPath=/root/trilium/key.pem(同上)

    设置完之后,您可以重新启动Trilium,然后就可以使用"https"访问主机名。

    docker compose restart

    这样就可以用 https://abc.com:777 来访问和管理你的笔记了,同时把客户端“同步”设置里的“服务器地址”也改成“https://abc.com:777”,整个安装、设置过程就齐活了。

    再胡扯几句

    之所以写这一篇笔记,是因为网上搜遍了,也没搜到几篇讲 trilium 如何启用 TLS 实现 https 访问的文章,所以只有对照着官方文档的说法,自己动手解决了。

    如果你正好有同样的需求,希望能帮到你。另外,获取证书和启用 TLS 的操作不仅适用于 docker 安装的 trilium ,其它方式安装的同样可以参考。

    最后就是,网上有不少文章,教你如何用 docker 来安装 trilium,然后到了讲 https 的时候一语带过,而且不同文章中的这“一语”还都是一篇里面抄来的,更魔性的是,最后还列上一段代码,手把手教你如何启用 nginx 反代,从而实现直接用 https://abc.com 访问你的笔记服务器,而不需要再加端口号如 https://abc.com:777 的形式。其魔幻之处在于,他却并没有教你怎么在 trilium 里设置 apache 或者 nginx 的代理模块……我是看的一头雾水。