https 详解(二) -- 手把手教你配置你的 https 网站

2019-06-05 18:46:58   最后更新: 2019-06-05 18:46:58   访问数量:66




上一篇文章中,我们详细介绍了 SSL 协议与整个通讯流程

那么,我们如何配置才能让我们自己的网站被浏览器鉴定为安全,并且从根本上保障通讯的安全性呢?

别着急,本文我们就来详细介绍如何配置我们自己的 https 服务

 

 

openssl

我们可以通过开源的 openssl 工具来生成我们的私钥和公钥,openssl 是一个非常强大的开源套件,他包含三个部分:

  1. libcryto -- 通用加密库,包含众多加密算法的实现
  2. libssl -- ssl 机制的实现,用于实现 TLS/SSL 的功能
  3. openssl -- 多功能命令行工具,可以用于加密或解密,甚至可以用来创建和吊销证书

 

有了 openssl,我们就可以轻松生成配置 ssl 所需的公钥和私钥文件了

 

安装

如果你使用的是 centos,执行下面命令即可:

yum install openssl

yum install openssl-devel

 

如果你使用的是 ubuntu,执行下面的命令:

apt install openssl

apt install libssl-dev

 

此外,你也可以到官网下载源码包编译安装:

https://www.openssl.org/

 

生成私钥

执行下面的命令即可生成私钥文件 ssl.key

openssl genrsa -out ssl.key 2048

 

参数 2048 是秘钥的比特长度,2009年12月12日,编号为 RSA-768 的秘钥被成功分解,他的长度为 768 比特,1024 比特秘钥的安全性已经受到威胁,因此使用 2048 比特长度的秘钥目前是非常安全的,不建议生成 1024 比特长度的秘钥

 

生成证书请求csr

执行下面的命令生成包含公钥与服务信息的证书

openssl req -new -key ssl.key -days 3650 -out ssl.csr

 

-days 参数是证书的有效期

 

一键生成上述的私钥与公钥文件

openssl 命令支持意见同时生成公钥与私钥文件:

openssl req -new -newkey rsa:2048 -sha256 -nodes -out test_com.csr -keyout test_com.key -subj "/C=CN/ST=Beijing/L=Beijing/O=website Inc./OU=Web Securi

ty/CN=*.test.com"

 

完成这一步,就已经完成了我们的文件生成工作,如果你要让客户端新人,你必须有一个 CA 颁发的数字证书,到此你有两种选择:使用通用的 CA 认证机构颁发的证书或自己生成根证书与含链证书,具体请分别参考下面两部分中的对应部分

 

根据我们的上一篇文章可以知道,整个信任链最重要的就是认证机构颁发的证书了

我们可以找一个免费的 CA 机构,上传上面生成 csr 文件,按照 CA 的提示进行操作验证,最终获取到机构认证的数字证书,保存到服务器目录下

 

在免费 CA 认证机构中认证证书是最为方便的方式了,但有时,你不希望你的网站或接口被任意访问,因此不能让所有客户端都轻易获取到根证书,显然,在这样的情况下,通过 CA 生成数字证书就无法实现了,我们需要生成自己的根证书与含链证书

 

生成根证书私钥

我们要实现一个 CA,首先要生成 CA 的私钥,生成命令和过程上面已经介绍过,使用项目命令即可

 

生成根证书签发申请文件

执行下面的命令可以生成根证书:

openssl req -new -key ca/ca.key -out ca.csr

 

签发根证书

执行下面的命令签发根证书:

openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.crt

 

签发服务端数字证书

执行下面的命令签发服务端数字证书:

openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

 

在生成所有证书以后,我们只要在相应的客户端安装我们生成的 CA 根证书为信任机构,所有 CA 生成的数字证书都会在安装后被信任

在 python 中,通过 requests 包方法众多 verify 参数传入证书文件地址即可:

requests.get('https://exaple.com', verify='ca.crt')

 

 

如果你的网站是通过 nginx 做负载均衡的,那么只需要在 server 配置中增加下面的配置即可:

listen 443 default ssl; ssl_certificate /etc/nginx/ssl/techlog/fullchain.crt; ssl_certificate_key /etc/nginx/ssl/techlog/ssl.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on;

 

如同我们开始的图片所示,谷歌浏览器已经自动标记我们的网站为安全的了

 

既然我们已经使用了 https 来保障传输的安全性,那么我们就应该废弃原有的 http 请求方式,但我们也不能直接拒绝所有 http 请求

最好的方式,是通过返回自动跳转代码,让客户端可以自动跳转到 https 的新网站中

之前 http 协议的介绍中,我们介绍了自动跳转的代码和他们的不同:

HTTP 协议简介

 

主要有两种 code:

  1. 301 Moved Permanently -- 永久性转移
  2. 302 Found -- 临时跳转

 

此处应该使用的 301 永久性转移,浏览器等客户端会存储旧链接与新链接的对应关系,下次请求旧链接将直接跳转到新链接,而避免了额外的网络请求

下面,我们就来介绍如何配置 nginx 来实现这一过程:

 

rewrite

我们通过 nginx rewrite 的 flag 参数就可以实现 301 跳转,具体可以参考此前的文章:

nginx rewrite 规则的配置

 

server { listen 80; server_name domain.com; rewrite ^(.*) https://$server_name$1 permanent; }

 

 

return

nginx 配置的 return 指令可以指定返回数据的 code 等信息,我们只要显式指定 301 code 即可

 

server { listen 80; server_name domain.com; return 301 https://$server_name$request_uri; }

 

 

error_page

除上述跳转的方式,nginx 也定义了一种错误码,用来强制浏览器跳转到对应的 https 链接,这个错误码就是 497,这是 nginx 的内置 HTTP 状态码,HTTP 协议中并没有定义这个状态码,nginx 会自动处理他并跳转

 

server { listen 80; listen 443 ssl; server_name domain.com; ssl on; ssl_certificate /etc/nginx/ssl/domain.com.crt; ssl_certificate_key /etc/nginx/ssl/domain.com.crt; # other error_page 497 https://$server_name$request_uri; }

 

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,全部原创,只有干货没有鸡汤

 

 






技术帖      技术分享      nginx      http      ssl      https      openssl     


京ICP备15018585号