等一下,等一下。

突然发现证书过期后需要重启nginx才能正确载入新证书,目前还没想到怎么处理。

为了能在更新证书之后自动重新载入nginx服务器,这里用到了letsencrypt.sh脚本的HOOK功能:

  1. 将 doc/example/hook.sh 复制一份
  2. 在 deploy_cert 函数中添加对应的功能处理脚本,我这里则是 systemctl restart nginx.service
    #附参考如下
    function deploy_cert {
        local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
        ln -s $FULLCHAINFILE {your full chain file}
        ln -s $KEYFILE {your privkey file}
        systemctl restart nginx.service
        # This hook is called once for each certificate that has been
        # produced. Here you might, for instance, copy your new certificates
        # to service-specific locations and reload the service.
        #
        # Parameters:
        # - DOMAIN
        #   The primary domain name, i.e. the certificate common
        #   name (CN).
        # - KEYFILE
        #   The path of the file containing the private key.
        # - CERTFILE
        #   The path of the file containing the signed certificate.
        # - FULLCHAINFILE
        #   The path of the file containing the full certificate chain.
        # - CHAINFILE
        #   The path of the file containing the intermediate certificate(s).
        # - TIMESTAMP
        #   Timestamp when the specified certificate was created.
    }
  3. 最后,cronjob的指令需要添加参数:–hook (-k) path/to/hook.sh

=========

letsencrypt是一个提供免费域名SSL证书的服务商,大腿很粗。我很早就拿到内测资格了,只是原版Letsencrypt依赖吓死人,使用超级不方便所以就没有及早使用。后来替代选择就多了,使用就方便多了。

我选择的是[https://github.com/lukas2511/letsencrypt.sh]的bash脚本,只依赖openssl,curl和sed,基本算是开箱即用。

Letsencrypt通过验证域名下某个特定uri的内容来验证域名所有权,再依据你的私钥来签发SSL证书(aes,暂不支持ecc)。各路脚本都是使用官方的API来实现这一过程。上述脚本也不例外,下面简要介绍操作步骤:

1. 使用git(或者其他方式)将上述脚本文件(夹)放置到服务器中,并使其拥有执行权限。

git clone https://github.com/lukas2511/letsencrypt.sh && chmod -R +x letsencrypt.sh/

2. 复制脚本目录下config.sh.sample文件为config.sh,将其中的参数依据实际需要修改:

主要是以下两个参数可能需要修改:

  1. BASEDIR:该参数指定的文件夹放置domain.txt配置文件,私钥和最终生成的证书文件。默认为脚本所在目录。
  2. WELLKNOWN:该参数指定的文件夹放置供Letsencrypt验证的文件

注意执行脚本的用户对上述路径应有读写权限,web服务器运行用户需要对WELLKNOWN参数对应的路径有读权限。简单方便的方法是,用web服务器用户执行脚本。

3. 在BASEDIR指定的文件夹中建立domains.txt文件,该文件指定需要签发证书的域名,结构如下:

#每个根域名占一行,二级域名之间用空格分隔

example.org www.example.org

example.com www.example.com wiki.example.com

4. 需要将对应域名的“/.well-known/acme-challenge”链接指向WELLKNOWN参数指定的目录

以nginx配置为例,在“所有”需要签发证书的域名的server区块添加如下配置:

location /.well-known/acme-challenge {

alias $WELLKNOWN; # $WELLKNOWN为你配置的WELLKNOWN参数指向的目录

}

 

只需要为http访问提供该链接,Letsencrypt会且仅会使用http方式访问此链接,所以请保证该链接一直有效。nginx对完整路径的location匹配优先级最高,所以不会干扰你的其他配置。

5. 执行脚本

./letsencrypt.sh -c

如果一切良好,你就会在$WELLKNOWN/certs/your domain目录下得到一系列的文件:

pems

其中的fullchain.pem和privkey.pem就是我们所需要的对应域名的证书(和私钥)了。

6. 最后,你需要在对应域名的server区块添加对前面获得的证书和私钥的引用:

server{
    listen 443 ssl;
    listen [::] 443 ssl;
    …
    ssl_certificate /path/to/your/fullchain.pem;
    ssl_certificate_key /path/to/your/privkey.pem;
    …
}

 

7. 重启nginx

sudo systemctl restart nginx.service
#或者是
sudo service nginx restart

8. 好啦

sslinfo

9. 为了方便自动更新证书,可以添加crontab定时任务:

使用对应用户运行 crontab -e;

添加类似下文的定时事件:

#每周一10:10运行更新脚本,本身证书有效期为三个月,这样的间隔就足够了
10 10 * * 1 bash /path/to/your/letsencrypt.sh/letsencrypt.sh -c > /path/to/somelogfile.txt

以上。


avatar
65535
4 Comment threads
15 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
5 Comment authors
shy泠一树小草remember石樱灯笼博客果啊 Recent comment authors
shy泠
Guest

支持ecc呢,https://static.shyling.com

remember
Guest
remember

虽然写了支持ecdsa证书,但运行实际出错,而服务器已经支持ecdsa了

remember
Guest
remember

已经发布到生产服务器了

remember
Guest
remember

我用另一个脚本了,支持dns验证,可以签多个子域名了。
btw,你这个评论框不支持嵌套,强迫症表示不能忍

石樱灯笼博客
Guest

我也开始考虑网站做https了

石樱灯笼博客
Guest

加密本身会消耗很多cpu计算,浏览器做证书校验也需要时间。其实就是一种靠时间换安全的方案。

果啊
Guest

你的博客有的资源貌似还没去头,所以还没出现小绿锁:)

果啊
Guest

nice!

果啊
Guest

yep, 也懒得考虑,省心……

果啊
Guest

这个嵌套好恶心啊

果啊
Guest

两层就够了吧……