工具、教程收藏 · 2018年3月21日

Linux 下使用 acme.sh 配置 Let's Encrypt 免费 SSL 证书 + 通配符证书

1、什么是 SSL 证书?

SSL 是保护用户数据和防止身份被盗用的最佳方式。拥有 SSL 证书的网站可以告诉用户,他们可以放心的浏览,SSL 可以保护他们的数据安全。不同的 SSL 证书提供不同级别的验证。了解更多 >
目前比较火的适合个人用户的证书就是 Let’s Encrypt,这货是免费的,下面我们就介绍一下如何在 Linux 服务器上配置 SSL 证书

2、使用 acme.sh 安装 Let’s Encrypt 证书

Let’s Encrypt 提供很多方式,网上也有不少教程,但是都不方便操作,下面我们就介绍一款国人写的开源脚本 acme.sh
首先,进入服务器后获取 acme.sh 脚本,此操作不一定需要 root 用户登陆
使用 curl 方式获取,系统需要安装 curl 软件

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

你也可以使用 wget 方式

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

更多安装方式请这儿
因为这货的脚本服务器放在了 Google Cloud Platform,国内服务器操作偶尔会抽风,解决方法的话,要么挂代理,要么选择大半夜网络好的时候
接着重新加载 Bash

source ~/.bashrc

输入 acme.sh --help 即可查看 acme.sh 的帮助命令

root@sb-blog ~ # acme.sh --help
https://github.com/Neilpang/acme.sh
v2.7.8
Usage: acme.sh  command ...[parameters]....
Commands:
  --help, -h               Show this help message.
  --version, -v            Show version info.
  --install                Install acme.sh to your system.
  --uninstall              Uninstall acme.sh, and uninstall the cron job.
  --upgrade                Upgrade acme.sh to the latest code from https://github.com/Neilpang/acme.sh.
  --issue                  Issue a cert.
  --signcsr                Issue a cert from an existing csr.
  --deploy                 Deploy the cert to your server.
  --install-cert           Install the issued cert to apache/nginx or any other server.
  --renew, -r              Renew a cert.
  --renew-all              Renew all the certs.
  --revoke                 Revoke a cert.
  --remove                 Remove the cert from list of certs known to acme.sh.
  --list                   List all the certs.
  --showcsr                Show the content of a csr.
  --install-cronjob        Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job.
  --uninstall-cronjob      Uninstall the cron job. The 'uninstall' command can do this automatically.
  --cron                   Run cron job to renew all the certs.
  --toPkcs                 Export the certificate and key to a pfx file.
  --toPkcs8                Convert to pkcs8 format.
  --update-account         Update account info.
  --register-account       Register account key.
  --deactivate-account     Deactivate the account.
  --create-account-key     Create an account private key, professional use.
  --create-domain-key      Create an domain private key, professional use.
  --createCSR, -ccsr       Create CSR , professional use.
  --deactivate             Deactivate the domain authz, professional use.

Parameters:
  --domain, -d   domain.tld         Specifies a domain, used to issue, renew or revoke etc.
  --challenge-alias domain.tld      The challenge domain alias for DNS alias mode: https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode
  --domain-alias domain.tld         The domain alias for DNS alias mode: https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode
  --force, -f                       Used to force to install or force to renew a cert immediately.
  --staging, --test                 Use staging server, just for test.
  --debug                           Output debug info.
  --output-insecure                 Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for secure.
  --webroot, -w  /path/to/webroot   Specifies the web root folder for web root mode.
  --standalone                      Use standalone mode.
  --stateless                       Use stateless mode, see: https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode
  --apache                          Use apache mode.
  --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file]   Use dns mode or dns api.
  --dnssleep  [120]                  The time in seconds to wait for all the txt records to take effect in dns api mode. Default 120 seconds.

  --keylength, -k [2048]            Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384.
  --accountkeylength, -ak [2048]    Specifies the account key length.
  --log    [/path/to/logfile]       Specifies the log file. The default is: "/root/.acme.sh/acme.sh.log" if you don't give a file path here.
  --log-level 1|2                   Specifies the log level, default is 1.
  --syslog [0|3|6|7]                Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
  These parameters are to install the cert to nginx/apache or anyother server after issue/renew a cert:
  --cert-file                       After issue/renew, the cert will be copied to this path.
  --key-file                        After issue/renew, the key will be copied to this path.
  --ca-file                         After issue/renew, the intermediate cert will be copied to this path.
  --fullchain-file                  After issue/renew, the fullchain cert will be copied to this path.
  --reloadcmd "service nginx reload" After issue/renew, it's used to reload the server.

  --server SERVER                   ACME Directory Resource URI. (default: https://acme-v01.api.letsencrypt.org/directory)
  --accountconf                     Specifies a customized account config file.
  --home                            Specifies the home dir for acme.sh .
  --cert-home                       Specifies the home dir to save all the certs, only valid for '--install' command.
  --config-home                     Specifies the home dir to save all the configurations.
  --useragent                       Specifies the user agent string. it will be saved for future use too.
  --accountemail                    Specifies the account email, only valid for the '--install' and '--update-account' command.
  --accountkey                      Specifies the account key path, only valid for the '--install' command.
  --days                            Specifies the days to renew the cert when using '--issue' command. The max value is 60 days.
  --httpport                        Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
  --local-address                   Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
  --listraw                         Only used for '--list' command, list the certs in raw format.
  --stopRenewOnError, -se           Only valid for '--renew-all' command. Stop if one cert has error in renewal.
  --insecure                        Do not check the server certificate, in some devices, the api server's certificate may not be trusted.
  --ca-bundle                       Specifies the path to the CA certificate bundle to verify api server's certificate.
  --ca-path                         Specifies directory containing CA certificates in PEM format, used by wget or curl.
  --nocron                          Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically.
  --no-color                        Do not output color text.
  --ecc                             Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
  --csr                             Specifies the input csr.
  --pre-hook                        Command to be run before obtaining any certificates.
  --post-hook                       Command to be run after attempting to obtain/renew certificates. No matter the obtain/renew is success or failed.
  --renew-hook                      Command to be run once for each successfully renewed certificate.
  --deploy-hook                     The hook file to deploy cert
  --ocsp-must-staple, --ocsp        Generate ocsp must Staple extension.
  --always-force-new-domain-key     Generate new domain key when renewal. Otherwise, the domain key is not changed by default.
  --auto-upgrade   [0|1]            Valid for '--upgrade' command, indicating whether to upgrade automatically in future.
  --listen-v4                       Force standalone/tls server to listen at ipv4.
  --listen-v6                       Force standalone/tls server to listen at ipv6.
  --openssl-bin                     Specifies a custom openssl bin location.
  --use-wget                        Force to use wget, if you have both curl and wget installed.

然后可以执行 acme.sh --upgrade --auto-upgrade 获取 acme.sh 更新,并设置之后都自动更新 acme.sh 脚本

3、获取 Let’s Encrypt 证书

如果你本地没有装任何 Web 服务器软件,或者你的 Web 服务器软件并没有监听 TCP 80 端口,那么可以用 Standalone 方式直接获取多域名证书,注意以下操作必须使用 root 或 sudo 切换
我们以 example.com / www.example.com / subdomain.example.com 这三个域名为例
首先,你需要把这三个域名都解析到你的服务器 IPv4 上,并且确保你的服务器可以访问公网,无法访问公网的内网服务器是不行的
另外,你也可以给 example.com 增加一个 CAA 记录为 0 issue "letsencrypt.org" 这样可以告诉 Let’s Encrypt 的 CA ,你授权给他们签发 SSL 证书

acme.sh --issue --standalone -d example.com -d www.example.com -d subdomain.example.com

通过这个方式,即可为 example.com www.example.com 和 subdomain.example.com 三个域名签发一张多域名证书
但是一般情况下,我们都装了 Web 服务器,并且安装了 SSL 以后很多用户选择 http 跳转到 https,所以你需要确保 Let’s Encrypt 能访问 80 端口下的 /.well-known/acme-challenge 目录,我们以 Nginx 为例
以下操作之前可以通过本站的教程安装 LEMP
Debian 9 / Debian 8 使用源安装 LEMP 教程
Ubuntu 16.04 / Ubuntu 14.04 使用源安装 LEMP 教程
CentOS / RHEL 7 使用 EPEL 安装 LEMP 教程
Linux 下编译安装最新版本 Nginx
首先建立一个 /var/www/letsencrypt 目录

mkdir -p /var/www/letsencrypt

然后修改 /etc/nginx/sites-enabled/default 文件

server {
	listen 80 default_server;
	listen [::]:80 default_server;
	server_name _;
	location /.well-known/acme-challenge {
		root /var/www/letsencrypt;
	}
	location / {
		return 301 https://$host$request_uri;
	}
}

这段话的意思是,所有访问 80 端口的请求,都自动跳转到 https ,但是 /.well-known/acme-challenge 这个目录仍然可以通过 80 端口进行访问
然后重启 Nginx

nginx -t && nginx -s reload

接下来给 example.com www.example.com 和 subdomain.example.com 三个域名签发一张多域名证书

acme.sh --issue -d example.com -d www.example.com -d subdomain.example.com -w /var/www/letsencrypt

如果没有问题,就会看到如下结果

root@example ~ # acme.sh --issue -d example.com -d www.example.com -w /var/www/letsencrypt
[Tue Mar 20 15:50:37 HKT 2018] Domains have changed.
[Tue Mar 20 15:50:37 HKT 2018] Multi domain='DNS:example.com,DNS:www.example.com'
[Tue Mar 20 15:50:37 HKT 2018] Getting domain auth token for each domain
[Tue Mar 20 15:50:37 HKT 2018] Getting webroot for domain='example.com'
[Tue Mar 20 15:50:37 HKT 2018] Getting new-authz for domain='example.com'
[Tue Mar 20 15:50:38 HKT 2018] The new-authz request is ok.
[Tue Mar 20 15:50:38 HKT 2018] Getting webroot for domain='www.example.com'
[Tue Mar 20 15:50:38 HKT 2018] Getting new-authz for domain='www.example.com'
[Tue Mar 20 15:50:39 HKT 2018] The new-authz request is ok.
[Tue Mar 20 15:50:39 HKT 2018] example.com is already verified, skip http-01.
[Tue Mar 20 15:50:39 HKT 2018] Verifying:www.example.com
[Tue Mar 20 15:50:43 HKT 2018] Success
[Tue Mar 20 15:50:43 HKT 2018] Verify finished, start to sign.
[Tue Mar 20 15:50:44 HKT 2018] Cert success.
-----BEGIN CERTIFICATE-----
这里一长串就是证书文件输出
-----END CERTIFICATE-----
[Tue Mar 20 15:50:44 HKT 2018] Your cert is in  /root/.acme.sh/example.com/example.com.cer
[Tue Mar 20 15:50:44 HKT 2018] Your cert key is in  /root/.acme.sh/example.com/example.com.key
[Tue Mar 20 15:50:45 HKT 2018] The intermediate CA cert is in  /root/.acme.sh/example.com/ca.cer
[Tue Mar 20 15:50:45 HKT 2018] And the full chain certs is there:  /root/.acme.sh/example.com/fullchain.cer

签发完成后,我们可以安装到 Nginx
为了进后方便维护,我们建立一个 /etc/nginx/ssl 目录用来放证书

mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com \
--key-file       /etc/nginx/ssl/example.com.key  \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd     "service nginx force-reload"

不管多域名证书里有几个域名,这里的 -d 参数只需要带第一个域名即可
如果是 Apache 2.4.8 以上版本的话,可以使用这个命令

acme.sh --install-cert -d example.com \
--key-file       /etc/apache2/ssl/example.com.key  \
--fullchain-file /etc/apache2/ssl/example.com.crt \
--reloadcmd     "service apache2 force-reload"

这样 SSL 证书就已经获取完毕并且加入了自动更新

4、配置 Nginx 或 Apache

这部分教程网站实在太多,本文不做一一描述,直接贴上我们推荐的配置文件

4.1、Nginx 配置

以下版本适用于 Nginx 1.10+ 默认开启了 HTTP/2.0 和 HSTS Preload 支持
首先我们生成 DHE 参数文件,这货是迪菲-赫尔曼密钥交换,一种灰常强大的安全协议

openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

然后编辑 /etc/nginx/sites-enable/example.com.conf

server {
	listen 443 ssl http2 default_server;
	listen [::]:443 ssl http2 default_server;
	server_name example.com;
	root /var/www/example.com;
	index index.html index.htm index.php;
# 我们采用强大的迪菲-赫尔曼密钥交换,生成命令 openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
	ssl_dhparam /etc/nginx/ssl/dhparam.pem;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
	ssl_prefer_server_ciphers on;
	ssl_session_cache shared:SSL:50m;
	ssl_session_timeout 1d;
# 如果你 Nginx 配置了 SNI 即多个站点,多个证书,则需要用到如下配置,先生成文件 openssl rand 48 > /etc/nginx/ssl/session_ticket.key
#	ssl_session_ticket_key     /etc/nginx/ssl/session_ticket.key;
#	ssl_session_tickets        off;

# 如果需要开启 OSCP 功能,则需要加入
#	ssl_stapling               on;
#	ssl_stapling_verify        on;
# ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
#	resolver                   8.8.8.8 8.8.4.4 valid=300s;
#	resolver_timeout           10s;

# 此处是证书文件

	ssl_certificate /etc/nginx/ssl/example.com.crt;
	ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 开启 HSTS Preload 支持

	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
	add_header X-Frame-Options SAMEORIGIN;
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
# 开启 PHP7.2-fpm 模式,如需要安装 PHP 7.1.x 请修改为 fastcgi_pass unix:/run/php/php7.1-fpm.sock;
#	location ~ \.php$ {
#	  include snippets/fastcgi-php.conf;
#    fastcgi_pass unix:/run/php/php7.2-fpm.sock;
#  }

	access_log /var/log/nginx/example.com.access.log;
	error_log /var/log/nginx/example.com.error.log;
}

注意 ssl_ciphers 的配置,这里贴的配置适合大多数的浏览器,最低浏览器支持是 Firefox 1, Chrome 1, IE 7, Opera 5, Safari 1, Windows XP IE8, Android 2.3, Java 7
如果需要更老的浏览器支持,可以改成

ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP';
ssl_prefer_server_ciphers on;

此方案适合最低 IE6, Java 6 但是我们强烈不推荐,因为漏洞太多, SSLv3 目前已经基本被淘汰,参考 #1 #2
当然如果需要激进一点,可以改成

ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;

此方案最低浏览器支持是 Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, and Java 8
再激进一点的,就要用 TLSv1.3 了,坐等各种浏览器都支持吧
然后检查配置并重启 Nginx

nginx -t && nginx -s reload

4.2、Apache 2.4 配置

<VirtualHost *:80>
  ServerName example.com
  Redirect permanent / https://example.com/
</VirtualHost>
LoadModule headers_module modules/mod_headers.so
<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile      /etc/apache2/ssl/example.com.crt
    SSLCertificateKeyFile   /etc/apache2/ssl/example.com.key
    # Uncomment the following directive when using client certificate authentication
    #SSLCACertificateFile    /path/to/ca_certs_for_client_authentication

    # HSTS (mod_headers is required) (15768000 seconds = 6 months)
    Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
    Header always set X-Frame-Options SAMEORIGIN
    Header always set X-Content-Type-Options nosniff
    Header set X-XSS-Protection "1; mode=block"
</VirtualHost>
# intermediate configuration, tweak to your needs
SSLProtocol             all -SSLv3
SSLCipherSuite          ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
SSLHonorCipherOrder     on
SSLCompression          off
SSLSessionTickets       off
# OCSP Stapling, only in httpd 2.3.3 and later
# SSLUseStapling          on
# SSLStaplingResponderTimeout 5
# SSLStaplingReturnResponderErrors off
# SSLStaplingCache        shmcb:/var/run/ocsp(128000)

以上 Apache 2.4 的配置并不完整,需要你根据实际情况调整,更多服务器软件的 SSL 配置可以参考 Mozilla SSL Configuration Generator
配置完成后重启 Apache 2.4

service apache2 reload

另外,开启了 HSTS Preload 后,可以去 HSTS Preload List Submission 检查并且提交你的网站,这样以后的各种浏览器就会把你的网址加入到 HSTS Preload List 访问 example.com 的时候就不需要额外去请求 80 端口了

5、获取 Let’s Encrypt 通配符证书

通配符证书,英文 Wildcard Certificate 国内黑话叫做野卡,经过一个月的跳票后,Let’s Encrypt 目前已经支持通配符的证书,同样 acme.sh 也是支持的,和多域名证书不同,通配符证书必须使用 DNS TXT 记录验证方式,我们以 example.com 和 *.example.com 为例

acme.sh --issue -d example.com -d '*.example.com' --dns

如果你的 DNS 提供商支持 API,你也可以直接使用 API 而不需要手工修改 TXT 记录,详细用法请见这里
然后会看到如下的输出

root@example ~ # acme.sh --issue -d example.com -d '*.example.com' --dns
[Tue Mar 20 16:34:35 HKT 2018] Domains have changed.
[Tue Mar 20 16:34:35 HKT 2018] Registering account
[Tue Mar 20 16:34:36 HKT 2018] Registered
[Tue Mar 20 16:34:36 HKT 2018] ACCOUNT_THUMBPRINT='blablablabla'
[Tue Mar 20 16:34:36 HKT 2018] Multi domain='DNS:example.com,DNS:*.example.com'
[Tue Mar 20 16:34:36 HKT 2018] Getting domain auth token for each domain
[Tue Mar 20 16:34:38 HKT 2018] Getting webroot for domain='example.com'
[Tue Mar 20 16:34:38 HKT 2018] Getting webroot for domain='*.example.com'
[Tue Mar 20 16:34:38 HKT 2018] Add the following TXT record:
[Tue Mar 20 16:34:38 HKT 2018] Domain: '_acme-challenge.example.com'
[Tue Mar 20 16:34:38 HKT 2018] TXT value: 'blablablabla1'
[Tue Mar 20 16:34:38 HKT 2018] Please be aware that you prepend _acme-challenge. before your domain
[Tue Mar 20 16:34:38 HKT 2018] so the resulting subdomain will be: _acme-challenge.example.com
[Tue Mar 20 16:34:38 HKT 2018] Add the following TXT record:
[Tue Mar 20 16:34:38 HKT 2018] Domain: '_acme-challenge.example.com'
[Tue Mar 20 16:34:38 HKT 2018] TXT value: 'blablablabla2'
[Tue Mar 20 16:34:38 HKT 2018] Please be aware that you prepend _acme-challenge. before your domain
[Tue Mar 20 16:34:38 HKT 2018] so the resulting subdomain will be: _acme-challenge.example.com
[Tue Mar 20 16:34:38 HKT 2018] Please add the TXT records to the domains, and re-run with --renew.
[Tue Mar 20 16:34:38 HKT 2018] Please add '--debug' or '--log' to check more details.
[Tue Mar 20 16:34:38 HKT 2018] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

接着你需要给 _acme-challenge.example.com 增加两个 TXT 记录 "blablablabla1" 和 "blablablabla2",然后慢慢等 DNS 生效

root@example ~ # dig TXT _acme-challenge.example.com @9.9.9.9 +short
"blablablabla1"
"blablablabla2"

生效后给证书续一秒

acme.sh --renew -d example.com -d '*.example.com'

输出如下

root@example ~ # acme.sh --renew -d example.com -d '*.example.com' --force
[Tue Mar 20 16:41:25 HKT 2018] Renew: 'example.com'
[Tue Mar 20 16:41:26 HKT 2018] Multi domain='DNS:example.com,DNS:*.example.com'
[Tue Mar 20 16:41:26 HKT 2018] Getting domain auth token for each domain
[Tue Mar 20 16:41:26 HKT 2018] Verifying:example.com
[Tue Mar 20 16:41:29 HKT 2018] Success
[Tue Mar 20 16:41:29 HKT 2018] Verifying:*.example.com
[Tue Mar 20 16:41:32 HKT 2018] Success
[Tue Mar 20 16:41:32 HKT 2018] Verify finished, start to sign.
[Tue Mar 20 16:41:33 HKT 2018] Cert success.
-----BEGIN CERTIFICATE-----
这里是证书文件
-----END CERTIFICATE-----
[Tue Mar 20 16:41:33 HKT 2018] Your cert is in  /root/.acme.sh/example.com/example.com.cer
[Tue Mar 20 16:41:33 HKT 2018] Your cert key is in  /root/.acme.sh/example.com/example.com.key
[Tue Mar 20 16:41:33 HKT 2018] The intermediate CA cert is in  /root/.acme.sh/example.com/ca.cer
[Tue Mar 20 16:41:33 HKT 2018] And the full chain certs is there:  /root/.acme.sh/example.com/fullchain.cer
[Tue Mar 20 16:41:33 HKT 2018] It seems that you are using dns manual mode. please take care: The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead.
[Tue Mar 20 16:41:33 HKT 2018] Call hook error.

然后就可以参考上面的 Nginx 或 Apache 2.4 的配置,这里不再重复
理论上按照本站的 Nginx 配置教程配置完成后, SSL Lab 得分都会在 A+,参考本站的得分,限于篇幅,我们之后会再介绍 Nginx 下 SSL 配置的更详细教程,如有疑问请随时进讨论
 
原文:https://sb.sb/blog/linux-acme-sh-lets-encrypt-ssl/