一、为什么使用HTTPS
为什么要使用HTTPS,就两个字:安全。我们知道在http下都是明文进行数据传输的,任何人截取到了你的数据,都能获取你的信息。这么大的隐患没有人能够人忍受得了,所以为了消除这些隐患,我们必须使用更安全的方法。
HTTPS 在 TCP 和 HTTP 之间增加了 TLS(Transport Layer Security,传输层安全),提供了内容加密、身份认证和数据完整性三大功能。这样,即使其他人截取到了你的数据,他们也是一脸懵逼的,看到的都是 一串毫无规则的字母数据。我们的隐私就很难被其他人知道。
二、SSL 证书
Nginx 配置主要有两个步骤:签署第三方可信任的 SSL 证书 和 配置 HTTPS。
有关 SSL 的介绍可以参阅维基百科的传输层安全协议和阮一峰先生的 《SSL/TLS协议运行机制的概述》。
SSL 证书主要有两个功能:加密和身份证明,通常需要购买,也有免费的,通过第三方 SSL 证书机构颁发,常见可靠的第三方 SSL 证书颁发机构有:StartSSL、Comodo、GlobolSign、GeoTrust…
StartCom 机构上的 SSL 证书有以下几种:
企业级别:EV(Extended Validation)、OV(Organization Validation)
个人级别:IV(Identity Validation)、DV(Domain Validation)
其中 EV、OV、IV 需要付费
免费的证书安全认证级别一般比较低,不显示单位名称,不能证明网站的真实身份,仅起到加密传输信息的作用,适合个人网站或非电商网站。由于此类只验证域名所有权的低端 SSL 证书已经被国外各种欺诈网站滥用,因此强烈推荐部署验证单位信息并显示单位名称的 OV SSL 证书或申请最高信任级别的、显示绿色地址栏、直接在地址栏显示单位名称的 EV SSL 证书。
使用 OpenSSL 生成 SSL Key 和 CSR 文件
配置 HTTPS 要用到私钥 example.key 文件和 example.crt 证书文件,申请证书文件的时候要用到 example.csr 文件,OpenSSL 命令可以生成 example.key 文件和 example.csr 证书文件。
CSR:证书签署请求文件,里面包含申请者的 DN(Distinguished Name,标识名)和公钥信息,在第三方证书颁发机构签署证书的时候需要提供。证书颁发机构拿到 CSR 后使用其根证书私钥对证书进行加密并生成 CRT 证书文件,里面包含证书加密信息以及申请者的 DN 及公钥信息
Key:证书申请者私钥文件,和证书里面的公钥配对使用,在 HTTPS 『握手』通讯过程需要使用私钥去解密客戶端发來的经过证书公钥加密的随机数信息,是 HTTPS 加密通讯过程非常重要的文件,在配置 HTTPS 的時候要用到
使用 OpenSSl命令可以在系统当前目录生成 example.key 和 example.csr 文件:
openssl req -new -newkey rsa:2048 -sha256 -nodes
-out example_com.csr -keyout example_com.key
-subj “/C=CN/ST=ShenZhen/L=ShenZhen/O=Example Inc./OU=Web Security/CN=example.com”
下面是上述命令相关字段含义:
C:Country ,单位所在国家,为两位数的国家缩写,如: CN 就是中国
ST 字段: State/Province ,单位所在州或省
L 字段: Locality ,单位所在城市 / 或县区
O 字段: Organization ,此网站的单位名称;
OU 字段: Organization Unit,下属部门名称;也常常用于显示其他证书相关信息,如证书类型,证书产品名称或身份验证类型或验证内容等;
CN 字段: Common Name ,网站的域名;
生成 csr 文件后,提供给 CA 机构,签署成功后,就会得到一個 example.crt 证书文件,SSL 证书文件获得后,我们将example_com.key 和example.crt文件上传到服务器上,就可以在 Nginx 配置文件里配置 HTTPS 了。
PS: CSR文件用来申请证书(提供给证书供应商);
KEY文件是私钥,用来配置ssl(放到服务器);
CRT是证书供应商颁发的证书(放到服务器)
三、自签名证书
因为在CA机构获取SSL证书太麻烦(因为要钱),所以我们可以自己通过keytool去生成一个证书,然后使用,并不是CA机构去颁发的。使用自签名证书的网站,大家在使用浏览器访问的时候,一般都是报风险警告。但是对于我的网站这并不影响,没有什么重要的东西。
在上面我们知道了配置HTTPS 需要两个文件,key文件和crt文件。我们通过openssl这个命令来生成这两个文件。
先来生成key文件,下面生成crt文件需要这个:
openssl genrsa -out server.key 2048
运行这个命令后,当前目录下回生成一个server.key文件。我们在依赖这个文件生成crt文件:
openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
运行后,会让你输入一些信息,跟上面一样。这里要注意的是,Common Name (e.g. server FQDN or YOUR name) []: 这一项,是最后可以访问的域名,我这里为了方便测试,写成 localhost ,如果是为了给网站生成证书,需要写成 xxxx.com 。
最后我们将这两个文件放入某个目录中,最好是在/etc/nginx/ 创建一个目录,将其放在里面,毕竟我们是为Nginx配置HTTPS。最后一定要记住这个目录,下面配置时要用到。
四、配置Nginx,支持HTTPS
在前一个Nginx分类的文章中,我们配置了Nginx支持http,为了让配置HTTPS后不影响前面的,我建议在/etc/nginx/conf.d/ 目录下创建新的配置文件来配置HTTPS。这样我们网站既可以支持http, 也可以支持HTTPS。
我们创建https.conf文件,添加配置:
server {
listen 443 ssl; # 1.1版本后这样写
server_name www.flighting.top; #填写绑定证书的域名
ssl_certificate /etc/nginx/crt/server.crt; # 指定证书的位置,绝对路径
ssl_certificate_key /etc/nginx/crt/server.key; # 绝对路径,同上
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
ssl_prefer_server_ciphers on;
location / {
# index index.html index.jsp;
proxy_pass http://192.168.223.104;
proxy_redirect ~^http://([^:]+)(:\d+)?(.*)$ https://$1$3;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Proto $scheme;
#proxy_set_header X-Forwarded-Port $server_port;
}
}
完成上面的配置后重启Nginx就可以了。为什么可以在/etc/nginx/conf.d/ 目录下添加个https.conf文件后,就能使用https了,是因为在nginx.conf文件中加载了这个目录的所有文件后缀为.conf的文件。我们可以在nginx.conf找到 include /etc/nginx/conf.d/*.conf 这样的配置,这是默认的,你可以随意更改。
我们不在nginx.conf中配置https也方便以后不用https直接删掉https.conf(或者改个名称,但要注意文件后缀不能再为.conf)就行了。
配置中大部分都有注释,这里也不需要多讲了、主要说一下location 中的。
proxs_pass 是个代理,我们访问https://192.168.223.104/的所有请求都会转到http://192.168.223.104去,这个就是我Nginx上一篇配置完成后需要访问的。其实添加了https,主要区别就是原来在浏览器直接访问http://192.168.223.104,现在需要在浏览器访问https://192.168.223.104/ 然后Nginx把请求转给 http://192.168.223.104 。
proxy_redirect 这个是关于重定向的,这个也是在使用中发现bug后解决的。原因就是在我后台代码中有重定向的操作,然而nginx与tomcat之间的通信是http协议,所以当后台代码有重定向redirect时,实际上是重定向到了http下的地址,导致了浏览器随后访问的都是http请求。所以我加了proxy_redirect 将所有的http访问重定向到https。
当然还有其他的办法解决这个问题,配置最后被我注释掉的三个配置也是其中一个办法,但是在我实际情况中就没有起作用,原因是我使用的都不是默认端口,http使用的端口为12345,https使用的端口为3389。我上面写的配置都是在本地机上测试的,所以用的都是默认端口。但在我云服务器上不是用默认端口的,主要原因是我使用的是域名访问,而非IP,然而域名没有备案(太麻烦),使用默认端口访问会被禁止。
云服务器上的配置为: proxy_redirect ~http://([:]+)(:\d+)?(.*)$ https://$1:3389$3; 在后面修改了端口,因为我云服务器https使用的端口为3389。
五、结束
到这里基本就完成了。上一段,我提了一些我的实际情况,在其中还有一个问题。也是因为我使用的不是默认端口的原因吧。emm… 仔细想了想,这个好像在我没配置https就出现的,还是在上一篇文章中添加吧