用ACME更新并安装Ocserv的服务器证书

天下谁人不自宫 相逢何必问枯荣 人生聚散原如此 莫把浮浪误大胸

大家好,本文介绍了如何给自己的ocserv服务器使用ACME协议,这将极大地简化ocserv的服务器端数字证书生命周期管理。阅读本文需要您有入门级别的Linux知识,并阅读过家庭简易VPN服务器搭建。动手实验需要以下材料:

  • 个人电脑(虚拟机可,盒子亦可),运行Linux
  • 公网IPv4
  • 一个域名
  • DDNS服务

C 缘起

为了出门在外也能使用家里的网络环境,我的VPN服务器已经运行多年,一直使用免费的数字证书(从DigiCert薅来的羊毛)来保障通信安全。但是2023年开始,各大CA机构调整了免费数字证书的有效期,从之前的一年缩短到了三个月。我要是每三个月就手动安装一次数字证书那就太麻烦了。要是数字证书的更新(renew)与安装都能自动化完成那我就省事了。

D ACME

自动证书管理环境(英语:Automatic Certificate Management Environment)是一个互联网标准的通信协议。简而言之,它能向证书服务商证明您对域名的控制权,以生成相关域名的证书。

知名的免费ACME服务商(下称CA机构)有Let’s EncryptZeroSSL等,本文使用后者。

知名的ACME客户端有acme.shCaddyCertbot等,本文使用acme.sh。

流程大概是:

  1. CA机构发起DNS挑战(chanllange)。
  2. acme.sh写入DNS记录,响应挑战。
  3. CA机构验证挑战通过。
  4. CA机构签发证书。
  5. acme.sh下载证书。
  6. acme.sh安装证书
  7. acme.sh定期更新证书(仍然需要挑战)。

E 准备一个DNS服务商的安全凭据

为了证明我们有域名的控制权,我们要赢得挑战。挑战有http类型的,它会启动一个web服务器,然后由CA机构来访问这个服务器,由于家用宽带很难开放TCP端口80,所以这条路行不通;

另一条路是DNS,CA机构要求我们新建DNS记录(txt类型),内容由对方指定。一旦CA机构解析到这条记录,即认为我们有域名的控制权。

所以我们得从DNS服务商获取安全凭据,这东西各家不一样,有的是令牌(token);有的是用户名/密码的形式。我用的是鹅厂的,网址是https://console.dnspod.cn/account/token/token 。

然后可以到ocerv服务器上存一下:

1
2
export DP_Id="<id>"
export DP_Key="<key>"

这种东西一般厂家都是只让人看到一次的,自己不存起来的就得再生成一次。

F ZeroSSL.com

ZeroSSL有API令牌,不过他家的ACME服务需要EAB(External Account Binding)。 在这里生成EAB: https://app.zerossl.com/developer

也是只展示一次,得存起来。

G acme.sh

安装

acme.sh很清爽:

1
wget -O -  https://get.acme.sh | sh -s email=[email protected]

它需要 curllibcurl4,缺少的自己装一下,太老的升级一下。

访问github有困难的可以用境内仓库。
1
2
3
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m [email protected]

绑定EAB:

1
2
3
acme.sh --register-account  --server zerossl \
        --eab-kid  <Q29xxxxxx>  \
        --eab-hmac-key  <Q4Exxxxxxxxx>

证书

acme.sh 支持多家CA机构,默认是ZeroSSL。

以下命令包含发起挑战、完成挑战并下载证书。

其中dns_dp是DNS服务商(鹅厂)的标识,foo.bar.com是ocserv服务器的FQDN。

其他DNS服务商见官方维基

1
acme.sh --issue --dns dns_dp -d foo.bar.com

安装证书

acme.sh把证书下载到了~/.acme.sh/foo.bar.com_ecc/文件夹。我们还得让它自己去把证书安装好,其实就是复制到指定的文件夹去。

文件夹权限

设我们想把证书存到/etc/ocserv/acme这个文件夹里,我们建个组,把自己加入组,然后给这个组权限。

用户的组身份变化可能需要重登录SSH。

1
2
3
4
5
6
7
8
9
export GRP_NAME="acmesh"
export OCSERV_ACME_DIR="/etc/ocserv/acme"
sudo groupadd $GRP_NAME
sudo usermod -aG $GRP_NAME $(whoami)
sudo mkdir $OCSERV_ACME_DIR
sudo touch $OCSERV_ACME_DIR/foo.bar.com_bundle.crt
sudo touch $OCSERV_ACME_DIR/for.bar.com.key
sudo chgrp -R $GRP_NAME $OCSERV_ACME_DIR
sudo chmod -R g+wx $OCSERV_ACME_DIR

然后就可以安装证书了:

1
2
3
4
acme.sh --install-cert -d foo.bar.com \
        --key-file /etc/ocserv/acme/foo.bar.com.key \
        --fullchain-file /etc/ocserv/acme/foo.bar.com_bundle.crt \
        --reloadcmd "sudo systemctl restart ocserv"

当前用户需要能免密码运行sudo

续签证书

acme.sh 使用定时任务检查证书有效期,有需要的话会去续签,续签成功还会自动安装。比如我的被它设置为每天05:52执行一次:

1
2
crontab -l
52 5 * * * "/home/<username>/.acme.sh"/acme.sh --cron --home "/home/<username>/.acme.sh" > /dev/null

接下来就什么都不用做了,它会每2个月续签并自动安装。

这个方法也适用于nginx以及apache。

好了,看过了就等于会了,谢谢观看。

0%