快速配置 HTTPS
已经是快到 2017 年,很多网站居然还不支持 HTTPS 访问。要知道 Chrome 可是要开始将 HTTP 站点标记为“不安全”了。那么这一篇就说一下如何最快速地将一个站点配置为 HTTPS 访问。
注意:一旦将你的网站配置为 HTTPS 访问,引用的所有脚本、图片、样式表等都必须是有效的 HTTPS 资源,否则页面将被标记为不安全。
首先,我们使用的组合是这样的:DNSPod + Let’s Encrypt 服务 + nginx。也就是说在本文的例子中,域名 NS 服务使用的是 DNSPod,证书是由 Let’s Encrypt 颁发的,服务器使用 nginx。
关于 nginx 的版本,建议是卸载服务器系统源中的版本,从 nginx 官方源安装,具体操作步骤参考 nginx 的官方文档。需要注意的是,nginx 在 Ubuntu 14.04 上不支持 HTTP2,具体原因和解决方法参考这里。
第一件事情:在服务器上配置好你的域名,最简单的 nginx 配置如下。
|
|
以上配置文件示例中,我们让 nginx 在 80 端口监听 HTTP,在 443 端口监听 HTTPS(并且使用 HTTP2),并将 HTTP 请求转向 HTTPS 地址。最终使用的证书和密钥存放在 /home/user/example/keys/ssl/
目录中,这个路径你可以任意指定,只要 nginx 有权限读取对应文件就行。
此外,配置中还有两个 include 的文件 /etc/nginx/ssl_params
和 /etc/nginx/hsts_headers
。后者只是添加了一些 HSTS 头,内容如下。
|
|
关于 HSTS 头有什么作用,以及为什么要添加这些响应头,请参考维基百科的 HSTS 页面。
/etc/nginx/ssl_params
这个文件是一些 SSL 相关的配置,一个简单的例子如下。
|
|
其中 /etc/nginx/dhparams.pem
文件的生成以及 SSL ciphers 的选择请参考 Guide to Deploying Diffie-Hellman for TLS。
编辑好配置文件后,可以按一般习惯存放在 /etc/nginx/sites-available/example.com
,然后软链接到 /etc/nginx/sites-enabled/example.com
。暂时先不要重启 nginx 服务,因为我们还没有申请证书,重启是肯定会失败的。
第二件事情就是去 DNSPod 将你的域名解析配置好,并生成 API token。域名解析应该不用多说,API token 是在通过 DNSPod 的 API 来操作 NS 记录时授权使用的,可以认为就是应用程序密码。关于如何新建一个 API token,请参考 DNSPod 的官方文档。这里个人建议是一台服务器上只需要申请一个 API token,名称要描述清楚 token 的用途和使用的机器,方便日后查询和管理。token 生成后只显示一次,这时候需要复制下来,供下一步使用。
第三步就是去 Let’s Encrypt 申请证书了,我们使用的是 acme.sh 工具。关于这个工具的优点有很多,我个人选择它的原因大概是:
- 安装、使用、卸载都非常简单
- 对于一个域名只需要手动操作一次,之后续期和重启服务器都是自动的
自动续期是很重要的一点,因为 Let’s Encrypt 颁发的都是 90 天有效的短期证书。
从零开始使用 acme.sh 的步骤如下。
|
|
申请完毕之后,acme.sh 会打印出所有相关文件的绝对路径。但是不要急着去使用这些文件,我们还要将它们安装到指定的位置。
说点多余的,其实这一步不是必须的,你完全可以直接使用这些文件。但是这些文件都存放在 ~/.acme.sh
中,之后 acme.sh 升级时,内部目录结构可能会改变,造成你的配置文件失效;并且通过额外的安装步骤,acme.sh 可以在续期后帮你自动重启 nginx 服务。后一点是很重要的,因为 nginx 只是在启动时读取证书和密钥,在续期后如果不重启,它还是使用旧的证书,你可能直到旧证书失效才会发现。
安装证书的步骤很简单。
|
|
只是将证书和密钥安装到指定的路径中,并且 reload nginx 配置。
需要注意的是,如果你的 sudo 命令需要密码,这里可能会有麻烦。但是也不要就因此直接用 root 用户来运行 acme.sh。你可以参考这篇文章,将当前用户配置为不需要输入 sudo 密码,或者配置为运行指定命令时不需要密码。
安装完证书后就可以访问你的网站了,按照前面的 nginx 配置,网站会返回 204 空响应,你可以通过 Chrome 开发工具的 Security 面板来检查网站的 HTTPS 证书。建议同时通过 SSL Server Test 来检查一下,根据检测结果来修正 SSL 相关设置,尽量达到 A 级或 A+。
最后,如果你想确认 acme.sh 会不会帮你网站的证书做自动续期,运行 crontab -l
来查看当前用户的定时任务,你应当会看到 acme.sh 自动添加的条目。这个任务会每天运行一次,如果一个域名的证书已经颁发超过 60 天,acme.sh 就会帮你自动续期。
本文中使用的例子是 DNSPod,但 acme.sh 还支持很多其他的 NS 服务提供商,具体请参考官方文档。
附一篇 nginx 相关配置的文章:本博客 Nginx 配置之安全篇 | JerryQu 的小站。