安装

安装 acme.sh

curl https://get.acme.sh | sh -s email=xg.song@qq.com

这个命令会把 acme.sh 安装到你的用户目录下,并设为隐藏,你可以在安装完成之后通过 ls -a 来检查是否有名为 .acme.sh 目录。

注意❗

在安装完成之后你可能需要执行 alias acme.sh=~/.acme.sh/acme.sh 创建 一个 bash 的 alias。否则会报错 -bash: acme.sh: command not found

生成证书

官方提供的证书认证方式有三种

  • http 方式需要在你的网站根目录下放置一个文件,来验证你的域名所有权,完成验证。然后就可以生成证书了
  • 手动 dns 方式,手动在域名上添加一条 txt 解析记录,验证域名所有权.
  • 可以使用域名解析商提供的 api 自动添加 txt 记录完成验证.

手动DNS

acme.sh 实现了 acme 协议支持的所有验证协议,一般有两种方式验证: http 和 dns 验证。由于泛域名证书的解析目前仅支持 DNS 方式验证,下面我们将通过 DNS 方式来验证你的域名所有权。

acme.sh --issue -d songxingguo.com -d *.songxingguo.com --dns \
 --yes-I-know-dns-manual-mode-enough-go-ahead-please

这种方式会将相应的解析记录显示出来,然后你需要在你的域名管理面板中添加这条 txt 记录。并等待解析完成之后,重新用下面命令生成证书:

acme.sh --renew -d songxingguo.com -d *.songxingguo.com --dns \
 --yes-I-know-dns-manual-mode-enough-go-ahead-please

注意❗

注意第二次这里用的是 --renew,当然我们并不想这么麻烦,dns 方式的真正强大之处在于可以使用域名解析商提供的 api 自动添加 txt 记录完成验证。

自动DNS

利用域名解析商提供的 API 让 acme.sh 自动进行相关的验证操作。acme.sh 目前支持 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等数十种解析商的自动集成。

获取 DNS 服务商 token

根据你的域名服务商类型,选择对应的 DNS API。如

1、腾讯云

在 这里申请 API Token,获取到 ID 及 Token 后执行:

然后,设置 DNSPod token

通过在命令行里执行以下命令设置 token,要严格按格式来, DP_Id 后的 = 号前后不能有空格。 DP_Id 为 DNSPod 里生成的 id , DP_Key 为生成的 token

export DP_Id="" 
export DP_Key=""

2、DNSPod

这里就详细说下 DNSPod 怎么获取 token。

  • 登录 DNSPod 后台
  • 点击右上角自己的头像
  • 点击左侧选项卡伤的的 DNSPod Tokens
  • 点击 创建密钥 后起个名字,接着就能拿到 ID 和 token 值,另外注意,Token 值只显示一次,请记好备份。

然后,设置 DNSPod token同上。

3、阿里云

这里申请阿里云 Accesskey

获取到 KEY 及 Secret 后执行下面命令:

export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"

生成证书

生成证书,这里一定要先添加主域名,再添加泛域名。我们可以通过 -d 来添加多个域名。域名证书生成成功后,默认保存在 .acme.sh/你的顶级域名 中。

acme.sh --issue --dns dns_dp -d songxingguo.com -d *.songxingguo.com

这种方式将自动为你的域名添加一条 txt 解析,验证成功后,这条解析记录会被删除,所以对你来说是无感的,就是要等 120秒

安装证书到指定目录

注意❗

注意,默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件,例如:不要直接让 nginx/apache 的配置文件使用这下面的文件。这里面的文件都是内部使用,而且目录结构可能会变化.

我们需要通过 --install-cert 来安装证书文件,使用官方的这种方式以后可以自动无感续期、自动更新等。官

acme.sh --install-cert -d songxingguo.com \
--key-file       /etc/nginx/ssl/songxingguo.key  \
--fullchain-file /etc/nginx/ssl/fullchain.cer \
--reloadcmd     "service nginx force-reload"

或是手动拷贝。

cp ~/.acme.sh/songxingguo.com_ecc/fullchain.cer /etc/nginx/ssl/fullchain.cer
cp ~/.acme.sh/songxingguo.com_ecc/songxingguo.com.key /etc/nginx/ssl/songxingguo.key

注意❗

一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload

这样在指定目录会自动生成对应的证书文件,接下来我们在 Nginx 配置文件里进行引用就行了。

续期

我们前面在安装 acme.sh 的时候默认会自动生成一个 crontab 任务,我们可以通过 crontab -l 查看。默认的计划任务是每天检查一次是否需要续期,如果需要则会自动续期,当然你也可以自由设置任务,crontab 示例配置如下:

56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

Nginx 配置文件

# /etc/nginx/snippets/ssl-params.conf
 
server_tokens   off;
 
ssl_session_cache        shared:SSL:10m;
ssl_session_timeout      60m;
 
ssl_session_tickets      on;
 
ssl_stapling             on;
ssl_stapling_verify      on;
 
resolver                 8.8.4.4 8.8.8.8  valid=300s;
resolver_timeout         10s;
ssl_prefer_server_ciphers on;
 
# 证书路径 绝对地址
ssl_certificate          /etc/nginx/ssl/fullchain.cer;
ssl_certificate_key      /etc/nginx/ssl/songxingguo.key;
 
ssl_protocols            TLSv1 TLSv1.1 TLSv1.2;
 
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
 
add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload";
add_header  X-Frame-Options  deny;
add_header  X-Content-Type-Options  nosniff;
add_header x-xss-protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https:; connect-src 'self' https:; img-src 'self' data: https: blob:; style-src 'unsafe-inline' https:; font-src https:";

接下来再新建一个 nginx 配置文件,并配置 server 项,并在 server 项里通过 include 命令导入我们之前写的 ssl 配置代码段即可。

server {
    listen 443 ssl;
    server_name test.yourdomain.com;
    
    include snippets/ssl-params.conf;
 
  location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $http_host;
      proxy_pass http://127.0.0.1:15215;
 
      # 如果您要使用本地存储策略,请将下一行注释符删除,并更改大小为理论最大文件尺寸
      # client_max_body_size 20000m;
  }
 
 
    location ~ /.well-known {
        allow all;
    }
 
    client_max_body_size 50m;
}

扩展阅读