现在 HTTPS 已经越来越热了。

国外的 GoogleFacebookTwitter之类的大厂早就全线推 HTTPS

国内原本只有金融业用 HTTPS 比较多,现在的大厂也跟进,BaiduTaobao之类的主站也都全面使用 HTTPS

作为个人网站的网站主,在以前推动网站 HTTPS 改造的最主要的拦路虎是 SSL 的证书。

早期的免费证书有国外的 StartSSL (现在已经是数字公司的了)。

后来国内也有 WoSign (沃通),现在它已经被打压了。

不过,Let's Encrypt 也正式对外颁发免费的SSL

Let’s Encrypt 是一个免费、自动化、开放的证书签发服务,由 ISRG(Internet Security Research Group,译:互联网安全研究小组) 这个非盈利组织维护。现在是 Linux 基金会 (Linux Foundation) 合作的项目

Let’s Encrypt 证书

类型

SSL 证书分为3类:

  1. DV 域名验证证书
  2. OV 组织机构验证证书
  3. EV 增强的组织机构验证证书

一般个人网站用 DV 就可以了。Let’s Encrypt就是DV` 证书。

兼容性

明确支持的浏览器/客户端:

  • Mozilla Firefox >= v2.0
  • Google Chrome
  • Internet Explorer on Windows XP SP3 and higher
  • Microsoft Edge
  • Android OS >= v2.3.6
  • Safari >= v4.0 on macOS
  • Safari on iOS >= v3.1
  • Debian Linux >= v6
  • Ubuntu Linux >= v12.04
  • NSS Library >= v3.11.9
  • Amazon FireOS (Silk Browser)
  • Cyanogen > v10
  • Jolla Sailfish OS > v1.1.2.16
  • Kindle > v3.4.1
  • Java 7 >= 7u111
  • Java 8 >= 8u101

明确不支持的浏览器/客户端:

  • Blackberry OS v10, v7, & v6
  • Android < v2.3.6
  • Nintendo 3DS
  • Windows XP 早于 SP3 (不支持 SHA-2)
  • Java 7 < 7u111
  • Java 8 < 8u101

怎么获取 Let's Encrypt 的证书

Let's EncryptGetting Started 里面讲了很多办法。

  • Shell:在命令行上获取。
  • Without Shell:免命令行(一般是CDN虚拟主机服务商)获取。

Shell

在这里,我们需要 ACME (Automatic Certificate Management Environment, 译作: 自动化证书管理环境) 为你颁发 Let's Encrypt 的证书。

官方推荐使用的ACME 工具是 Certbot,也是我们这篇文章的主角。

当然,Let's Encrypt 也提供了一个列表说明不同的 ACME 客户端,它们都是由不同的语言编写的脚本,这篇文章不会谈及。

Without Shell

这类型的颁发证书的方式一般都是 CDN虚拟主机 自己本身就集成了 Certbot。一般用法很弱智,就看你的服务商支不支持了。

安装 Certbot

查不同系统、不同服务器软件的教程

访问 Certbot 的官网,映入眼帘的就是 I'm using ( Software ) on ( System ) 这两个选择器。

因为我这儿服务器软件是 NGINX 所以第一个选择 NGINX

因为我这儿服务器系统是 CentOS 7, 所以 System 选择 CentOS/RHEL 7

下面也是按照 CentOS 7 使用 NGINX 来介绍的。

yum 安装

下面也是按照 CentOS 7yum 自带了 certbot,所以很轻松就 yum 装好了。

1
sudo yum install certbot

初始化验证目录

Let's Encrypt 验证你对域名的拥有权的方式很简单。

就是访问你的域名的 HTTP 服务器,校验 certbot 生成的验证文件。

我们需要一个地方存放这些验证域名的临时文件。

1
2
mkdir /usr/share/nginx
mdkir /usr/share/nginx/certbot

上面挑选了,/usr/share/nginx/certbot 作为这些文件的存放点。

颁发证书

这一步就是每一次颁发不同网站的 SSL 证书所需要的。

配置 NGINX

首先,你要能确保你要获得证书的网站可以被互联网访问。这个就不用教了。

其次就是 绑定 Let's Encrypt 验证目录

这一步和“初始化验证目录”那一步有关系,因为我们需要把验证目录绑定到你的网站上。

只需要在 NGINX 配置文件上的 server 层加上下面的代码就可以了:

1
2
3
4
5
6
7
8
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/nginx/certbot;
}
location = /.well-known/acme-challenge/ {
return 404;
}

第一个 location 做的就是绑定验证目录。

第二个 location 做的就是对外隐藏这个验证目录,防止黑客猜测。

做完这些操作之后,别忘记重启 NGINX 服务器。

nginx -s reload 走你~~

使用 certbot 颁发证书

命令很简单:

1
sudo certbot certonly --webroot -w /usr/share/nginx/certbot -d {域名}

好比说我要颁发证书给 micblo.com

1
sudo certbot certonly --webroot -w /usr/share/nginx/certbot -d micblo.com

如果说我要让一个证书可以和两个子域名一起用,好比说 micblo.comwww.micblo.com

1
sudo certbot certonly --webroot -w /usr/share/nginx/certbot -d micblo.com -d www.micblo.com

第一次使用的时候,Certbot 会让你填写一个邮箱,该邮箱作为证书的拥有者,用于后面证书更新。

还有就是同意 Let's Encrypt 的使用条款,没有异议的话选择 Agree 就好了。

完成颁发之后,就会看到 Congratulations! 之类的字样。

安装证书

证书颁发好了之后,会被存放在 /etc/letsencrypt/live/{域名}/ 里面。

回到 NGINX 的配置文件,假设原来的配置是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name micblo.com;
root /var/www/micblo;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/nginx/certbot;
}
location = /.well-known/acme-challenge/ {
return 404;
}
}

绑定 :443 端口

首先,先在listen 80; 后面加入 listen 443 ssl;,让 :443 端口和 SSL 绑定。

注意防火墙一定要打开 :443 端口!

引入证书

前面我们已经获得 Let's Encrypt 颁发的证书啦。

下面就是调用这些公钥、私钥和证书链的方法。

1
2
3
ssl_certificate /etc/letsencrypt/live/{域名}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{域名}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/{域名}/chain.pem;

不要忘记替换掉 {域名}

SSL 安全、优化配置

全家桶在下面。

1
2
3
4
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 20m;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:!ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:!RC4-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;

大概的意思:

  • SSL 开启 Session,减少重复认证的可能;
  • 提高前向安全性,由服务器决定 SSL 版本;
  • 只支持安全的加密方式

Diffiel-Hellman 参数安全

Diffiel-Hellman 作为交换密钥的手段,需要有一个Diffiel-Hellman 参数。

默认的 Diffiel-Hellman 参数是公开的,相对来说不安全。

因此我们需要自己初始化 Diffiel-Hellman 参数。

1
2
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

生成 dhparam.pem 后,在 NGINX 配置加入 ssl_dhparam /etc/ssl/certs/dhparam.pem; 就好了。

合体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 80;
listen 443 ssl;
server_name micblo.com www.micblo.com;
ssl_certificate /etc/letsencrypt/live/micblo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/micblo.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/micblo.com/chain.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 20m;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:!ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:!RC4-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
root /var/www/micblo;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /usr/share/nginx/certbot;
}
location = /.well-known/acme-challenge/ {
return 404;
}
}

自动更新证书

因为 Let's Encrypt 的证书只有 3个月 有效期

所以我们需要依靠 certbot 自动更新证书。

CentOS 7 下也是很简单:

1
certbot renew --quiet

高玩 HTTP 2

如果你在 NGINX 编译的时候顺便编译了 HTTP 2,那么恭喜你,你可以玩 HTTP 2

改一下一行就可以了:

1
listen 443 ssl http2;

不过,在 NGINX 上的 HTTP 2 模块还是有些问题。玩玩可以,暂时不建议在生产环境使用。

写到最后

看到这里,相信你也会使用 certbot 为自己颁发一个免费 SSL 证书啦。

大家撸起袖子加油干,把自己的网站都改 HTTPS 吧~

除非注明,麦麦小家文章均为原创,转载请以链接形式标明本文地址。

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

本文地址:https://blog.micblo.com/2017/01/20/利用Certbot优雅获取Let-s-Encrypt免费SSL证书/