openssl手工生成证书以及acme.sh自动部署证书

证书简介

有关https是如何保证数据的安全证的,可以参考文章:详解https加密通信原理 ,以下简介证书相关的知识点。

我们一般在服务器上面可以使用openssl命令来生成证书的.而一般是使用X509的证书链。x509证书一般会用到三类文件,key,csr,crt

  • key是私用密钥,openssl格式,通常是rsa算法

  • csr是证书请求文件,用于申请证书。在申请的时候,必须使用自己的私钥来签署申请,还可以设定一个密钥。

  • crt是证书文件(windows下面的csr,其实是crt),是签署人用自己的key给你签署的凭证。

除了以上格式,openssl还有如下后缀名的文件:

  • .crl格式:证书吊销列表,Certificate Revocation List的缩写
  • .pem格式:用于导出,导入证书时候的证书的格式,有证书开头,结尾的格式
  • .p12 “或者 “.pfx” : 用于实现存储许多加密对象在一个单独的文件中。通常用它来打包一个私钥及有关的 X.509 证书,或者打包信任链的全部项目。

在部署HTTPS证书时,不同的服务器我们需要用到不同格式的证书文件,常见的证书文件格式有以下几种:

  • PEM
    • 适用于Apache、Nginx、Candy Server等Web服务器
    • 常见的文件后缀为.pem、.crt、.cer、.key
    • 可以存放证书或私钥,或者两者都包含
    • .key后缀一般只用于证书私钥文件
  • PFX
    • 适用于IIS等Web服务器
    • 常见的文件后缀为.pfx、.p12
    • 同时包含证书和私钥,且一般有密码保护
  • JKS
    • 适用于Tomcat、Weblogic、JBoss、Jetty等Web服务器
    • 常见的文件后缀为.jks

手工生成证书

有时我们需要在内网环境下测试https,可以使用以下方法进行操作:

生成私钥key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 生成rsa私钥,des3算法,openssl格式,2048位强度。
[root@VM_0_6_centos ssl]# openssl genrsa -des3 -out in.key 2048
Generating RSA private key, 2048 bit long modulus
.............................................................+++
................................................+++
e is 65537 (0x10001)
Enter pass phrase for in.key:
139631662581648:error:28069065:lib(40):UI_set_result:result too small:ui_lib.c:831:You must type in 4 to 1023 characters //提示必须输入4位以上的密码
Enter pass phrase for in.key:
Verifying - Enter pass phrase for in.key:

// 可以通过以下方法去除密码
[root@VM_0_6_centos ssl]# openssl rsa -in in.key -out out.key
Enter pass phrase for in.key:
writing RSA key
[root@VM_0_6_centos ssl]# ll
total 8
-rw-r--r-- 1 root root 1751 Sep 12 23:03 in.key
-rw-r--r-- 1 root root 1679 Sep 12 23:03 out.key

使用openssl genrsa -out in.key 2048 就默认是没有密码的.

生成证书请求文件csr:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@VM_0_6_centos ssl]# openssl req -new -key out.key -out out.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN // 输入国家代码
State or Province Name (full name) []:FJ // 输入省份
Locality Name (eg, city) [Default City]:XM // 输入城市
Organization Name (eg, company) [Default Company Ltd]:XM // 输入组织机构(或公司名
Organizational Unit Name (eg, section) []:XM // 输入机构部门
Common Name (eg, your name or your server's hostname) []:wumingx.com //这里填入证书的域名,如果要生成泛域名证书,要以*.domain.com开头
Email Address []:8@wumingx.com // 你的邮箱地址

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: // 你的证书密码,如果不想设置密码,可以直接回车
An optional company name []:

生成证书:

1
2
3
4
[root@VM_0_6_centos ssl]# openssl x509 -req -days 365 -in out.csr -signkey out.key -out out.crt
Signature ok
subject=/C=CN/ST=FJ/L=XM/O=XM/OU=XM/CN=wumingx.com/emailAddress=8@wumingx.com
Getting Private key

查看证书的有效期以及域名:

1
2
3
4
5
6
7
8
9
10
11
[root@VM_0_6_centos ssl]# openssl x509 -in out.crt -noout -startdate -enddate -subject
notBefore=Sep 12 15:43:58 2020 GMT
notAfter=Sep 12 15:43:58 2021 GMT
subject= /C=CN/ST=FJ/L=XM/O=XM/OU=XM/CN=wumingx.com/emailAddress=8@wumingx.com

// 验证域名是否匹配证书
[root@VM_0_6_centos ssl]# openssl x509 -in out.crt -noout -checkhost wumingx.com
Hostname wumingx.com does match certificate
[root@VM_0_6_centos ssl]#
[root@VM_0_6_centos ssl]# openssl x509 -in out.crt -noout -checkhost www.wumingx.com
Hostname www.wumingx.com does NOT match certificate

acme.sh

由于https的证书是需要费用的,可以使用letsencrypt 生成免费的证书,所以我们可以借助acme.sh来申请泛域名的证书,且可以实现自动更新证书。

安装

安装很简单, 一个命令:

1
curl  https://get.acme.sh | sh

安装过程进行了以下几步:

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

并创建 一个 bash 的 alias, 方便你的使用: alias acme.sh=~/.acme.sh/acme.sh,将这一行写入到.bash_profile即可

2). 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

更高级的安装选项请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-install

安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中: ~/.acme.sh/

生成证书

生成证书有2种方式进行验证,http 和 dns 验证。申请泛域名证书只能通过DNS认证。

1
2
3
4
5
6
7
8
9
10
11
[root@VM_0_6_centos ~]# acme.sh  --issue -d *.wumingx.com -d wumingx.com --webroot /home/wwwroot/wumingx.com/
[Mon Sep 14 22:43:14 CST 2020] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon Sep 14 22:43:14 CST 2020] Creating domain key
[Mon Sep 14 22:43:14 CST 2020] The domain key is here: /root/.acme.sh/*.wumingx.com/*.wumingx.com.key
[Mon Sep 14 22:43:14 CST 2020] Multi domain='DNS:*.wumingx.com,DNS:wumingx.com'
[Mon Sep 14 22:43:14 CST 2020] Getting domain auth token for each domain
[Mon Sep 14 22:43:25 CST 2020] Getting webroot for domain='*.wumingx.com'
[Mon Sep 14 22:43:25 CST 2020] Error, can not get domain token entry *.wumingx.com for http-01
[Mon Sep 14 22:43:25 CST 2020] The supported validation types are: dns-01 , but you specified: http-01
[Mon Sep 14 22:43:25 CST 2020] Please add '--debug' or '--log' to check more details.
[Mon Sep 14 22:43:25 CST 2020] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh

有报错:The supported validation types are: dns-01 , but you specified: http-01

http

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

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

只需要指定域名, 并指定域名所在的网站根目录. acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证. 最后会聪明的删除验证文件. 整个过程没有任何副作用。如果是nginx,可以指定 acme.sh --issue -d mydomain.com --nginx nginx.conf 就可以了,从nginx配置里面自动完验证。

DNS

支持手工和自动的方法,推荐使用自动的方法。以dnspod为例,先申请API。在安全设置,申请API Token。

1
2
3
4
5
申请API之后继续执行申请,acme脚本会使用添加的API自动在DNS服务商处对域名添加TXT记录

export DP_Id="申请的API ID"
export DP_Key="申请的API Key"
~/.acme.sh/acme.sh --issue --dns dns_dp -d *.wumingx.com

以下是操作过程:

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
[root@VM_0_6_centos ~]# export DP_Id="YOU ID"
[root@VM_0_6_centos ~]# export DP_Key="YOU KEY"
[root@VM_0_6_centos ~]# acme.sh --issue --dns dns_dp -d *.wumingx.com -d wumingx.com
[Mon Sep 14 22:51:19 CST 2020] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon Sep 14 22:51:19 CST 2020] Multi domain='DNS:*.wumingx.com,DNS:wumingx.com'
[Mon Sep 14 22:51:19 CST 2020] Getting domain auth token for each domain
[Mon Sep 14 22:51:28 CST 2020] Getting webroot for domain='*.wumingx.com'
[Mon Sep 14 22:51:28 CST 2020] Getting webroot for domain='wumingx.com'
[Mon Sep 14 22:51:28 CST 2020] Adding txt value: mPC7BuynLkelvBKO2gDIAVkzwexIpXghxKFAGxml_kg for domain: _acme-challenge.wumingx.com
[Mon Sep 14 22:51:29 CST 2020] Adding record
[Mon Sep 14 22:51:29 CST 2020] The txt record is added: Success.
[Mon Sep 14 22:51:29 CST 2020] Adding txt value: Vp-lFa0CzR3eIqCbZjgulwN-KG3vCUdYSjmNp4C_aU4 for domain: _acme-challenge.wumingx.com
[Mon Sep 14 22:51:29 CST 2020] Adding record
[Mon Sep 14 22:51:30 CST 2020] The txt record is added: Success.
[Mon Sep 14 22:51:30 CST 2020] Let's check each DNS record now. Sleep 20 seconds first.
[Mon Sep 14 22:51:51 CST 2020] Checking wumingx.com for _acme-challenge.wumingx.com
[Mon Sep 14 22:51:55 CST 2020] Domain wumingx.com '_acme-challenge.wumingx.com' success.
[Mon Sep 14 22:51:55 CST 2020] Checking wumingx.com for _acme-challenge.wumingx.com
[Mon Sep 14 22:51:58 CST 2020] Domain wumingx.com '_acme-challenge.wumingx.com' success.
[Mon Sep 14 22:51:58 CST 2020] All success, let's return
[Mon Sep 14 22:51:58 CST 2020] Verifying: *.wumingx.com
[Mon Sep 14 22:52:08 CST 2020] Success
[Mon Sep 14 22:52:08 CST 2020] Verifying: wumingx.com
[Mon Sep 14 22:52:14 CST 2020] Success
[Mon Sep 14 22:52:14 CST 2020] Removing DNS records.
[Mon Sep 14 22:52:14 CST 2020] Removing txt: mPC7BuynLkelvBKO2gDIAVkzwexIpXghxKFAGxml_kg for domain: _acme-challenge.wumingx.com
[Mon Sep 14 22:52:15 CST 2020] Removed: Success
[Mon Sep 14 22:52:15 CST 2020] Removing txt: Vp-lFa0CzR3eIqCbZjgulwN-KG3vCUdYSjmNp4C_aU4 for domain: _acme-challenge.wumingx.com
[Mon Sep 14 22:52:16 CST 2020] Removed: Success
[Mon Sep 14 22:52:16 CST 2020] Verify finished, start to sign.
[Mon Sep 14 22:52:16 CST 2020] Lets finalize the order.
[Mon Sep 14 22:52:16 CST 2020] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/96628938/5183873632'
[Mon Sep 14 22:52:21 CST 2020] Downloading cert.
[Mon Sep 14 22:52:21 CST 2020] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/0406e69631e78d603c65f61d1527169be11c'
[Mon Sep 14 22:52:22 CST 2020] Cert success.
-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
[Mon Sep 14 22:52:22 CST 2020] Your cert is in /root/.acme.sh/*.wumingx.com/*.wumingx.com.cer
[Mon Sep 14 22:52:22 CST 2020] Your cert key is in /root/.acme.sh/*.wumingx.com/*.wumingx.com.key
[Mon Sep 14 22:52:22 CST 2020] The intermediate CA cert is in /root/.acme.sh/*.wumingx.com/ca.cer
[Mon Sep 14 22:52:22 CST 2020] And the full chain certs is there: /root/.acme.sh/*.wumingx.com/fullchain.cer

完成之后,dnspod的信息会保存在/root/.acme.sh/account.conf,下次就不需要输入了。

有关续约,有如下方法:

  • 手工方法:使用acme.sh --renew --force -d *.wumingx.com 就可以强制更新证书

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    [root@VM_0_6_centos .acme.sh]# acme.sh --renew -d *.wumingx.com --force
    [Wed Sep 16 22:15:34 CST 2020] Renew: '*.wumingx.com'
    [Wed Sep 16 22:15:36 CST 2020] Using CA: https://acme-v02.api.letsencrypt.org/directory
    [Wed Sep 16 22:15:36 CST 2020] Signing from existing CSR.
    [Wed Sep 16 22:15:36 CST 2020] Getting domain auth token for each domain
    [Wed Sep 16 22:15:41 CST 2020] Getting webroot for domain='*.wumingx.com'
    [Wed Sep 16 22:15:41 CST 2020] Getting webroot for domain='wumingx.com'
    [Wed Sep 16 22:15:42 CST 2020] *.wumingx.com is already verified, skip dns-01.
    [Wed Sep 16 22:15:42 CST 2020] wumingx.com is already verified, skip dns-01.
    [Wed Sep 16 22:15:42 CST 2020] Verify finished, start to sign.
    [Wed Sep 16 22:15:42 CST 2020] Lets finalize the order.
    [Wed Sep 16 22:15:42 CST 2020] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/96628938/5216400077'
    [Wed Sep 16 22:15:44 CST 2020] Downloading cert.
    [Wed Sep 16 22:15:44 CST 2020] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/042c57fcab6c76af999a89ac1220a379cd33'
    [Wed Sep 16 22:15:46 CST 2020] Cert success.
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    [Wed Sep 16 22:15:46 CST 2020] Your cert is in /root/.acme.sh/*.wumingx.com/*.wumingx.com.cer
    [Wed Sep 16 22:15:46 CST 2020] The intermediate CA cert is in /root/.acme.sh/*.wumingx.com/ca.cer
    [Wed Sep 16 22:15:46 CST 2020] And the full chain certs is there: /root/.acme.sh/*.wumingx.com/fullchain.cer
  • 定时方法:申请后acme.sh脚本会自动添加一条crontab定时任务,以便脚本自动续期,如果没有自动续期,可以执行以下命令 32 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

之后再配合一些简单的脚本就可以实现https通用证书的部署了。

参考链接

Openssl生成自签名证书,简单步骤

openssl生成CA证书

使用openssl 生成免费证书

acmd.sh官方说明

  • 本文作者: wumingx
  • 本文链接: https://www.wumingx.com/tcpip/openssl-acmesh.html
  • 本文主题: openssl手工生成证书以及acme.sh自动部署证书
  • 版权声明: 本站所有文章除特别声明外,转载请注明出处!如有侵权,请联系我删除。
0%