为nginx服务器网站添加HTTPS/配置SSL证书

栏目: 服务器 · Nginx · 发布时间: 8年前

内容简介:为nginx服务器网站添加HTTPS/配置SSL证书

转载请注明出处: http://www.codelast.com/

网站使用HTTPS的好处就不用多说了,在当今凶险的互联网环境下,使用HTTP越来越不安全,所以我也决定把网站转成HTTPS。使用HTTPS,首先你需要有一张SSL证书。

曾经,收费的SSL证书很贵,一般人玩不起;随着互联网的发展,免费的SSL证书越来越普及,谁都可以很容易获取到,所以HTTPS的个人网站也越来越多。

其中,现在最流行的就是使用可靠的数字证书认证机构 Let's Encrypt 提供的免费SSL证书。

下面,我们就来看看,如何一步步把网站变成HTTPS安全链接。

文章来源: https://www.codelast.com/

『1』 使nginx支持SSL

首先你得让你的web server支持SSL。如果你的nginx本来就支持SSL,那就当我没说。如果不支持,请参考 这个 链接。

『2』 获取及部署SSL证书

为了简化SSL证书的部署,Let's Encrypt提供了一个叫做 Certbot 的客户端软件来辅助完成证书部署工作。

首先要安装这个软件,以CentOS系统为例。在Certbot的网站主页上,正确选择web server和OS之后,会跳转到对应的文档章节,指导你怎么做:

为nginx服务器网站添加HTTPS/配置SSL证书

如果你不想看官方文档,也可以参照我下面的方法来操作。

下面是一个例子(不同的web server、不同的OS是不同的,仅供参考):

  • 启用 EPEL (Extra Packages for Enterprise Linux):
yum install epel-release
  • 如果你使用的是Amazon Elastic Compute Cloud (Amazon EC2),那么可以这样做:
yum -y install yum-utils
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
  • 安装Certbot:
yum install certbot
  • 生成SSL证书:
certbot certonly --webroot -w /path_to_your_web_root_dir/ -d codelast.com -d www.codelast.com

其中, path_to_your_web_root_dir 是你的web server的根目录,例如,如果你使用的是WordPress,那么这个目录下就应该有WordPress的index.php等一堆 php 文件。

命令执行过程中,会交互式地要你输入紧急联系人的Email,填自己的邮箱即可。

文章来源: https://www.codelast.com/

『3』 配置nginx使得网站可以用https://...访问

在你nginx配置文件 nginx.conf 中的 server {...} 段里,应该有这样一句:

listen 80;

这是http访问的标准端口,把它改成:

listen 443 ssl;

使得nginx可以接受https的访问。但同时,我们还要加上下面的配置:

ssl_certificate      /etc/letsencrypt/live/codelast.com/fullchain.pem;

ssl_certificate_key  /etc/letsencrypt/live/codelast.com/privkey.pem;

ssl_trusted_certificate /etc/letsencrypt/live/codelast.com/chain.pem;

这几个路径中的pem文件,就是我们之前用certbot工具生成的。

重启nginx,试验一下是否能用https://...访问网站,浏览器的左上角地址栏里应该有绿色小锁图标:

为nginx服务器网站添加HTTPS/配置SSL证书

到现在已经是一个巨大的进步了。

文章来源: https://www.codelast.com/

『4』 测试网站的SSL安全性

当你认为“似乎”一切都已经完成,一切看起来都那么完美之后,你需要使用 SSL Labs的权威工具 来测试一下网站的SSL安全性,搞不好结果会令你失望哦。

如下图所示,输入网站域名然后点击“Submit”就会开始测试:

为nginx服务器网站添加HTTPS/配置SSL证书

文章来源: https://www.codelast.com/

测试结果可能会像下面这样:

为nginx服务器网站添加HTTPS/配置SSL证书

文章来源: https://www.codelast.com/

SSL安全性得分是C,这是个非常糟糕的分数,它表明我配置的SSL server很不安全!所以需要按照测试结果下方给出的建议来进行修改。从标红的文字知道,得分为C的原因是我没有禁用SSL 3.0协议。为什么要禁用?因为SSLv3已经被发现有严重的安全漏洞,所以不应该再让web server支持它。

『5』 禁用SSLv3

在nginx配置文件的 server {...} 段中,添加下面这句,使得nginx只支持TLS协议:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

这样,重启nginx之后SSLv3就被禁用了。再次运行SSL Labs的测试,会发现安全性评分提高到了B:

为nginx服务器网站添加HTTPS/配置SSL证书

文章来源: https://www.codelast.com/

『6』 配置前向安全性和DHE(Diffie Hellman Ephemeral)

分数B还是比较“惨”的,正如“Grade capped to B”那一句高亮的话所提示的,我的SSL server现在还有DH key交换的安全问题,关于这个问题的详细解释,可以参考 这个 这个 链接。

解决步骤如下:

使用openssl命令生成一个强壮的DH组(前提是你已经安装了openssl软件):

openssl dhparam -out dhparams.pem 2048

命令执行后,命令行会打印出如下信息:

Generating DH parameters, 2048 bit long safe prime, generator 2

This is going to take a long time

正如这句话所描述的,经过漫长的等待结束之后,会在当前目录下生成一个 dhparams.pem 文件。

然后我把这个文件移到 /etc/ssl/certs/ 目录下(其实你放哪里都可以):

mv dhparams.pem /etc/ssl/certs/

最后在nginx中的 server {...} 段中添加这么几句配置:

ssl_dhparam /etc/ssl/certs/dhparams.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;

然后再重启nginx,此问题就解决了。再次运行SSL Labs的测试,会发现安全性评分提高到了令人欣慰的A:

为nginx服务器网站添加HTTPS/配置SSL证书

文章来源: https://www.codelast.com/

『7』 兼容原有的HTTP访问

经过上面的配置,我们已经可以用 https://... 来访问网站,并且网站的SSL安全性也比较高了,但是,网站的老用户可能并不知道我们使用了安全链接,他们仍然会使用 http://... 来访问网站,所以要保证用户使用这个链接访问网站的时候,会自动跳转到 https://... 网址,从而使用安全链接。

nginx配置方法是,在 http {...} 段中添加一个独立的 server {...} 块,如下:

server {

listen 80;

server_name codelast.com www.codelast.com;

return 301 https://$server_name$request_uri;

}

重启nginx之后,试一下用 http://... 来访问网站,应该就能自动跳转到 https://... 的对应链接了。

文章来源: https://www.codelast.com/

『8』 配置HSTS(HTTP严格传输安全,HTTP Strict Transport Security),进一步提高安全性

事实上,前面的nginx配置还有一个安全性漏洞,填补上之后,评分A还可以进一步提高为A+!

这个配置就是所谓的 HSTS

HTTP严格传输安全(英语:HTTP Strict Transport Security,缩写:HSTS)是一套由互联网工程任务组发布的互联网安全策略机制。网站可以选择使用HSTS策略,来让浏览器强制使用HTTPS与网站进行通信,以减少会话劫持风险。

不启用HSTS的潜在问题,也可以参考 这个 链接。

nginx开启HSTS的方法是,在SSL相关的 server {...} 段中添加这么一句话:

add_header Strict-Transport-Security "max-age=31536000;includeSubDomains";

然后重启nginx,再次运行SSL Labs的测试,会发现安全性评分终于达到了A+:

为nginx服务器网站添加HTTPS/配置SSL证书

图下方那句绿色高亮的信息表示我已经启用了HSTS。

文章来源: https://www.codelast.com/

『9』 自动更新证书

Let's Encrypt 提供的免费SSL证书只有90天的有效期,过期之后,如果你不更新证书,那么访问网站的时候,浏览器就会提示证书的安全问题,如果发生这种情况,会对访客造成极大的困扰。

Certbot提供了非常简便的自动更新证书功能,我们只需要执行1个命令,就可以完成证书的更新,所以,把这个命令加入crontab中自动执行,我们就不用担心证书过期问题啦。

测试自动更新证书(实际上并不会更新,只是测试):

certbot renew --dry-run

如果你看到打印出类似于这样一句话:

Congratulations, all renewals succeeded. The following certs have been renewed:

那就说明测试成功了。下面,你需要做的就是把这个命令加入crontab,让其周期性执行:

certbot renew

这个命令的作用是更新证书(不是测试),但是在你的证书到期之前,它并不会产生什么实际的效果。为了保险,Certbot建议每天运行这个命令两次,所以我在我的 /etc/crontab 中添加了下面这几句配置:

# renew Cetbot SSL certificate

59 23 * * * root certbot renew

59 11 * * * root certbot renew

它表示在每天的23:59和11:59时会执行证书更新命令。这样就可以高枕无忧了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning jQuery

Learning jQuery

Jonathan Chaffer、Karl Swedberg / Packt Publishing / 2007-7-7 / GBP 24.99

jQuery is a powerful JavaScript library that can enhance your websites regardless of your background. In this book, creators of the popular jQuery learning resource, learningquery.com, share the......一起来看看 《Learning jQuery》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换