Nginx 配置详解(三):Nginx + HTTPS 配置

Nginx 配置详解(三):Nginx + HTTPS 配置

本系列文章包括:

本文介绍 Nginx + HTTPS 配置。

关于如何安装 Nginx 和 PHP 请参考本人的另一篇文章 CentOS 7中安装 LNMP (Linux + Nginx + MySQL + PHP)

HTTP vs HTTPS

HTTP 协议传输的数据都是未加密的,也就是明文传输;HTTPS 是 HTTP 运行在 SSL/TLS 之上,数据是加密传输的。

如下图所示:

http-vs-https.png

HTTPS 相较于 HTTP 最大的好处就是“安全”,但是加密过程会消耗服务器资源,因此会影响用户的访问速度。

根据 W3TECHS.com 站点的统计,截止 2018 年 6 月,默认采用 https 的站点比率为 35.1% ,在过去一年里呈增长趋势,详见:Usage of Default protocol https for websites

Google 早在 2014 年已经开始鼓励大家讲 HTTP 升级到 HTTPS 了,并且宣称将略微调高采用 HTTPS 的网站在搜索结果中的排名,详见:HTTPS as a ranking signal

因此,如果你的网站流量较多依赖于搜索引擎,升级为 HTTPS 还是值得的。

HTTPS 协议简介

为了便于理解,下面改编了一段“鹿鼎记”的故事,来描述使用 HTTPS 协议的通信过程。

故事发生在康熙年间,天地会青木堂堂主韦小宝受陈总舵主之命,潜入清廷做卧底,深得皇帝恩宠。陈总舵主觉得满清气数已尽,遂命天地会兄弟与韦小宝接头,约定时间、地点、行动及暗号,里应外合,推翻满清。
整个故事情节如下图所示:

https-ludingji.png

这个故事要与下图(该图源自又拍云)对照来看:

https-workflow.png

流程说明:

  1. 客户端向服务端打招呼:“Hello服务端,咱俩私聊吧!”

  2. 服务端回复:“Hello客户端,好啊!”,并主动把数字签名和数字证书都发给了客户端。客户端收到之后用它们对服务端进行身份验证:

    • 数字签名中包含聊天内容的摘要(例如可以是md5值,客户端通过该摘要可判断传输途中聊天内容是否被篡改);

    • 但是服务端不能将数字签名直接(未加密)发给客户端,这样要是被黑客截获,便可以冒充服务端;

    • 于是,服务端用他的私钥对数字签名进行了加密,让客户端用服务端的公钥解密就好了,若解密成功便能确认服务端身份(因为公钥与私钥是唯一配对的);

    • 可是客户端一开始并没有服务端的公钥,客户端找啊找,最后发现服务端发来的数字证书中包含公钥;

    • 客户端心想,这个公钥会不会是黑客冒充吧?客户端无法确认真伪,于是去问证书颁发机构;

    • 证书颁发机构说:“我把服务端(在我这里认证过)的公钥发给你吧,你自己去判断”,于是把服务端的公钥发给了客户端;

    • 客户端比较了证书颁发机构发来的公钥和“服务端”(可能是黑客冒充的)发来的公钥,是相同的,于是便相信这是真的服务端了。

  3. 客户端确认了服务端的身份,便完全相信服务端了。

    • 但是有一个问题,双方私聊的内容若是通过非对称加密(客户端用公钥加密/解密,服务端用私钥加密/解密),那么服务端发送给客户端的内容黑客截获后也能解密(因为服务端的公钥是公开的)。

    • 客户端想,那我们用对称加密吧,客户端想好一种加密方式(比如“反转聊天文字内容”),然后把他的想法通过服务端公钥加密(最后一次非对称加密,只有服务端的私钥才能解密,防止黑客窃取加密方式),然后发送给服务端。

  4. 服务端收到客户端的消息,用私钥解密一看,原来是“我们通过反转聊天文字内容的方式加密聊天内容吧”。

    • 服务端想立马回复“好的,就按你说的方式加密”,但转念一想说好了要反转聊天文字;

    • 于是,服务端给客户端回复了“密加式方的说你按就,的好”。

  5. 客户端收到服务端的回复,反转文字进行解密,知道服务端已经明白并同意了他的想法,便开心地跟服务端聊起来:

    客户端:啊人里哪是你            (服务端反转文字解密:你是哪里人啊)
    服务端:呢你,人东山是我        (客户端反转文字解密:我是山东人,你呢)
    客户端:呢乡老俩俺,人东山是也俺(服务端反转文字解密:俺也是山东人,俺俩老乡呢)
    服务端:心开好,缘友好          (客户端反转文字解密:好有缘,好开心)
    ... (俩人聊得很开心,期间,黑客截获了部分内容,打开一看,一脸懵逼)
    

选择证书颁发机构

证书颁发机构颁发的证书通常分为三种类型:

类型 描述
域名型SSL证书(DV SSL) 信任等级普通,只需验证网站的真实性便可颁发证书保护网站
企业型SSL证书(OV SSL) 信任等级强,须要验证企业的身份,审核严格,安全性更高
增强型SSL证书(EV SSL) 信任等级最高,一般用于银行证券等金融机构,审核最严格,安全性最高

个人博客(或小型企业)而言,普通的就够了(信任等级越高,意味着收费也会越高)。

W3TECHS.com 站点统计了市面上都有主流的 CA 机构及其市场份额,下图是 2018 年 6 月的数据:

certificate-authority-list.png

本文推荐使用 Let’s Encrypt 机构颁发的证书,推荐理由:

  • 免费;
  • 简单:可以使用脚本自动创建和安装证书(因此只支持域名型SSL证书);
  • 可靠:由互联网安全研究小组(缩写ISRG,一个非营利性组织)提供服务。

如何配置 Nginx + HTTPS ?

本节内容以 Let’s Encrypt 证书创建和安装为例。

步骤一:安装并生成 CA

命令如下:

yum install certbot.noarch -y
yum install python2-certbot-nginx.noarch -y
certbot --nginx certonly --nginx-server-root /usr/local/nginx/conf -d shawaner.com -d www.shawaner.com

其中:

  • 最后一条命令需替换为你自己的域名和 Nginx 配置文件目录;

  • 上面 certbot 命令会输出以下信息:

    IMPORTANT NOTES:
     - Congratulations! Your certificate and chain have been saved at:
       /etc/letsencrypt/live/shawaner.com/fullchain.pem
       Your key file has been saved at:
       /etc/letsencrypt/live/shawaner.com/privkey.pem
       Your cert will expire on 2018-09-08. To obtain a new or tweaked
       version of this certificate in the future, simply run certbot
       again. To non-interactively renew *all* of your certificates, run
       "certbot renew"
    

    其中包含了证书(certificate)文件路径和私钥(private key)文件路径,需记下来,后面配置 Nginx 时需要用到。

    另外,上面还提示了证书的有效期(默认是90天),有效期之后证书将会变为无效,此时仅需要更新证书即可,按照上面的提示,执行以下命令即可更新证书:

    certbot renew
    

步骤二:配置 Nginx

找到 Nginx 的配置文件(nginx.conf),添加如下指令:

server {
    listen 443 ssl;
    server_name shawaner.com www.shawaner.com;
    ssl_certificate         /etc/letsencrypt/live/shawaner.com/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/shawaner.com/privkey.pem;
    keepalive_timeout       70;
    ...
}
server {    # 若用户手动输入 http 时,自动跳转至 https
    listen 80;
    server_name shawaner.com www.shawaner.com;
    return 301 https://$server_name$request_uri;
}

参考文章:

本文允许转载,但请保持原文完整,并且注明出处:https://shawaner.com/tech/web-dev/nginx-configs-part3-https。如对本文有任何疑问或纰漏指出,请在文章评论区留言。

发表评论

电子邮件地址不会被公开。 必填项已用*标注