Docker环境下自动更新Let’s Encrypt SSL证书

说明:以下脚本在Ubuntu 18.04运行通过,大部分脚本执行需要管理员权限。

1. 准备docker环境

# 安装必备工具包
apt-get -y install apt-transport-https ca-certificates curl software-properties-common

# 添加docker阿里云源,相对官方源速度更快
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

# 安装最新版社区版docker
apt update -y
apt install -y docker-ce

# 如果想要安装指定版本的docker-ce,如下:
# 查看有哪些版本
apt-cache madison docker-ce
# 安装指定版本
apt install -y docker-ce=[版本]

#  设置阿里云docker源
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-‘EOF‘
{
  "registry-mirrors": ["https://uon07it7.mirror.aliyuncs.com"]
}
EOF

systemctl daemon-reload
systemctl restart docker

# 下载安装docker-compose
curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

2. Let‘s Encrypt免费证书签发过程简介

Let‘s Encrypt免费证书签发过程包含以下三个阶段:

  1. 在本地服务器上安装CertbotCertbot是签发/更新证书的客户端程序;
  2. 运行Certbot获取SSL/TLS证书,证书有效期为3个月
  3. 设置定时脚本每周运行一次Certbot更新证书。如果证书有效期小于30天,Certbot会更新证书;

3. Certbot工作原理简介

不论是第一次申请证书,还是更新证书,Certbot都会发起一次ACME请求,来验证你是否拥有该域名。如果验证通过,Certbot就会将新证书安装到本地服务,其实就是将证书保存在一个目录中。证书一般包含两个文件(包含公钥、私钥以及证书等信息),web服务器需要配置使用这两个证书文件,来实现HTTPS访问。

ACME验证过程如下:

  1. 假设你有一个域名:example.com,和一个公网IP:xxx.xxx.xxx.xxx,并设置好了DNS解析;
  2. 配置好一台web服务器,在80端口和443端口接受examle.com的请求;
  3. CertbotLet‘s Encrypt发起证书申请;
  4. Let‘s Encrypt返回Certbot一个唯一的token
  5. Certbot配置web服务器,使token可以通过url:http://example.com/.well-known/acme-challenge/{token}访问;
  6. Let‘s Encrypt CA访问上述url,如果获取到的token和它发送给Certbottoken一致,就可以证明你拥有该域名;

注意:Certbot需要配置web服务器的相应权限。以nginx为例,Certbot需要权限将token写入.well-known/acme-challenge目录。

4. 通过docker来运行Certbot

为了方便维护、升级,推荐使用docker来运行Certbot。整个过程可以分为两部分:首次申请证书和更新证书。

4.1 首次申请证书

  1. 创建web服务目录: mkdir -p /letsencrypt/site。这里以静态网页为例,也可以设为反向代理。
  2. 创建docker-compose文件:nano /letsencrypt/docker-compose.yml
version: ‘3.1‘

services:
  demo-site:
    container_name: ‘demo-site‘
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./site:/usr/share/nginx/html
    networks:
      - docker-network

networks:
  docker-network:
    driver: bridge
  1. 创建nginx配置文件:nano /letsencrypt/nginx.conf
server {
    listen 80;
    server_name example.com www.example.com;

    location ~ /.well-known/acme-challenge {
        allow all;
        root /usr/share/nginx/html;
    }

    root /usr/share/nginx/html;
    index index.html;
}
  1. 启动web服务器:cd /letsencrypt && docker-compose up -d
  2. 运行Certbot申请证书
docker run --rm -it -v /letsencrypt/certbot/etc/letsencrypt:/etc/letsencrypt \             # 证书申请工作目录
-v /letsencrypt/certbot/var/log/letsencrypt:/var/log/letsencrypt \     # 日志记录
-v /letsencrypt/site:/data/letsencrypt \                               # ACME验证token目录,与nginx服务器共享
certbot/certbot certonly --webroot \                                                   # 指定ACME验证方式:token文件验证
--email youremail@domain.com --agree-tos --no-eff-email \              # 申请者邮件
--webroot-path=/data/letsencrypt \                                     # ACME验证token文件放置目录
-d example.com -d www.example.com                                      # 指定要申请证书的域名列表

如果脚本正常运行,可以在/letsencrypt/certbot/etc/letsencrypt/live下找到example.com文件夹,其中包含申请成功的证书文件:fullchain.pemprivkey.pem

  1. 停止web服务器:cd /letsencrypt && docker-compose down
  2. 更新docker-compose配置
version: ‘3.1‘

services:
  demo-site:
    container_name: ‘demo-site‘
    image: nginx:alpine
    ports:
      - "80:80"     # 保留80端口,用于证书更新
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./site:/usr/share/nginx/html
      - ./certbot/etc/letsencrypt/live:/letsencrypt/live        # 当前证书目录
      - ./certbot/etc/letsencrypt/archive:/letsencrypt/archive  # 历史证书目录
      - ./dhparam-2048.pem:/letsencrypt/dhparam-2048.pem        # 使用2048位DH(Diffie-Hellman)参数
    networks:
      - docker-network

networks:
  docker-network:
    driver: bridge

生成2048位的DH参数文件命令如下:

openssl dhparam -out /letsencrypt/dhparam-2048.pem 2048

live目录的证书会soft link到archive目录,而docker对soft link支持不好,因此需要同时映射live和archive目录。

  1. 更新nginx配置,启用HTTPS

处理http:

server {
    listen      80;
    server_name example.com www.example.com;

    # 重定向到https
    location / {
        rewrite ^ https://$host$request_uri? permanent;
    }

    # 高优先级,仅用于更新证书
    location ~ /.well-known/acme-challenge {
        allow all;
        root /data/letsencrypt;
    }
}

处理https:

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    server_tokens off;

    ssl on;

    ssl_certificate /letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /letsencrypt/live/example.com/privkey.pem;

    ssl_buffer_size 8k;

    ssl_dhparam /letsencrypt/dhparam-2048.pem; # 使用2048位DH参数,加强安全

    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

    ssl_ecdh_curve secp384r1;
    ssl_session_tickets off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8;

    root /usr/share/nginx/html;
    index index.html;
}

DH以及OCSP内容请参考:Strong SSL Security On nginx

  1. 重新启动web服务器:cd /letsencrypt && docker-compose up -d

4.2 更新证书

  1. 设置更新脚本
    touch /letsencrypt/renew.sh && chmod +x /letsencrypt/renew.sh
    nano /letsencrypt/renew.sh

renew.sh脚本内容如下:

#!/bin/bash

docker run -it --rm -v /letsencrypt/certbot/etc/letsencrypt:/etc/letsencrypt -v /letsencrypt/certbot/var/lib/letsencrypt:/var/lib/letsencrypt -v /letsencrypt/certbot/var/log/letsencrypt:/var/log/letsencrypt -v /letsencrypt/site:/data/letsencrypt certbot/certbot renew --webroot -w /data/letsencrypt --quiet && docker kill --signal=HUP demo-site

最后一行脚本说明:在更新完证书后,通知nginx重新加载配置。

  1. 设置定时任务
    通过crontab设置定时任务:
    crontab -e
    添加一行,每周执行一次更新脚本:
    0 1 * * 0 /letsencrypt/renew.sh

5. 安全加强

可以通过ssllabs.com验证证书,如果按照上述配置,应该可以获得A+评价。
当然,还可以进一步通过securityheaders.io校验网站安全性,对于nginx可以添加以下配置:

server {
    # ....

    location / {
        #security headers
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options "DENY" always;
        #CSP
        add_header Content-Security-Policy "frame-src ‘self‘; default-src ‘self‘; script-src ‘self‘ ‘unsafe-inline‘ https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src ‘self‘; style-src ‘self‘ https://maxcdn.bootstrapcdn.com; font-src ‘self‘ data: https://maxcdn.bootstrapcdn.com; form-action ‘self‘; upgrade-insecure-requests;" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    }

    # ....
}

6. 小结

本文参考How to Set Up Free SSL Certificates from Let‘s Encrypt using Docker and Nginx,对Docker环境下如何使用Let‘s Encrypt自动获取/更新SSL证书做了一个简明攻略。
如果你正在使用K8S,ingress nginxtraefik都对let‘s encrypt提供了很好的支持,配合helm来安装部署,也更为简单方便。

作者:freefishz2
链接:https://www.jianshu.com/p/ea090833f766
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

原文地址:https://www.cnblogs.com/gao88/p/10596143.html

时间: 2024-10-09 05:27:40

Docker环境下自动更新Let’s Encrypt SSL证书的相关文章

Apache环境下配置多个站点的SSL证书

重新创建apache目录中conf/extra/下的httpd-ssl.conf文件 Listen 443 <VirtualHost *.443> DocumentRoot "/var/www/site1" ServerName www.site1.com ServerAlias www.site1.com SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5 SSLCertif

Docker环境下使用SpringBootAdmin2.x教程

Spring Boot Admin 2.x是一个用于监测管理微服务应用的程序,通过Eureka注册中心发现服务,然后获取服务的运行状态.日志信息.并提供一套UI界面供系统运维人员检查,同时结合Spring Security进行登录权限认证 首先上完整的Github项目代码: liumapp/spring-boot-admin-in-docker 然后是完整的Wiki文档: 使用文档 所需依赖 spring boot 2.0.2 spring cloud Finchley.RELEASE code

bash环境下自动安装并初始化oh-my-zsh & autojump zsh

Linux和Mac系统默认的shell 都是bash,但是真正强大的shell应属于zsh,而且完全监控bash,是shell中的终极杀手,有很多bash所没有的功能,但是zsh的初期配置太过繁琐,流行率一直不高,直到有个叫Robby Russell的家伙在github上开发了oh-my-zsh项目,使大家使用zsh的便捷性大大提高. 由于在公司的电脑是windows,就折腾了下cygwin,并且安装了zsh,这样做起维护方便很多了,而且我把autojump项目也集成一起,最后写了一个自动安装的

Oracle RAC环境下如何更新patch(Rolling Patch)

Oracle RAC数据库环境与单实例数据库环境有很多共性,也有很多异性.对于数据库补丁的更新同样如此,都可以通过opatch来完成.但RAC环境的补丁更新有几种不同的更新方式,甚至于可以在零停机的情况下对所有节点实现滚动升级.本文主要是转述了Doc 244241.1,描述RAC环境下的patch更新方式以及在不同的情形下选择何种更新方式. 1.RAC patch的几种方式 OPatch supports 3 different patch methods on a RAC environmen

Cordova webapp实战开发:(6)如何写一个iOS下自动更新的插件?

上一篇我们学习了如何写一个Andorid下自动更新的插件,我想还有一部分看本系列blog的开发人员希望学习在iOS下如何做插件的吧,那么今天你就可以来看看这篇文字了. 本次练习你能学到的 学习如何获取iOS当前版本号 学习iOS下插件类的编写 学习iOS下插件的配置 学习iOS下插件的调用 主要内容 APP中[检查更新]显示当前版本号 插件类的编写 在上一篇介绍Andorid插件时我们贴出了很多源码,这里也直接贴出代码,首先是iOS下插件的代码. 我们在Plugins下新建两个文件,一个头文件

Code First 下自动更新数据库结构(Automatic Migrations)

示例 Web.config <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramew

Docker环境下编译android源码|编译可运行xposed

前言 因为我的电脑是Ubuntu18的版本,成功编译xposed刷入手机之后无法启动,检查了所有的环境,没有问题,发现可能是Ubuntu系统的兼容库的问题,但是我不可能重新安装系统吧,毕竟有点蠢,所以最好的方式就是在docker的Ubuntu容器中编译,统一环境问题,也可以隔离环境平时 工作开发环境,下面开始操作 安装配置docker docker加速,采用对国人友好的镜像地址 通过修改daemon配置文件/etc/docker/daemon.json来使用加速器,执行以下命令: 您可以配置 D

Cordova webapp实战开发:(5)如何写一个Andorid下自动更新的插件?

在 <Cordova webapp实战开发:(4)Android环境搭建>中我们搭建好了开发环境,也给大家布置了调用插件的预习作业,做得如何了呢?今天我们来学一下如何自己从头建立一个Andorid下的cordova插件. 本次练习你能学到的 学习如何实现自动更新功能 学习插件类的编写 学习插件的配置 学习插件的调用 主要内容 打开APP后检查版本更新,如果有更新则弹出更新对话框 APP中[检查更新]显示当前版本号,并可以点击进行版本检查更新 如何实现自动更新功能 你可以自己写代码,也可以网上找

Linux常用开发环境软件-RabbitMQ安装(docker环境下)

linux下docker环境安装RabbitMQ版本 1.从docker官网仓库下载安装RabbitMQ镜像 docker pull rabbitmq:management 注意:如果docker pull rabbitmq 后面不带management,启动rabbitmq后是无法打开管理界面的,所以我们要下载带management插件的rabbitmq. 2.启动RabbitMQ docker镜像 docker run -d --hostname my-rabbit -p 5672:5672