关于SSL证书免费续期的一些事

2018/06/01 23:59 下午 posted in  技术 随记 comments

经过了一年的使用,经历了StartCom所签发证书被全球所有浏览器不被信任强制吊销事件1后转移到了阿里云免费提供的SSL服务,直到上个月。

从上个月月初开始,绑定阿里云的邮箱每隔几天就收到主题为“阿里云云盾证书服务即将到期提醒”的邮件。从30天到15天再到7天、3天、2天……

秉着不到最后不续期的原则,我在最后时间之后去阿里云网站上操作。天真的我以为阿里云还有免费SSL提供呢,然而,登陆之后我无论是续费还是新购都并没有发现免费SSL的踪迹……

于是,一场免费SSL服务的选择开始了……

还好早先就有目标,直接搜Let's Encrypt准备申请,结果进入letsencrypt.org,发现并没有申请入口??我感到了大清亡了的味道……

然后我搜索了一下之后发现原来是Let's Encrypt提供免费SSL服务的品牌换成了Certbot (点击进入),感觉比原来好多了的样子。

看了看官网给的教程示例,然后又搜了下Certbot的相关使用情况,然后就在服务器上自己整了下,没过几分钟就完成了。真棒。而且这次选择的是Let's Encrypt V2证书,即泛域名SSL证书。感觉自己爽歪歪哦。

为了以后自己需要查看,也为了有需要的朋友们借鉴,我简单总结下主要的步骤:

申请与配置SSL证书的主要步骤与注意事项

注意:本文首次撰写于2018-06-02,最近修改时间为2018-06-02,请注意相关程序的可用性与安全性。

我的服务器:CentOS 7.1 x64,以下过程皆在此环境下执行。

  1. 依照官网提示,输入下述命令安装所需组件:

     $ yum -y install yum-utils
     $ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
    

    如果EPEL源不完整,可能需要安装或更新依赖的 epel 源:

     $ sudo yum install epel-release
    
  2. 按照上述步骤安装完成,输入下述命令可正式安装Certbot:

     $ sudo yum install python2-certbot-nginx
    
  3. 输入如下命令,进入证书生成步骤:

     $ sudo certbot certonly -d "*.abc.com" --manual --preferred-challenges dns-01  --server https://acme-v02.api.letsencrypt.org/directory
    

    其中abc.com需要换成你自己的域名。

    参数解析:

    • certonly -d为申请证书的命令,certonly 表示插件,Certbot 有很多插件。不同的插件都可以申请证书,用户可以根据需要自行选择。-d 为哪些主机申请证书。如果是通配符,输入 *.abc.com (根据实际情况替换为你自己的域名)。

    • --manual为手动模式

    • --preferred-challenges dns-01选择dns解析为验证模式(泛域名解析只能使用此模式)dns模式为dns-01

    • --server,Let's Encrypt ACME v2 版本使用的服务器不同于 v1 版本,需要显示指定。

    • 客户在申请 Let’s Encrypt 证书的时候,需要校验域名的所有权,证明操作者有权利为该域名申请证书,目前支持三种验证方式:

      • dns-01:给域名添加一个 DNS TXT 记录。
      • http-01:在域名对应的 Web 服务器下放置一个 HTTP well-known URL 资源文件。
      • tls-sni-01:在域名对应的 Web 服务器下放置一个 HTTPS well-known URL 资源文件。
  4. 接下来的步骤按照下面的要求走:

     Saving debug log to /var/log/letsencrypt/letsencrypt.log
     Plugins selected: Authenticator manual, Installer None
     Enter email address (used for urgent renewal and security notices) (Enter 'c' to
     cancel): [email protected] # 输入可以接收到应急续期邮件的电子邮箱
     Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
     
     -------------------------------------------------------------------------------
     Please read the Terms of Service at
     https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
     agree in order to register with the ACME server at
     https://acme-v02.api.letsencrypt.org/directory
     -------------------------------------------------------------------------------
     (A)gree/(C)ancel: A #输入A,同意使用协议
     
     -------------------------------------------------------------------------------
     Would you be willing to share your email address with the Electronic Frontier
     Foundation, a founding partner of the Let's Encrypt project and the non-profit
     organization that develops Certbot? We'd like to send you email about EFF and
     our work to encrypt the web, protect its users and defend digital rights.
     -------------------------------------------------------------------------------
     (Y)es/(N)o: Y # 输入Y,同意
     Starting new HTTPS connection (1): supporters.eff.org
     Obtaining a new certificate
     Performing the following challenges:
     dns-01 challenge for abc.com
     
     -------------------------------------------------------------------------------
     NOTE: The IP of this machine will be publicly logged as having requested this
     certificate. If you're running certbot in manual mode on a machine that is not
     your server, please ensure you're okay with that.
     
     Are you OK with your IP being logged?
     -------------------------------------------------------------------------------
     (Y)es/(N)o: Y # 输入Y,同意
     
     -------------------------------------------------------------------------------
     Please deploy a DNS TXT record under the name
     _acme-challenge.abc.com with the following value:
     
     edPUDuItificg6cXv241tificlhCBcstificU5FYDqc
     
     Before continuing, verify the record is deployed.
     -------------------------------------------------------------------------------
    

    到这里我们需要把上面的那串字符串复制下,然后去我们域名的DNS解析添加一条txt解析记录,记录内容为此字符串,记录名是上面提供的_acme-challenge。添加完后不要立即回车,等待几分钟后回车,继续下面的步骤:

     Press Enter to Continue
     Waiting for verification...
     Cleaning up challenges
     
     IMPORTANT NOTES:
      - Congratulations! Your certificate and chain have been saved at:
        /etc/letsencrypt/live/abc.com/fullchain.pem
        Your key file has been saved at:
        /etc/letsencrypt/live/abc.com/privkey.pem
        Your cert will expire on 2018-08-29. To obtain a new or tweaked
        version of this certificate in the future, simply run certbot
        again. To non-interactively renew *all* of your certificates, run
        "certbot renew"
      - Your account credentials have been saved in your Certbot
        configuration directory at /etc/letsencrypt. You should make a
        secure backup of this folder now. This configuration directory will
        also contain certificates and private keys obtained by Certbot so
        making regular backups of this folder is ideal.
      - If you like Certbot, please consider supporting our work by:
     
        Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
        Donating to EFF:                    https://eff.org/donate-le
    

    这里给的信息是已经生成好的证书存放地,共有四个文件在上面的路径中2

     $ tree /etc/letsencrypt/live/abc.com/
     .
     ├── cert.pem
     ├── chain.pem
     ├── fullchain.pem
     └── privkey.pem
    

    校验证书信息,输入如下命令2

     $ openssl x509 -in  /etc/letsencrypt/live/abc.com/cert.pem -noout -text 
     
     # 可以看到证书包含了 SAN 扩展,该扩展的值就是 *.abc.com
     ...
     Authority Information Access: 
             OCSP - URI:http://ocsp.int-x3.letsencrypt.org
             CA Issuers - URI:http://cert.int-x3.letsencrypt.org/
     
     X509v3 Subject Alternative Name: 
         DNS:*.abc.com
     ...
    
  5. 生成好后,在nginx的主机配置文件中修改,例如在abc.com.conf这个示例配置文件中的具体配置为:

     server
     {
     	listen 80;
     	#listen [::]:80;
     	server_name www.abc.com abc.com;
     	return 301 https://www.abc.com$request_uri;
     }
     
     server
     {
     	listen 443 ssl http2;
     	ssl_certificate /etc/letsencrypt/live/abc.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/abc.com/privkey.pem;
        ssl_trusted_certificate  /etc/letsencrypt/live/abc.com/chain.pem;
     	# 注意检查上面证书的路径,live下的证书文件夹名是否含有www,如果没有,请在上面两行中删除 www.
     	# 上面四行最关键,千万不能出错
     	
     	ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
     	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     	ssl_prefer_server_ciphers on;
     	ssl_session_cache shared:SSL:10m;
     	
     	# HSTS (ngx_http_headers_module is required) (31536000 seconds = 12 months)
     	# add_header Strict-Transport-Security "max-age=31536000" always;
     	
     	# OCSP Stapling ---
     	# fetch OCSP records from URL in ssl_certificate and cache them
     	ssl_stapling on;
     	ssl_stapling_verify on;
     	
     	# SSL相关配置完毕
     	
     	# 此处省略其他配置项……
    
     }
    
  6. 关于自动续期3

    官方给出了一个具体的说明:

    Certbot can be configured to renew your certificates automatically before they expire. Since Let's Encrypt certificates last for 90 days, it's highly advisable to take advantage of this feature. You can test automatic renewal for your certificates by running this command:

    Certbot可以配置为在证书过期之前自动续订您的证书。 由于Let's Encrypt证书的使用时间为90天,因此强烈建议利用此功能。 您可以通过运行以下命令来测试证书的自动续订:

     $ sudo certbot renew --dry-run
    

    If that appears to be working correctly, you can arrange for automatic renewal by adding a cron job or systemd timer which runs the following:

    如果上述命令工作正常,您可以通过添加运行以下命令的cron job或systemd timer来安排自动续期:

     certbot renew
    

    Note 注意:

    if you're setting up a cron or systemd job, we recommend running it twice per day (it won't do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let's Encrypt-initiated revocation happened for some reason). Please select a random minute within the hour for your renewal tasks.

    如果您设置cron job或systemd timer,我们建议其每天运行两次(在您的证书到期续约或撤消之前,它不会执行任何操作,但定期运行它可以让您的站点保持在线状态 如果Let's Encrypt发起的撤销是由于某种原因发生的)。请在一小时内为您的续订任务选择一个随机分钟。

    An example cron job might look like this, which will run at noon and midnight every day:

    一个cron job的例子可能是这样的,它会在每天的中午和午夜运行:

     0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew 
    
  7. 关于生成证书的手动模式和自动模式4

    从网上查到的资料说是,“如果是用手动模式生成的证书,你需要把上述手动模式一节的操作再执行一次,每隔两三个月就要手动操作一次”,但是官方在主流程里并没有重点说这件事……文档懒得查了。回头确定了更新下这一节。56

参考文献

  1. 惊闻StartCom之死[EB/OL]. https://hr98.xyz/termination-startcom-ca/, 2018-06-02

  2. Let's Encrypt 免费通配符 SSL 证书申请教程[EB/OL]. https://www.hi-linux.com/posts/6968.html, 2018-06-02

  3. Certbot - Centosrhel7 Nginx[EB/OL]. https://certbot.eff.org/lets-encrypt/centosrhel7-nginx, 2018-06-02

  4. 配置使用免费的通配符证书[EB/OL]. https://blog.laisky.com/p/letsencrypt/, 2018-06-02

  5. Certbot对免费Let’s Encrypt证书的自动续期,So Easy![EB/OL]. https://www.liaosam.com/use-cron-service-and-certbot-for-renewal-of-letsencrypt-ssl-certificates.html, 2018-06-02

  6. 使用 Certbot + Let's Encrypt 小步快跑的奔向 Https[EB/OL]. https://laravel-china.org/topics/2525/using-certbot-lets-encrypt-small-step-run-towards-https, 2018-06-02