使用Let's Encrypt签署免费SSL证书


本文操作在 Linux 操作系统下完成,需要 Python 和 Nginx

超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为 HTTP over TLS,HTTP over SSL 或 HTTP Secure)是一种网络安全传输协议。在计算机网络上,HTTPS 经由超文本传输协议进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网络服务器的身份认证,保护交换数据的隐私与完整性。这个协议由网景公司(Netscape)在 1994 年首次提出,随后扩展到互联网上。
HTTPS 连接经常用于万维网上的交易支付和企业信息系统中敏感信息的传输。HTTPS 不应与在 RFC 2660 中定义的安全超文本传输协议(S-HTTP)相混淆。

以上引用自维基百科关于 Https 的解释
关于 Https 的详细信息网上都有,请查阅维基百科 Google

本文签发 Https 证书的机构为 Let’s Encrypt (以下简称为 LE), 该组织旨在消除当前手动创建和安装证书的复杂过程的自动化流程,为安全网站提供免费的 SSL/TLS 证书。

流程开始

注册 Let’s Encrypt 账户 (account.key)

account.key 为 LE 用来识别你身份 (相当于账户) 的 RSA key,使用 openssl 生成

openssl genrsa 4096 > account.key

创建 CSR 文件

LE 和 ACME 协议旨在配置一个自动化的,不需要人为干涉
即可以获得浏览器信任证书的 Https 服务器,该功能是通过服务器上运行一个证书管理代理程序 (Certificate Management Agent) 来实现的,该程序首先需要一个域名的证书签名请求文件 (Certificate Signing Request, CSR),然后将该文件递交给 LE 进行签发。
首先生成 domain.key 文件来作为域名的身份凭证

openssl genrsa 4096 > domain.key

切记不可使用 account.key 来作为 domain.key
然后生成 CSR 文件

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:{domain1},DNS:{domain2}")) > domain.csr

将 {domain1},{domain2} 替换成自己的域名即可,比如 timeliar.date , blog.timeliar.date ,可添加多个,以逗号分隔,写成 DNS:domain 的格式即可。
提示 /etc/ssl/openssl.cnf 找不到的话请自行 google:can not open /etc/ssl/openssl.cnf,路径有可能是 /usr/local/ssl/openssl.cnf,这个取决于 openssl 是如何安装的

认证

LE 想给你域名签发证书首先得确定域名可用,并且域名是你的。

  • 首先创建一个写入临时文件的目录,如 /var/www/le

    mkdir -p /var/www/le
  • 修改 Nginx 配置文件,添加一个 virtual server

    server {
      	listen 80;
      	location ^~ /.well-known/acme-challenge/ {
            alias /var/www/le/;
            try_files $uri =404;
      	}
    }

    path /.well-known/acme-challenge/ 为 LE 固定访问 URI,请不要修改

  • 启动 nginx

    nginx
  • 开始认证

    python acme_tiny.py \
            --account-key account.key \
            --csr domain.csr \
            --acme-dir /var/www/le/ > \
            signed.crt
    # 获取LE中见证书
    wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
    # 将le的中间证书和生成的证书组合成证书链
    cat ./signed.crt ./intermediate.pem > ./chained.pem

    ** 认证过程中 py 脚本会对提供的本机目录 /var/www/le 里写文件,然后通过访问 {domain}/.well-known/acme-challenge/{文件名} 来校验域名是否可用 **

生成 dhparam

前段时间 Google 完成了 SHA-1 的碰撞实验 (Google 宣布攻破 SHA-1,从此 SHA-1 不再安全),是时候该抛弃 SHA-1 了,这里使用了迪菲 - 赫尔曼密钥交换协议,具体讲解请看 wikipedia

openssl dhparam -out dhparam.pem 2048

配置 Nginx

将生成的 chained.pem 配置到 Nginx 中

ssl on;
ssl_certificate /path/to/chained.pem;
ssl_certificate_key /path/to/domain.key;
ssl_dhparam /path/to/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers  on;

然后开始使用吧!
但是出于安全考虑,该证书有效期只有 90 天,到期之后只需要再次进行认证即可,将下列脚本加入 crontab ,90 天运行一次

python acme_tiny.py \
        --account-key account.key \
        --csr domain.csr \
        --acme-dir /var/www/le/ > \
        signed.crt
cat ./signed.crt ./intermediate.pem > ./chained.pem

此外还有一些著名付费 Https 证书签发机构

免费的证书认证级别还是还是比较低的,只能起到加密信息的作用,适合做个人网站博客等安全要求不是特别高的。电商站点还是得用认证级别更高的付费证书来防止钓鱼网站

  • 自行 Google 吧

评论
 上一篇
关于匿名内部类的坑 关于匿名内部类的坑
起因 有一种初始化方法,写起来很爽,比如这样: Map<String,String> map = new HashMap<String,String>(){ { put("name","timel
2017-03-13 Timeliar
下一篇 
恨恨而死 恨恨而死
恨恨而死 作者:鲁迅 古来很有几位恨恨而死的人物。他们一面说些 “怀才不遇”“天道宁论” 的话,一面有钱的便狂嫖滥赌,没钱的便喝几十碗酒,—— 因为不平的缘故,于是后来就恨恨而死了。
2016-11-30
  目录