acme.sh申请免费https证书

默认分类 · 2023-12-06

好久以前就申请了https证书给网站配上了,当时没有做笔记,现在证书快过期了,要重新申请下
顺便记一下https证书的申请流程,免得以后忘了又要重新折腾
申请用的工具是"acme.sh"

项目地址:
https://github.com/acmesh-official/acme.sh

国内镜像:
https://gitee.com/neilpang/acme.sh

准备工作

先git克隆代码到本地,不想配代理可以用国内gitee的镜像

mkdir acme
cd acme
git clone https://gitee.com/neilpang/acme.sh.git

执行安装,邮箱写自己的,默认会安装到~/.acme.sh/目录下

./acme.sh --install -m youremail@domain.com

安装完重新登录终端,执行下acme.sh命令

su
acme.sh

安装成功的话会显示acme.sh的帮助信息

[root@test ~]# acme.sh 
https://github.com/acmesh-official/acme.sh
v3.0.5
Usage: acme.sh <command> ... [parameters ...]
Commands:
  -h, --help               Show this help message.
  -v, --version            Show version info.

申请证书

证书申请需要验证你是否有域名的权限,acme.sh有三种方式验证:

1.在服务器上打开80端口,在网站根目录下放一个文本文件,然后手动将域名指向服务器
2.手动修改域名的dns记录,添加一条指定内容的txt记录
3.使用域名服务商提供的api来自动完成txt记录的添加与删除

因为80端口已经被别的服务占用,加文件麻烦,所以不选1,2的话每次申请手动添加删除也麻烦,所以这里选3
先根据不同的域名服务商来确定需要给acme.sh暴露的环境变量,参考acme.sh的wiki:

How to use DNS API:
https://github.com/acmesh-official/acme.sh/wiki/dnsapi

我这里的域名提供商是GoDaddy,需要暴露下面两个变量

export GD_Key="<key>"
export GD_Secret="<secret>"

申请证书,"--dns"要按自己实际来填,-d的域名一定要加二级域名"example.com",只加三级域名通配"*.example.com"的话,申请到的证书是不包含二级域名example.com

./acme.sh --issue --dns dns_gd -d example.com -d *.example.com

如果你的域名提供商在海外,直连连不上的话,dns记录加不上,证书申请就会失败,就需要设置一个代理服务器来请求提供商的api

export http_proxy=http://host:port
export https_proxy=http://host:port

等待程序执行,看到输出下面的信息时,说明证书申请成功

[Wed Dec  6 11:58:18 CST 2023] Cert success.
[Wed Dec  6 11:58:18 CST 2023] Your cert is in: /root/.acme.sh/example.com/example.com.cer
[Wed Dec  6 11:58:18 CST 2023] Your cert key is in: /root/.acme.sh/example.com/example.com.key
[Wed Dec  6 11:58:18 CST 2023] The intermediate CA cert is in: /root/.acme.sh/example.com/ca.cer
[Wed Dec  6 11:58:18 CST 2023] And the full chain certs is there: /root/.acme.sh/example.com/fullchain.cer

这时候就可以在对应的目录下找到申请的证书了

也可以敲命令查看申请到的证书的相关信息

acme.sh --info -d example.com

配置nginx使用证书

复制或者直接改名下列两个证书文件

fullchain.cer -> cert.pem
example.com.key -> key.pem

修改nginx的配置文件
首先强制80端口http跳转443端口https,当然也可以不做

server {
    listen 80;
    rewrite ^(.*)$ https://$host$1 permanent;
}

加上证书,我这里不同的站点拆分到不同的文件中进行配置了,所以证书就配在主配置文件里了

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    gzip  on;

    server_tokens off;

    ssl_certificate      /etc/nginx/cert/example.com/cert.pem;
    ssl_certificate_key  /etc/nginx/cert/example.com/key.pem;

    include /etc/nginx/conf.d/*.conf;
}

贴一个子域名的反代配置在这里

server {
    listen       443;
    server_name  subdomain.domain.com;

    location / {
        proxy_pass http://0.0.0.0:9999;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
Theme Jasmine by Kent Liao