使用acme.sh生成免费https证书
主要特性:
- 纯shell脚本开发,其完整实现了acme协议,无过多依赖
- 支持ECDSA证书
- 支持泛域名证书
- 兼容Bash、dash、sh
- 支持自动续期,定时任务续期提醒
- 简单易上手
- 不会修改web服务器配置,需自行配置
It’s probably the easiest & smartest shell script to automatically issue & renew the free certificates.
安装
直接通过curl下载安装脚本并自动执行:
1 | curl https://get.acme.sh | sh -s email=my@example.com |
或者:
1 | wget -O - https://get.acme.sh | sh -s email=my@example.com |
中国区如果无法安装可以克隆项目的github或gitee地址
1 | git clone --depth 1 https://github.com/acmesh-official/acme.sh.git |
安装完后需要source环境变量,或者重开一个终端才能使用acme.sh
命令。
acme.sh程序安装在用户目录,以root用户为例,目录在/root/.acme.sh
,安装成功后会自动创建定时任务,用于更新即将过期的证书。
生成证书
切换CA
如果不想用zero ssl,可以切换默认CA为Let’s Encrypt:
1 | acme.sh --set-default-ca --server letsencrypt |
常见的验证模式
webroot模式
webroot模式要求在服务器上已经运行了http服务,并且可以通过公网访问,该模式的好处是,你无需在申请证书的过程中停止web服务,因此,该模式也是推荐使用的模式。验证完毕后,acme.sh会清除这些临时生成的文件。
1 | acme.sh --issue -d example.com -w /home/webroot |
申请证书时如果报无法验证的错误,请在nginx 域名配置文件domain.conf
server里面加上这段配置:
1 | location ^~ /.well-known/acme-challenge/ { |
nginx模式
acme.sh会在域名验证完毕后自动将nginx配置还原,不会修改用户的设置
1 | acme.sh --issue --nginx -d example.com |
另外acme可能无法识别nginx配置文件位置,此时可以指定nginx配置文件目录
1 | acme.sh --issue -d example.com --nginx /etc/nginx/nginx.conf |
DNS自动模式
这种模式可以使用域名解析商提供的api自动为域名添加txt记录以完成域名所有权验证,不同于DNS手动模式,DNS自动模式支持自动更新证书。这也是我推荐使用的模式,因为我要生成泛域名证书。
acme.sh目前支持cloudflare,dnspod,aliyun,cloudxns,godaddy以及ovh等数十种解析商,具体可查看~/.acme.sh/dnsapi
目录,不会的看这里:如何使用DNS API获取证书
以阿里云为例:
登录DNS服务商控制台,获取AccessKeyId和AccessKeySecret,地址:https://ram.console.aliyun.com/manage/ak。
添加环境变量,vim
~/.bashrc
1 | export Ali_Key="<key>" |
- 生成泛域名证书
1 | # 只适用dns模式 |
证书生成成功后会有SUCCESS提示
生成ECC证书
目前大部分的证书都是使用RSA非对称加密算法,但一些CA,例如letsencryption、zerossl等,已经支持颁发性能更加优良的ECC非对称加密算法证书。
1 | acme.sh --issue -d example.com -d example1.com --dns dns_ali --keylength ec-256 |
keylength可用的值有:
- ec-256 (prime256v1, “ECDSA P-256”, which is the default key type)
- ec-384 (secp384r1, “ECDSA P-384”)
- ec-521 (secp521r1, “ECDSA P-521”, which is not supported by Let’s Encrypt yet.)
- 2048 (RSA2048)
- 3072 (RSA3072)
- 4096 (RSA4096)
生成ecc泛域名证书
1 | # 引号不能忽略 |
生成证书失败
这三种模式我都用过,其中使用nginx或webroot模式,可能会失败,出现如下错误:
1 | ... |
这时推荐把ca切换到letsencrypt,并且升级acme版本,重新申请后如果还是同样错误,建议使用dns模式。
部署证书
部署前必须自己更新nginx配置
1 | server { |
检查无误后我们可以通过--install-cert
参数复制证书文件到nginx指定目录
1 | acme.sh --install-cert -d example.com --key-file /etc/nginx/cert/example.com.key --fullchain-file /etc/nginx/cert/example.com.fullchain.cer --reloadcmd "service nginx force-reload" |
reloadcmd是用于重新加载配置,由于reload不会加载证书,所以需要force-reload,它其实是先stop再start,也可以restart,如果nginx没有注册成service,可以指定其路径。
acme有一个好处是它会记录一些命令中的信息,用于未来自动更新证书,它存储在这里:
1 | ~/.acme.sh/example.com/example.com.conf |
查看证书
列出已生成的证书
1 | acme.sh --list |
命令打印如下信息,最后一列Renew表示证书下一次更新的时间
1 | Main_Domain KeyLength SAN_Domains CA Created Renew |
1 | # 查看证书具体信息 |
更新证书
默认情况下acme.sh会自动更新即将过期的证书,不过我们可以手动更新
1 | acme.sh --renew -d example.com |
更新acme.sh
1 | acme.sh --upgrade |