配置HTTPS站点

配置HTTPS站点

前提

  1. 一个已认证的域名(本文为wantp.xyz )
  2. Web 服务器(本文为NGINX 1.17.6)
  3. 已部署的HTTP站点(本文为http://www.wantp.xyz)

HTTPS简介

由于 HTTP 协议在网络上是以明文传输的,使得HTTP请求在被劫持后信息完全暴露,很容易被不法之徒利用。为加强传输过程的安全性,对传输的信息进行加密就变得很有必要,SSL/TLS 协议应运而生。SSL/TLS 协议是运行在 TCPHTTP 中间的,在 TCP 三次握手后,SSL/TLS 验证客户端和服务端的真实性并协商加密方式,后续的HTTP 都以协商好的加密方式传输并在服务端解密,这样即使传输被劫持,黑客拿到的是加密后的信息,很难加以利用。

更详细的 SSL/TLS 工作原理可以从官方文档或者其他文章学习,本文重点在于介绍如何配置一个 HTTPS 站点。

SSL/TLS 协议是SSL协议和TLS协议的统称,TLSSSL的升级版。由于SSL存在很多的已知安全漏洞,升级到SSLv3依然没能解决问题,因此重新设计了TLS作为SSL的替代。一般如果不是为了兼容较古老的浏览器(如IE6),HTTPS 站点建议都只支持TLS

SSL/TLS 是通过浏览器的证书数字签名和服务器的SSL证书来验证客户端和服务端的真实性的,因此要配置HTTPS 站点,第一步需要准备好SSL证书。

一、获取SSL证书

SSL证书一般是跟权威的CA厂商(SymantecGeoTrustTrustAsia 等)购买,一般价格都比较昂贵(对于个人、普通站点和小企业而言)。

常见 SSL 证书有三种类型:

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

DV SSL 的证书价格相对便宜,也有不少免费的,很适合个人网站或者小企业。

国内又拍、腾讯、阿里等厂商都可以申请为期一年的免费 DV 证书。

不过免费的DV SSL证书开源的 Let‘s Encrypt 可能是更好的选择, Let‘s Encrypt 可以颁发3个月有效期的证书,并且可以实现自动续签。

还有一种完全不依赖第三方厂商的方式就是:自签发证书,虽然可以实现https,但是自己颁发的证书是不会得到浏览器的认可的。下面分别介绍自签发证书和Let‘s Encrypt免费证书。

现在HTTP站点在主流浏览器上都会提示不安全。

在这里插入图片描述

1. 自签发证书

购买或申请免费证书如果都觉得很麻烦,还有一个选择是自签发证书。不过自己签发的证书是不被信任的,用于站点时主流浏览器都会提示这是一个不安全的链接。但是对一些强制需要HTTPS但会通过浏览器访问来访问的功能还是可以用的。

1.1 生成私钥
$ openssl genrsa -des3 -out ssl.key 2048

生成了一个rsa私钥,des算法,2048长度,长度低于2048在新版的NGINX会报秘钥长度太短的错误

上述命令会要求输入一个密码

想简化后续的调用可以去掉密码

$ openssl rsa -in ssl.key -out ssl.key
1.2 生成CSR(证书签名请求)
$ openssl req -new -key ssl.key -out ssl.csr

请求需要依次输入国家、地区、城市、组织、组织单位、Common Name(与要部署证书的域名一致)和Email

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:ShangHai
Locality Name (eg, city) []:ShangHai
Organization Name (eg, company) [Internet Widgits Pty Ltd]:wantp
Organizational Unit Name (eg, section) []:wantp
Common Name (e.g. server FQDN or YOUR name) []:wantp.xyz
Email Address []:zhangrongwang798@gmail.com
1.3 生成证书
$ openssl x509 -req -days 3650 -in ssl.csr -signkey ssl.key -out ssl.crt

以上命令签发了有效期为3650天的crt证书。

1.4 配置web服务器

Web服务器配置ssl ,web服务器配置更详细说明请参考 Web服务配置

/etc/nginx/conf.d/wantp.xyz.conf

server {
    listen       443 ssl;	# 监听443端口 开启ssl
    server_name  www.wanp.xyz;	# 域名
    root         /var/www/wantp.xyz/;	# 项目根目录
    index index.html index.php;

    ssl_certificate "/root/ssl/wantp.xyz/ssl.crt";	# SSL证书路径
    ssl_certificate_key "/root/ssl/wantp.xyz/ssl.key";	# SSL证书私钥路径
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;	# 支持的协议
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;	# 加密套件
    ssl_prefer_server_ciphers on;

    ... # 项目其它配置
}

重启 nginx 服务

$ sudo nginx -s reload

访问https://www.wantp.xyz
在这里插入图片描述

浏览器会有红色不安全提示,并且不能直接访问到站点。需要我们信任链接,点击继续前往,站点就能访问了。
在这里插入图片描述

2. Let’s Encrypt免费证书

Let's Encrypt 颁发的证书是浏览器信任的,不会像我们自己签发的会有不安全的提示,对于需要提供网页服务的站点来说是一个更好的选择。

Let's Encrypt 使用 Certbot 来实现证书的发布和自动续签。

2.1 安装Certbot

访问 Certbot 的官方网站,选择 Web 服务器和操作系统,
在这里插入图片描述
会有相应的安装、使用说明,不同系统安装过程有些许差别,可能需要先安装一些依赖库,按照说明一步步安装就好了
在这里插入图片描述

2.2 生成证书

Certbot 安装成功后就可以生成证书了,有两种方式

生成证书并部署并自动部署到Web服务器

$ sudo certbot --nginx

只是生成证书,自己手动部署,我们选用此方式

$ sudo certbot certonly --nginx

上述命令会检测web服务的配置,通过交互选择需要颁发证书的网站

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: wantp.xyz
2: www.wantp.xyz
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1 2 

成功后会生成证书和对应的key

 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/wantp.xyz/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/wantp.xyz/privkey.pem
   Your cert will expire on 2020-03-02. 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"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
2.3 配置web服务器

配置的证书和key的路径

/etc/nginx/conf.d/wantp.xyz.conf

server {
    listen       443 ssl;	# 监听443端口 开启ssl
    server_name  www.wanp.xyz;	# 域名
    root         /var/www/wantp.xyz/;	# 项目根目录
    index index.html index.php;

    ssl_certificate "/etc/letsencrypt/live/wantp.xyz/fullchain.pem";	# SSL证书路径
    ssl_certificate_key "/etc/letsencrypt/live/wantp.xyz/privkey.pem";	# SSL证书私钥路径
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;	# 支持的协议
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;	# 加密套件
    ssl_prefer_server_ciphers on;

    ... # 项目其它配置
}

重启 nginx 服务器

$ sudo nginx -s reload

再次访问https://www.wantp.xyz,链接变成了加锁的安全标识
在这里插入图片描述

2.4 自动续期

出于安全考虑颁发的正式有效期为90天,每三个月都手动去签发一次证书会很麻烦,忘记在有效期内续签还可能导致网站访问出问题。因此Certbot还提供了自动续签的功能。

执行证书更新指令,如果证书在30天内到期就会续订,否则不会进行任何操作

$ sudo certbot renew --dry-run

命令执行后,可以在以下计划任务中看到相关的定时任务,不同系统有差别

/etc/crontab/ 或 /etc/cron.*/* 或 systemctl list-timers

Debian 10/etc/cron.d/certbot 中查看

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

可以看到每天执行两次 renew 检查

证书自动续期配置好了就不用担心证书过期的问题了

二、Web服务器配置

基础配置
server {
    listen       443 ssl;	# 监听443端口 开启ssl
    server_name  www.wantp.xyz;	# 域名
    root         /var/www/wantp.xyz/;	# 项目根目录
    index index.html index.php;

    ssl_certificate "/etc/letsencrypt/live/wantp.xyz/fullchain.pem";	# SSL证书路径
    ssl_certificate_key "/etc/letsencrypt/live/wantp.xyz/privkey.pem";	# SSL证书私钥路径
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;	# 支持的协议
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;	# 加密套件
    ssl_prefer_server_ciphers on;

    ... # 项目其它配置
}
加密套件说明
1、最大兼容性(兼容IE6)
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH;
2、安全与兼容同时兼顾(参考阿里云)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
3、最大安全性(仅兼容主流浏览器)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256::!MD5;
域名重定向的配置

HTTPS 站点配置好后,我们往往希望用户永远访问的是我们的 HTTPS 站点,这时候需要对 HTTP 的站点做些处理,将HTTP请求都重定向到HTTPS上,例如将http://xyz.comhttp://www.xyz.com 都重定向到 https://www.xyz.com 上。

我们通过配置 web 服务器的重定向实现

server {
    listen    80;
    server_name  wantp.xyz www.wantp.xyz;
    return 307 https://www.wantp.xyz$request_uri;    
}

重定向也可以通过 rewrite 实现,但是并不推荐,参考文档
处理 rewrite 时需要匹配正则表达式,这往往意味着更多的消耗。

HSTS

每次访问 http://www.abc.com 都会先发起一个 Http 请求然后重定向到 Https 。这个过程中存在一个风险,就是 Http 请求可能被劫持,导致后面的重定向不安全。通过配置 HSTS 可以让浏览器在有效期内自动将 Http 请求处理成 Https 请求而不是通过发起 Http 请求来重定向。

配置HSTS很简单,只需要添加一个 Strict-Transport-Security header 头即可

server {
	...
    index index.html index.php;
	
	add_header Strict-Transport-Security "max-age=31536000";	# HSTS,有效期为31536000秒

	ssl_certificate "/home/ssl/abc/ssl.pem";	# SSL证书路径
    ...
}

要注意,即使配置了 HSTS 也还是存在第一次HTTP请求被劫持的风险,但是后续的请求都不会通过 HTTP ,风险已经大大的降低了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值