如何在容器集群环境中使用Let's Encrypt HTTPS证书

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文介绍了Let's Encrypt单域名和通配型HTTPS证书的申请与更新,以及如何在容器集群环境中自动化地实现证书更新

背景

Let's Encrypt是由互联网安全研究小组(ISRG)在2015年推出一个HTTPS证书的免费解决方案,旨在提供一个免费开放的CA。配合电子前哨基金会(EFF)提供的自动化脚本certbot,只需一条命令就能够申请/更新HTTPS证书。

Let's Encrypt签发的证书有效期三个月,需要频繁地更新。虽然certbot提供了一键更新证书的功能,但其工作方式决定了它很难应用在容器集群中。

  1. HTTP验证方式在更新证书时会在本地生成一个验证文件,Let's Encrypt服务器通过HTTP路径访问该验证文件。容器集群中服务都是多点部署,而certbot只能在其中一个节点运行,无法保证验证请求总是被导入certbot运行的节点
  2. 使用DNS验证没有上述问题,其缺点在于难以自动化,在更新过程中需要人为创建对应的DNS记录

以下是我们针对这两点问题探索的一些解决方案。

单域名证书

certbot支持HTTP和DNS两种方式来验证域名所有者。

  • HTTP

Let's Encrypt服务端以HTTP方式访问域名下指定的验证文件

  • DNS

Let's Encrypt服务端查看域名下是否有创建指定的TXT记录

certbot对HTTP验证的支持度更好,几乎是开箱机用。但使用HTTP就会遇到上面提到的问题1,如何将流量导入我们指定的节点呢? 我们最终使用SLB的转发策略加虚拟服务器组来解决这个问题。

第一步,在SLB的80端口监听中,添加一条特殊的转发策略,匹配该规则的URL转发至一个特殊的虚拟服务器组,这个组只有一个节点,指向运行certbot的容器。

forward_rule

  • 假设域名为abc.example.com
  • URL设置为/.well-known/acme-challenge/,Let's Encrypt的验证请求总是以这个地址开头
  • 虚拟服务器组cert-refresh-group指向节点ecs-refresh的30080端口

第二步,在ecs-refresh运行容器:

  docker run -it --rm -p 30080:80 -v ~/letsencrypt:/etc/letsencrypt certbot-image bash -c "\
         service nginx start && \
         sleep 30 && \
         source /root/certbot/venv/bin/activate && \
         certbot renew -a webroot --webroot-path=/var/www/html -d abc.example.com"
  • ~/letsencrypt是节点上存放证书的目录
  • imagecertbot-image是一个安装了certbot和nginx的docker image,Dockerfile如下:
  From ubuntu:16.04
  ## install certbot
  RUN apt-get install -y git && \
      cd /root && \
      git clone https://github.com/certbot/certbot.git && \
      cd /root/certbot && \
      ./certbot-auto --os-packages-only --non-interactive && \
      ./tools/venv.sh

  ## install nginx
  RUN apt-get update && \
      add-apt-repository -y ppa:nginx/stable && \
      apt-get update && \
      apt-get install -y nginx && \
      chown -R www-data:www-data /var/lib/nginx && \
      mkdir -p /var/www/html
  ADD nginx.conf /etc/nginx/nginx.conf
  • nginx需要监听80端口,并且设置root为/var/www/html。nginx.conf如下:
    server {
        listen 80;
        root /var/www/html;
        location ~ /.well-known/acme-challenge {
            allow all;
        }
    }
  • 启动nginx后等待30秒是为了等待SLB的健康检查生效,从而能够导入流量
  • 由于Dockerfile中使用virtualenv安装certbot,所以运行certbot前需要先设初始化环境:source /root/certbot/venv/bin/activate

这条命令开始更新证书:

  certbot renew -a webroot --webroot-path=/var/www/html -d abc.example.com
  1. certbot将验证文件<authorization_file>放入目录/var/www/html
  2. Let's Encrypt访问http://abc.example.com/.well-known/acme-challenge/<authorization_file>
  3. 如果<authorization_file>内容通过验证,则签发新的证书

第三步,删除第一步配置的转发策略和虚拟服务器组

我们将这三步动作集成起来,放到chronos中每月运行一次。certbot会判断证书的到期时间,如果当证书有效期小于30天时才会执行更新操作。

通配型域名证书

Let's Encrypt对通配型的支持已于半月前(2018年3月13日)上线,申请通配型证书有以下几点需要注意:

  1. 由于通配型证书刚上线不久,certbot的stable版本还不支持,需要安装0.22或以上版本的certbot
  2. 默认情况下,certbot会请求Let's Encrypt的ACME v1接口,而v1接口不支持通配证书,需要使用参数--server https://acme-v02.api.letsencrypt.org/directory指定使用v2接口
  3. 申请通配型证书只能使用DNS验证方式,之前基于HTTP的验证方案不再有效
  certbot certonly --manual -d '*.example.com' --server https://acme-v02.api.letsencrypt.org/directory

运行这条命令即可申请通配证书,中途会提示添加DNS TXT记录,添加之后回车继续。

  Please deploy a DNS TXT record under the name
  _acme-challenge.example.com with the following value:

  v3YCTNw96mfgqMuQA80-McBf1MLvg3G4vXUDnLmlbz

  Before continuing, verify the record is deployed.

整个流程还是非常简单的,相比HTTP验证方式不用配置SLB来转发验证请求,其缺点在于不容易自动化。certbot中虽然集成了一些DNS验证的插件,但只支持国外几个DNS服务商:

  • certbot-dns-cloudflare
  • certbot-dns-cloudxns
  • certbot-dns-digitalocean
  • certbot-dns-dnsimple
  • certbot-dns-dnsmadeeasy
  • certbot-dns-google
  • certbot-dns-luadns
  • certbot-dns-nsone
  • certbot-dns-rfc2136
  • certbot-dns-route53

如果使用的DNS服务商恰好名列其中,那就省事不少,也算是开箱即用。小博无线使用DNSPod管理DNS,要将这套流程自动化起来还需要额外的工作。我们参照已有的插件,写了一个DNSPod的验证插件certbot-dns-dnspod

    class Authenticator(dns_common.DNSAuthenticator):
        def __init__(self, *args, **kwargs):
            super(Authenticator, self).__init__(*args, **kwargs)
            self.credentials = None

        def _perform(self, domain, validation_name, validation):
            self._get_dnspod_client().add_txt_record(domain, validation_name, validation, self.ttl)

        def _cleanup(self, domain, validation_name, validation):
            self._get_dnspod_client().del_txt_record(domain, validation_name, validation, self.ttl)

        def _get_dnspod_client(self):
            return _DnspodClient(self.conf('credentials'))

插件开发不算麻烦,只需要实现对应的_perform()_cleanup()方法。只是目前certbot对DNS插件的引用都是hard code在代码中,需要修改certbot的代码才能使新插件正常工作。有四个文件包含了对插件的引用代码:

  • certbot/cli.py
  • certbot/constants.py
  • certbot/plugins/disco.py
  • certbot/plugins/selection.py

安装插件

certbot目前的stable版本还不支持通配证书,所以我们使用v0.22.0分支安装certbot,插件certbot-dns-dnspod也在virtualenv环境中安装。

  ## install certbot
  RUN apt-get install -y git && \
      cd /root && \
      git clone https://github.com/certbot/certbot.git && \
      cd /root/certbot && \
      git checkout v0.22.0
  ADD modified_code/certbot/cli.py certbot/cli.py
  ADD modified_code/certbot/constants.py certbot/constants.py
  ADD modified_code/certbot/plugins/disco.py certbot/plugins/disco.py
  ADD modified_code/certbot/plugins/selection.py certbot/plugins/selection.py
  RUN ./certbot-auto --os-packages-only --non-interactive && \
      ./tools/venv.sh

  ## install certbot-dns-dnspod
  RUN bash -c 'source /root/certbot/venv/bin/activate && \
      cd /root/certbot-dns-dnspod && \
      python setup.py install'

申请证书

在申请证书时,我们将域名指定为*.example.com,证书支持所有子域名,但不包含根域名(example.com)。如果希望也支持根域名,将根域名也一同放入参数-d

  docker run -it --rm -v ~/letsencrypt:/etc/letsencrypt certbot-image bash -c "\
      certbot certonly \
              --dns-dnspod \
              --dns-dnspod-credentials ~/access_token.json \
              --dns-dnspod-propagation-seconds 30 \
              -d 'example.com,*.example.com'"

更新证书

  docker run -it --rm -v ~/letsencrypt:/etc/letsencrypt certbot-image bash -c "\
      certbot renew \
              --dns-dnspod \
              --dns-dnspod-credentials ~/access_token.json \
              --dns-dnspod-propagation-seconds 30 \
              -d 'example.com,*.example.com'"

Rate Limits

Let's Encrypt严格限制了签发证书的次数,一个注册域名(*.example.com)每周最多签发20个证书,一个子域名(abc.example.com)每周最多签发5个证书。

我们实践发现,即使是验证错误也会计算一次。所以在正式运行以前,一定加上--staging参数使用Let's Encrypt的测试接口。测试接口只用于测试证书的签发流程,其签发的证书为无效证书。

如果是申请通配证书,使用了--server参数,便不能再使用--staging参数,将--server地址指定为https://acme-staging-v02.api.letsencrypt.org/directory即可。

目录
相关文章
|
14天前
|
运维 网络协议 安全
为什么经过IPSec隧道后HTTPS会访问不通?一次隧道环境下的实战分析
本文介绍了一个典型的 HTTPS 无法访问问题的排查过程。问题表现为 HTTP 正常而 HTTPS 无法打开,最终发现是由于 MTU 设置不当导致报文被丢弃。HTTPS 因禁止分片,对 MTU 更敏感。解决方案包括调整 MSS 或中间设备干预。
|
7月前
|
安全 算法 网络协议
解析:HTTPS通过SSL/TLS证书加密的原理与逻辑
HTTPS通过SSL/TLS证书加密,结合对称与非对称加密及数字证书验证实现安全通信。首先,服务器发送含公钥的数字证书,客户端验证其合法性后生成随机数并用公钥加密发送给服务器,双方据此生成相同的对称密钥。后续通信使用对称加密确保高效性和安全性。同时,数字证书验证服务器身份,防止中间人攻击;哈希算法和数字签名确保数据完整性,防止篡改。整个流程保障了身份认证、数据加密和完整性保护。
求助!怎么上传第三方HTTPS证书?为什么我上传lets encrypt的证书显示私钥格式异常?
用户上传证书时遇到问题,提示格式异常,已尝试转换RSA格式仍未解决。
|
2月前
|
人工智能 安全 算法
HTTPS 的「秘钥交换 + 证书校验」全流程
HTTPS 通过“证书如身份证、密钥交换如临时暗号”的握手流程,实现身份认证与数据加密双重保障,确保通信安全可靠。
190 0
|
5月前
|
安全 算法 数据建模
HTTPS证书类型和品牌一览
HTTPS证书(SSL证书)是保障网站数据传输安全与身份可信认证的重要工具,适用于电商、企业官网等各类平台。证书主要分为DV(域名验证)、OV(企业验证)、EV(扩展验证)三种安全级别,以及单域名、通配符、多域名等不同覆盖类型。品牌方面,既有高性价比的国产锐安信、CFCA,也有国际知名的Sectigo、Digicert。
|
8月前
|
Linux 持续交付 调度
HTTPS 证书自动化运维:https证书管理系统-自动化部署
本指南介绍如何部署Linux服务器节点。首先复制生成的Linux脚本命令,然后将其粘贴到目标服务器上运行。接着刷新页面查看节点记录,并点击“配置证书”选择证书以自动部署。最后,节点部署完成,后续将自动调度,无需人工干预。
HTTPS 证书自动化运维:https证书管理系统-自动化部署
|
4月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
120 18
|
4月前
|
网络安全 开发者
如何解决HTTPS协议在WordPress升级后对网站不兼容的问题
以上就是解决WordPress升级后HTTPS协议对网站的不兼容问题的方法。希望能把这个棘手的问题看成是学校的管理问题一样来应对,将复杂的技术问题变得更加有趣和形象,并寻觅出解决问题的方式。希望你的网站能在新的学期得到更好的发展!
104 19
|
4月前
|
JSON 安全 网络协议
HTTP/HTTPS协议(请求响应模型、状态码)
本文简要介绍了HTTP与HTTPS协议的基础知识。HTTP是一种无状态的超文本传输协议,基于TCP/IP,常用80端口,通过请求-响应模型实现客户端与服务器间的通信;HTTPS为HTTP的安全版本,基于SSL/TLS加密技术,使用443端口,确保数据传输的安全性。文中还详细描述了HTTP请求方法(如GET、POST)、请求与响应头字段、状态码分类及意义,并对比了两者在请求-响应模型中的安全性差异。
345 20
|
4月前
|
安全 网络协议 算法
HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析
本文系统探讨了构建企业级双协议隧道代理系统的挑战与实现。首先对比HTTP/HTTPS和SOCKS5协议特性,分析其在工作模型、连接管理和加密方式上的差异。接着提出兼容性架构设计,包括双协议接入层与统一隧道内核,通过协议识别模块和分层设计实现高效转换。关键技术部分深入解析协议转换引擎、连接管理策略及加密传输方案,并从性能优化、安全增强到典型应用场景全面展开。最后指出未来发展趋势将更高效、安全与智能。
156 1