• 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
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    python面试大全
    python面试2
    python求职之路
    python面试题目
    关于栈的输入顺序和输出顺序
    表单提交中get和post方式的区别
    DOS命令行下mysql 基本命令
    跨站请求伪造CSRF
    Windows上python的virtualenv 安装及使用
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/gao88/p/10596143.html
Copyright © 2020-2023  润新知