from--https://xiaoyue26.github.io/2019/04/14/2019-04/2019%E5%B9%B4%E7%9A%84%E4%BA%BA%E4%BB%AC%E5%A6%82%E4%BD%95%E7%94%9F%E6%88%90HTTPS%E8%AF%81%E4%B9%A6/
2019年的人们如何生成HTTPS证书
由于配置相关的教程总是有年限限制,过期就不能用了,本教程至少保证2019.4.14还可用。
环境: centos,nginx,chrome
备注: 可以避免chrome的NET::ERR_CERT_COMMON_NAME_INVALID
错误。
摘要
从HTTP升级到HTTPS: 用openssl命令创建本地的CA,然后自签证书,然后配置到nginx中,最后信任一下本地CA即可。
需求
从HTTP协议升级到HTTPS。
用HTTPS可以防止会话内容被拦截解析,同时防止中间人攻击,防止他人伪装称你的网站,欺骗你的客户。
SSL协议的详细含义可以参见:
https://xiaoyue26.github.io/2018/09/26/2018-09/%E9%80%9A%E4%BF%97%E7%90%86%E8%A7%A3SSL-TLS%E5%8D%8F%E8%AE%AE%E5%8C%BA%E5%88%AB%E4%B8%8E%E5%8E%9F%E7%90%86/
现有架构
请求=>nginx服务器=>后端网站服务
改造思路/原理
原理上只需要让nginx负责SSL协议的部分即可,不需要动后端网站服务。
客户端发送HTTPS请求到nginx服务器,nginx服务器转发HTTP请求到后端网站服务。
(封装的思想,上层变动对底层HTTP服务透明)
HTTPS中断、TLS中断:
nginx直接负责搞定ssl部分,netty等后端服务只需要负责http部分就好了。
如果依赖nginx的话,netty的SslHandler什么的都可以废掉了XD
所以我们只需要关心架构中的前半部分:
请求=>nginx服务器
再分解一下这部分的话:
用户=>浏览器(chrome)==https请求=>nginx服务器
整个架构中我们需要修改的部分:
- nginx配置.
是的,就这么一项。所以改造成本很低。
当然了,如果不想花钱买官方CA证书的话,也就是自己弄一个CA, 然后给自己的网站颁发证书的话,还需要改动用户浏览器的信任CA,那么需要修改的部分就增加一项了:
- nginx配置;
- 用户浏览器信任CA。
这里的证书、CA是个啥概念呢?
证书: 就好比我们网站的身份证;
CA : 就好比派发身份证的派出所。
本质上是一个信任传递、担保的过程,用户浏览器会默认信任几个官方的CA,只要官方CA承认的网站,信任传递一下,用户就可以也信任了。
参见下图可以通过chrome右键”检查”的security
面板查看证书的详细信息。
而如果我们自己弄的CA的话,好比自己开的黑作坊,用户不可能直接信任黑作坊签发的身份证的,就需要修改用户浏览器配置了,加入我们的私人CA证书。
公网HTTPS
生成数字证书
可以参考:
http://www.ruanyifeng.com/blog/2016/08/migrate-from-http-to-https.html
从
https://www.gogetssl.com/
https://www.ssls.com/
https://sslmate.com/
购买SSL证书。
免费的:
https://certbot.eff.org/
可以用这个工具,选择转发服务器和操作系统,生成证书:
https://certbot.eff.org/lets-encrypt
配置nginx
把原来nginx配置中的:
1 | listen 80; |
改成:
1 2 3 | listen 443 ssl; ssl_certificate /usr/local/nginx/ssl/private/server.crt; ssl_certificate_key /usr/local/nginx/ssl/private/device.key; |
这里的service.crt就是数字证书了。
如果要支持http和https同时可以访问,就把listen 80
再加上。
如果要强制https,即使访问了http也强制跳转https(一般都需要这样搞),可以增加rewrite配置:
1 2 3 4 5 | server { listen 80; server_name localhost; rewrite ^(.*) https://$server_name$1 permanent; } |
局域网HTTPS
公网https起码要买个域名,买个服务器(阿里云),如果只是局域网玩玩、或者自签证书,可以如下操作:
- 本地生成一个CA;
- 用这个CA给自己网站的数字证书签名,生成网站数字证书;
- 修改nginx配置;
- 配置用户chrome信任第一步中的CA。
可以看出多了1,2两步来生成证书,代替购买证书;
多了第4步来强制用户信任非官方CA.
1. 本地生成CA
找个干净的目录开始操作:
1 2 | openssl genrsa -des3 -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem |
里面可以填下密码,email地址和ca的名字。其他的可以留空。
第一条命令: 生成本地CA的密钥rootCA.key
(要记住你设置的密码,比如我的是staythenight
);
第二条命令: 用这个密钥进行签名,生成一张CA的证书rootCA.pem
.
(这里设置的过期时间为1024天).
2. 生成网站数字证书(用这个CA给自己网站的数字证书签名)
为了避免chrome的NET::ERR_CERT_COMMON_NAME_INVALID
错误,需要在网站证书里填一些额外的信息。
首先创建文件server.csr.cnf
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [req] default_bits = 2048 prompt = no default_md = sha256 distinguished_name = dn [dn] C=US ST=RandomState L=RandomCity O=RandomOrganization OU=RandomOrganizationUnit emailAddress=296671657@qq.com # 修改成自己的email CN = kandiandata.oa.com # 修改成自己的域名 |
然后创建文件v3.ext
:
1 2 3 4 5 6 7 8 | authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = kandiandata.oa.com # 修改成自己的域名 DNS.2 = localhost |
创建证书:
1 2 3 4 5 6 | openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout device.key -config server.csr.cnf openssl x509 -req -in server.csr \ -CA rootCA.pem \ -CAkey rootCA.key \ -CAcreateserial -out server.crt -days 1800 -sha256 -extfile v3.ext |
第一条命令: 用server.csr.cnf
配置生成网站证书server.csr
,同时生成网站私钥device.key
(给nginx用的)。
第二条命令: 用CA私钥rootCA.key
以CA的名义(rootCA.pem
)️给网站证书签名,生成CA签名后的证书server.crt
,同时加上v3.ext
中的配置(防止chrome报错)。
到这里我们就准备好了下一步nginx要用到的两个文件:
1 2 | server.crt device.key |
server.crt
: 网站的数字证书;
device.key
: 网站的私钥,用来解开用户发过来的通信密码。详细原理参见:
http://xiaoyue26.github.io/2018/09/26/2018-09/%E9%80%9A%E4%BF%97%E7%90%86%E8%A7%A3SSL-TLS%E5%8D%8F%E8%AE%AE%E5%8C%BA%E5%88%AB%E4%B8%8E%E5%8E%9F%E7%90%86/
3. 配置nginx
这里和之前的一样,打开ssl支持,监听443:
1 2 3 | listen 443 ssl; ssl_certificate /usr/local/nginx/ssl/private/server.crt; ssl_certificate_key /usr/local/nginx/ssl/private/device.key; |
加上监听80+重定向:
1 2 3 4 5 | server { listen 80; server_name localhost; rewrite ^(.*) https://$server_name$1 permanent; } |
4. 配置用户chrome信任第一步中的CA
将第一步中的rootCA.pem
发送给用户,让它安装即可。
(千万不要发错了。)
如果是mac系统,可以直接双击安装到钥匙串中:
系统
=>证书
,然后完全信任ca的证书即可:最后得到chrome的承认:其他
还可以查看openssl支持的ssl/tls版本:
1 | openssl ciphers -v | awk '{print $2}' | sort | uniq |
查看本地的443端口是否支持tls1.2协商:
1 | openssl s_client -connect localhost:443 -tls1_2 |
成功的话会返回一大段内容,包括:
1 2 3 4 5 6 7 8 | # 前面一大堆 --- Certificate chain 0 s:/C=US/ST=RandomState/L=RandomCity/O=RandomOrganization/OU=RandomOrganizationUnit/emailAddress=296671657@qq.com/CN=kandiandata.oa.com i:/C=XX/L=Default City/O=tencent/OU=kandian/CN=pipe_ca/emailAddress=296671657@qq.com --- Server certificate # 后面一大堆 |
失败的话:
1 2 3 4 5 | --- no peer certificate available --- No client certificate CA names sent --- |