letsencrypt刚出来的时候写了一篇它的认证签发原理。自那过后就没有真正的去实践过了。最近有部署HTTPS的需求就又考察了一番。发现acme.sh灰常好用啊~~~,来一篇水文记录下测试部署HTTPS的完整过程吧

README

首先有2种认证方式,生成一个指定的文件让letsencrypt访问。或者生成一个DNS记录让letsencrypt访问。第一种方式有非常大的局限性。比如你的80端口正在被使用。那么你需要先设置DNS解析,再修改下nginx的配置让网址能够被正常访问到。这就显得很麻烦了。主流的DNS服务提供商都已经提供了API接口,使用DNS的优势就是:

  1. 任何电脑都能直接生成证书文件,不需要依赖本机能够被外部访问
  2. 不需要对nginx做任何设置

以下记录下我使用一个临时的digitalocean机器从0开始部署https的步骤(假设测试url为ssl.ficapy.com,操作环境为osx)

我还是要安利下,临时使用digitalocean测试使用命令行工具tugboat灰常好啊

  1. 安装tugboat用命令行快速创建机器以及测试完成后删除

    1
    gem install tugboat
  2. 将digitalocean的api写入让tugboat能够正常使用,并执行一些初始化设置

    1
    tugboat authorize
  3. 根据初始化默认设置创建一个vps

    1
    tugboat create temp
  4. ssh登陆

    1
    tugboat ssh temp
  5. 安装acme.sh

    1
    curl https://get.acme.sh | sh
  6. 参照acme.sh文档将dns的api信息作为环境变量写入(记得执行source ~/.bashrc)

  7. 生成证书

    1
    acme.sh --issue --dns dns_cf -d ssl.ficapy.com --debug
  8. 将证书放置到位置并设置nginx重启命令

    1
    2
    3
    4
    acme.sh --installcert -d ssl.ficapy.com \
    --keypath /etc/nginx/ssl/ssl.ficapy.com.key \
    --fullchainpath /etc/nginx/ssl/ssl.ficapy.com.pem \
    --reloadcmd "service nginx force-reload"
  9. 强制测试续约(该操作会自动执行注册过的事件,一般就是重启nginx咯,续约key是不会变的,变的是fullchain.cer文件)

    1
    acme.sh --renew-all --force
  10. 生成dhparam文件

    1
    openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
  11. 使用生成一个标准的nginx配置文件并放入/etc/nginx/site-enables目录,示例如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    server {
    listen 443 ssl;

    server_name ssl.ficapy.com;
    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/nginx/ssl/ssl.ficapy.com.pem;
    ssl_certificate_key /etc/nginx/ssl/ssl.ficapy.com.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;
    }
  12. 最后就是浏览器访问以下测试完毕啦。如果出现错误可以查看nginx的日志/var/log/error.log,肯定是哪一步出问题啦,最后就是测试完毕后删除vps啦tugboat destory temp

额外说一下其他的吧。最开始我试过阿里云dns的api,用的是子账号。结果子账号是无法包含(注意)dns的操作权限的,就总是失败。后来不用子账号,直接用原账号的api密匙就完全没问题啦~~~。另外各大云平台大多都有负载均衡器,然后可以填写https证书。这种就不太适合letsencrypt这种短期证书了。否则总上去换证书不被麻烦死。如果在这种负载均衡器上不设置https证书。那么就需要在负载均衡器每一台机器都设置上https证书,嗯想想也挺头大啊~~~,所以这种自动化方式只比较适合在一台机器上生成并维护证书

再额外,哪个时候写个Ansible的playbook就好哒,可能会更加方便┑( ̄Д  ̄)┍

参考

github tugboat
mozilla ssl-config-generator
使用 acme.sh 给 Nginx 安装 Let’ s Encrypt 提供的免费 SSL 证书