Contents
  1. 1. 前言
  2. 2. 安装
  3. 3. 开始之前
    1. 3.1. 支持acme协议的ca
    2. 3.2. 测试申请证书
      1. 3.2.1. 测试申请ECC证书
  4. 4. 申请正式证书
    1. 4.1. 使用url验证
    2. 4.2. 使用dns验证
  5. 5. 安装证书
  6. 6. 更新证书

前言

这是学习部署Xray接触到的技术,感觉挺有用,记录一下
现在申请阿里和腾讯的免费证书需要手动去控制台操作,证书1年有效,手动续期,用这个acme技术就可以全命令行和自动续期
以下文章多处参考Xray相关文档

安装

在linux安装运行下面命令就ok

1
wget -O -  https://get.acme.sh | sh

执行完后需要更新一下环境变量,可以断开连接重新登录系统,也可用下面命令

1
. .bashrc

自动更新acme.sh

1
acme.sh --upgrade --auto-upgrade

开始之前

支持acme协议的ca

acme.sh支持的ca可以看官方文档
目前acme.sh默认ca是zerossl,但是我试过用这个ca申请失败

更换默认ca

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

在命令中指定ca需要加参数,例如: –server letsencrypt

测试申请证书

在正式申请证书之前,我们先用测试命令(–issue –test)来验证是否可以成功申请,验证通过后再正式申请,过程中有报错的话就加(–debug)参数看看

测试申请ECC证书

1
acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256

ECC证书的主要优势在于它的 Keysize 更小,意味着同等大小下安全性的提升和加密解密速度的加快。如 ECC-256bit 的强度大约相当于 RSA-3072bit,何乐而不为呢?当然,有人说 ECC 证书握手会明显更快,这我觉得就有些夸张了,因为 RSA 握手也没有太慢,就算有差别应该也是毫秒级,很难直接感知。

另外,如果有些网站确实需要兼容某些古老设备的,那也还是请按需选择RSA证书。

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
[Wed 30 Dec 2022 04:25:12 AM EST] Using ACME_DIRECTORY: https://acme-staging-v02.api.letsencrypt.org/directory
[Wed 30 Dec 2022 04:25:13 AM EST] Using CA: https://acme-staging-v02.api.letsencrypt.org/directory
[Wed 30 Dec 2022 04:25:13 AM EST] Create account key ok.
[Wed 30 Dec 2022 04:25:13 AM EST] Registering account: https://acme-staging-v02.api.letsencrypt.org/directory
[Wed 30 Dec 2022 04:25:13 AM EST] Registered
[Wed 30 Dec 2022 04:25:13 AM EST] ACCOUNT_THUMBPRINT='CU6qmPKuRqhyTAIrF4swosR375194z_1ddUlWef8xDc'
[Wed 30 Dec 2022 04:25:13 AM EST] Creating domain key
[Wed 30 Dec 2022 04:25:13 AM EST] The domain key is here: /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key
[Wed 30 Dec 2022 04:25:13 AM EST] Single domain='二级域名.你的域名.com'
[Wed 30 Dec 2022 04:25:13 AM EST] Getting domain auth token for each domain
[Wed 30 Dec 2022 04:25:14 AM EST] Getting webroot for domain='二级域名.你的域名.com'
[Wed 30 Dec 2022 04:25:14 AM EST] Verifying: 二级域名.你的域名.com
[Wed 30 Dec 2022 04:25:23 AM EST] Pending
[Wed 30 Dec 2022 04:25:25 AM EST] Success
[Wed 30 Dec 2022 04:25:25 AM EST] Verify finished, start to sign.
[Wed 30 Dec 2022 04:25:25 AM EST] Lets finalize the order.
[Wed 30 Dec 2022 04:25:25 AM EST] Le_OrderFinalize='https://acme-staging-v02.api.letsencrypt.org/acme/finalize/490205995/7730242871'
[Wed 30 Dec 2022 04:25:25 AM EST] Downloading cert.
[Wed 30 Dec 2022 04:25:25 AM EST] Le_LinkCert='https://acme-staging-v02.api.letsencrypt.org/acme/cert/xujss5xt8i38waubafz2xujss5xt8i38waubz2'
[Wed 30 Dec 2022 15:21:52 AM EST] Cert success.
--BEGIN CERTIFICAT--
sxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN
cTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp
wAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC
2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid
SjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb
wXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX
...
haiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg
0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2
YO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV
FmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc
G6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd
Am65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6
NZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0
x6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp
yiLKcBFc5H7dgJCImo7us7aJeftC44uWkPIjw9AKH=
--END CERTIFICAT--
[Wed 30 Dec 2022 15:21:52 AM EST] Your cert is in /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer
[Wed 30 Dec 2022 15:21:52 AM EST] Your cert key is in /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key
[Wed 30 Dec 2022 15:21:52 AM EST] The intermediate CA cert is in /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/ca.cer
[Wed 30 Dec 2022 15:21:52 AM EST] And the full chain certs is there: /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer

申请正式证书

申请过程中需要验证这个域名的所有权,就是你不能随便申请不属于你的域名,这种验证方式有2种,一是在你的网址添加一个随机url,ca验证这个url能否访问,二是通过在dns新增一个TXT记录指向,ca通过dns验证。两种方式看你的实际情况选择。
acme.sh支持阿里,dnspod(腾讯)的api,可以自动添加删除dns记录。

使用url验证

需提供你网站的root目录

1
acme.sh --issue -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --force

–force 参数的意思就是,在现有证书到期前,手动(强行)更新证书。上一步我们从“测试服”申请的证书虽然不能直接用,但是它本身是尚未过期的,所以需要用到这个参数。

申请成功的输出大概是这样

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
vpsadmin@vps-server:~$ acme.sh --issue -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256
[Wed 30 Dec 2022 15:22:51 AM EST] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Wed 30 Dec 2022 15:22:51 AM EST] Creating domain key
[Wed 30 Dec 2022 15:22:51 AM EST] The domain key is here: /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key
[Wed 30 Dec 2022 15:22:51 AM EST] Single domain='二级域名.你的域名.com'
[Wed 30 Dec 2022 15:22:51 AM EST] Getting domain auth token for each domain
[Wed 30 Dec 2022 15:22:51 AM EST] Getting webroot for domain='二级域名.你的域名.com'
[Wed 30 Dec 2022 15:22:51 AM EST] Verifying: 二级域名.你的域名.com
[Wed 30 Dec 2022 15:22:51 AM EST] Pending
[Wed 30 Dec 2022 15:22:51 AM EST] Success
[Wed 30 Dec 2022 15:22:51 AM EST] Verify finished, start to sign.
[Wed 30 Dec 2022 15:22:51 AM EST] Lets finalize the order.
[Wed 30 Dec 2022 15:22:51 AM EST] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/490205996/7730242872'
[Wed 30 Dec 2022 15:22:51 AM EST] Downloading cert.
[Wed 30 Dec 2022 15:22:51 AM EST] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/vsxvk0oldnuobe51ayxz4dms62sk2dwmw9zhuw'
[Wed 30 Dec 2022 15:22:51 AM EST] Cert success.
--BEGIN CERTIFICAT--
sxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN
cTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp
wAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC
2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid
SjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb
...
tYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos
haiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg
0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2
YO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV
FmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc
G6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd
Am65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6
NZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0
x6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp
yiLKcBFc5H7dgJCImo7us7aJeftC44uWkPM=
--END CERTIFICAT--
[Wed 30 Dec 2022 15:22:52 AM EST] Your cert is in /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer
[Wed 30 Dec 2022 15:22:52 AM EST] Your cert key is in /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key
[Wed 30 Dec 2022 15:22:52 AM EST] The intermediate CA cert is in /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/ca.cer
[Wed 30 Dec 2022 15:22:52 AM EST] And the full chain certs is there: /home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer

使用dns验证

以阿里为例,需要在控制台申请一个子账号,给予操作api角色,授权dns权限

创建一个自定义权限策略,我们只需要dns的增删查权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"alidns:AddDomainRecord",
"alidns:DeleteDomainRecord",
"alidns:DescribeDomainRecords"
],
"Resource": "acs:alidns:*:你的阿里云账号ID:domain/你的域名"
}
]
}

这里如果看不懂,也可以用阿里预定义的 AliyunDNSFullAccess 权限,这个权限就大很多。

把这个权限策略授予你的子账号。

在服务器添加阿里账号的key和secret,只需要export一次,acme.sh会记录好key和secret

1
2
export Ali_Key="LTAI5tMpUof13213213132"
export Ali_Secret="hA34543636457547IjwBP3LchvvFFf"

通过dns申请证书

1
acme.sh --issue --server letsencrypt --dns dns_ali -d 你的域名 --keylength ec-256

输出大概是这样

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
[Tue Sep 27 22:16:58 EDT 2022] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Tue Sep 27 22:16:58 EDT 2022] Creating domain key
[Tue Sep 27 22:16:59 EDT 2022] The domain key is here: /root/.acme.sh/你的域名_ecc/你的域名.key
[Tue Sep 27 22:16:59 EDT 2022] Single domain='你的域名'
[Tue Sep 27 22:16:59 EDT 2022] Getting domain auth token for each domain
[Tue Sep 27 22:16:59 EDT 2022] Getting webroot for domain='你的域名'
[Tue Sep 27 22:16:59 EDT 2022] Adding txt value: NI5emgtlL67Hhg-50Hq2kLF_Fb1YTHJ7C9vs6GxWNDo for domain: _acme-challenge.你的域名
[Tue Sep 27 22:17:04 EDT 2022] The txt record is added: Success.
[Tue Sep 27 22:17:04 EDT 2022] Let's check each DNS record now. Sleep 20 seconds first.
[Tue Sep 27 22:17:25 EDT 2022] You can use '--dnssleep' to disable public dns checks.
[Tue Sep 27 22:17:25 EDT 2022] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Tue Sep 27 22:17:25 EDT 2022] Checking 你的域名 for _acme-challenge.你的域名
[Tue Sep 27 22:17:27 EDT 2022] Domain 你的域名 '_acme-challenge.你的域名' success.
[Tue Sep 27 22:17:27 EDT 2022] All success, let's return
[Tue Sep 27 22:17:27 EDT 2022] Verifying: 你的域名
[Tue Sep 27 22:17:27 EDT 2022] Pending, The CA is processing your order, please just wait. (1/30)
[Tue Sep 27 22:17:31 EDT 2022] Success
[Tue Sep 27 22:17:31 EDT 2022] Removing DNS records.
[Tue Sep 27 22:17:31 EDT 2022] Removing txt: NI5emgtlL67Hhg-50Hq2kLF_Fb1YTHJ7C9vs6GxWNDo for domain: _acme-challenge.你的域名
[Tue Sep 27 22:17:37 EDT 2022] Removed: Success
[Tue Sep 27 22:17:37 EDT 2022] Verify finished, start to sign.
[Tue Sep 27 22:17:37 EDT 2022] Lets finalize the order.
[Tue Sep 27 22:17:37 EDT 2022] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/748519887/129511009687'
[Tue Sep 27 22:17:38 EDT 2022] Downloading cert.
[Tue Sep 27 22:17:38 EDT 2022] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/049ed602b81004f577acb96016a59e992eef'
[Tue Sep 27 22:17:38 EDT 2022] Cert success.
-----BEGIN CERTIFICATE-----
MIIEWDCCA0CgAwIBAgISBJ7WArgQBPV3rLlgFqWemS7vMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMjA5MjgwMTE3MzdaFw0yMjEyMjcwMTE3MzZaMBkxFzAVBgNVBAMT
DnRlc3QubHN0b3AucHViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqwZl3PAr
QONDemYxCP+a510fWwGWf4CcENS2tOwjos+R8KD9evXA+4G85R+UjpO2iqHrJ1CA
gj5YvZwtVom5b6OCAkowggJGMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr
BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUVgO5EHhY
yATz3tY16PTymj6R8rwwHwYDVR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYw
...
8vQRlEu16si2qu1erQQmgv1qK0OQ2VIhOj2IAptaDfvtrG96YTNvdxqT4+wxcJg8
iQeXpttDOeDdReq7FJZ69w4uwPcp64kfVjWpjKGhtfmNTXIAYVF6SHhmjNoCZVF6
E4UP5LhubHnTZdvGChGTsXoRjYZNyrgVTc/A+KJV7bafgARvcTlMnsdUqVkmbYdX
9H154cOr0sKFO2Lp0T3ceTwvPG2A5B36uPfZHFdyB6uFRahAq7RsWXyfapBPwISZ
RFLH+VtY82Ghxe1m
-----END CERTIFICATE-----
[Tue Sep 27 22:17:38 EDT 2022] Your cert is in: /root/.acme.sh/你的域名_ecc/你的域名.cer
[Tue Sep 27 22:17:38 EDT 2022] Your cert key is in: /root/.acme.sh/你的域名_ecc/你的域名.key
[Tue Sep 27 22:17:38 EDT 2022] The intermediate CA cert is in: /root/.acme.sh/你的域名_ecc/ca.cer
[Tue Sep 27 22:17:38 EDT 2022] And the full chain certs is there: /root/.acme.sh/你的域名_ecc/fullchain.cer

安装证书

申请好正式的证书后,要把证书放到合适位置,可能还需要重启一下你的进程,acme.sh

1
2
3
4
acme.sh --install-cert --ecc -d 二级域名.你的域名.com --cert-file /你要安装到的位置/cert.crt \
--key-file /你要安装到的位置/cert.key \
--fullchain-file /你要安装到的位置/fullchain.crt \
--reloadcmd "sudo systemctl restart xray"

fullchain ontains your certificate and all cas up to the root ca. 从root到该ca完整的证书链,因为ca可能有分级,不同设备内置的ca证书可能会没有中间证书,例如我申请的zerossl证书,使用cert证书部署后,在oppo手机上就不认,但是在pc没问题。换成fullchain证书部署,oppo就认了。

安装位置写决定路径,cmd写准确,否则会影响下面cron更新证书

更新证书

letsencrypt 证书有效期一般为90天,acme.sh帮我们做好了cron任务,每晚执行检查一下证书是否快过期需要更新,还会执行安装,这样就解决了证书长期使用问题。

尝试执行一下看看他做了什么,有多个域名都会一起检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@vps:~# "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"
[Tue Sep 27 22:36:11 EDT 2022] ===Starting cron===
[Tue Sep 27 22:36:11 EDT 2022] Already uptodate!
[Tue Sep 27 22:36:11 EDT 2022] Upgrade success!
[Tue Sep 27 22:36:11 EDT 2022] Auto upgraded to: 3.0.5
[Tue Sep 27 22:36:11 EDT 2022] Renew: 'blog.你的域名'
[Tue Sep 27 22:36:11 EDT 2022] Renew to Le_API=https://acme.ssl.com/sslcom-dv-ecc
[Tue Sep 27 22:36:11 EDT 2022] Skip, Next renewal time is: 2022-11-25T07:33:23Z
[Tue Sep 27 22:36:11 EDT 2022] Add '--force' to force to renew.
[Tue Sep 27 22:36:11 EDT 2022] Skipped blog.你的域名_ecc
[Tue Sep 27 22:36:11 EDT 2022] Renew: 'test.你的域名'
[Tue Sep 27 22:36:11 EDT 2022] Renew to Le_API=https://acme-v02.api.letsencrypt.org/directory
[Tue Sep 27 22:36:11 EDT 2022] Skip, Next renewal time is: 2022-11-26T02:17:38Z
[Tue Sep 27 22:36:11 EDT 2022] Add '--force' to force to renew.
[Tue Sep 27 22:36:11 EDT 2022] Skipped test.你的域名_ecc
[Tue Sep 27 22:36:11 EDT 2022] ===End cron===

如果证书不用了,需要到~/.acme.sh目录下删除对应文件夹

Contents
  1. 1. 前言
  2. 2. 安装
  3. 3. 开始之前
    1. 3.1. 支持acme协议的ca
    2. 3.2. 测试申请证书
      1. 3.2.1. 测试申请ECC证书
  4. 4. 申请正式证书
    1. 4.1. 使用url验证
    2. 4.2. 使用dns验证
  5. 5. 安装证书
  6. 6. 更新证书