nginx基础学习(六):nginx之https的配置

之前写的关于nginx的内容都是http的,现在轮到https上场了。其实https和http的不同是在于端口、证书和秘钥,其他基础配置都是相同的,这一篇我们来看看如何生成https证书和私钥、https实现的流程和相关的使用注意事项。当然这个证书和私钥是我们自己生成的,没有通过权威机构认证,在浏览器请求显示的时候会有提醒。要是想要正式的证书和秘钥,可以到相关机构去购买,有点耗银子。有兴趣的可以去找找。

https实现过程

https在请求的时候会从nginx端下载https证书,然后根据证书内的公钥来对请求的内容进行加密,加密完成后请求到nginx,nginx根据私钥来解密,将解密后的内容通过http请求发到对应tomcat应用(当然是不仅限于tomcat)。具体流程看下面的图示:

看了这张图后,发现以前我对https的理解是不对的。使用公钥加密的内容并不是请求的数据信息,而是一个随机的秘钥。然后根据秘钥对称加密请求数据,nginx通过秘钥来进行对称解密得到请求数据,最终以http的方式转发到对应的服务。

https证书、私钥生成

这种生成方式只能说自己玩玩可以,公司内的产品上线一般都不会这么用。我记得在12306没有改版之前使用的https就是自己生成的,导致请求不会直接进入官网首页,而是给出警告页面,需要进行一步信任操作才能进入。12306敢在线上使用那是因为它NB(有本事你就别用)。如果换一个初创的公司这样做,估计坟头上的草已经三丈高啦。

生成过程:

  • 创建服务器私钥

    1
    openssl genrsa -des3 -out server.key 1024

    这一步需要输入口令,可以理解为是密码,输入两次。

  • 创建签名请求的证书(CSR)

    1
    openssl req -new -key server.key -out server.csr

    这一步需要输入内容很多,但是大部分可以省略,首先输入口令,然后输入国家名(cn),然后输入城市名(sh),咱们都是中国人,都写cn就可以,城市名根据你所在城市来写。这两项完成输入后还有很多需要填的,直接回车,一直到结束即可。

  • 加载SSL支持的nginx并使用删除私钥是除去必须的口令

    1
    openssl rsa -in server.key -out server_nopass.key

    这一步是除去口令的验证,减少输入口令的麻烦。

  • 最后标记证书使用上述私钥和CSR

    1
    openssl x509 -req -days 365 -in server.csr -signkey server_nopass.key -out server.crt

    这一步正式生成证书,将在客户端和nginx建立连接初期提供给客户端。

注意:在机器中没有安装nginx或者安装nginx没有包含https模块的,在生成证书、私钥过程可能会受一点阻塞。查看nginx是否已经安装https模块的命令:

1
/usr/local/nginx/sbin/nginx -V

这里V是大写的,另外/usr/local/nginx/sbin/nginx会根据你nginx安装目录的不同而不同。然后会看到如下的输出内容:

1
2
3
4
5
nginx version: nginx/1.13.10
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

configure arguments信息,包含--with-http_ssl_module即为安装了https模块,如果没有需要对nginx重新配置、编译、安装,这个就不多说了,具体怎么做可以参考下面推荐文章的第一篇。

nginx.conf内https的配置

其实配置很简单,除了加上端口变化、证书和私钥的信息,其他都是和http配置相同的。配置如下:

1
2
3
4
5
6
7
8
9
10
11
server {
listen 443 ssl;
server_name blog.itcrud.com;

ssl_certificate /usr/local/https/server.crt;
ssl_certificate_key /usr/local/https/server_nopass.key;

location / {
# ……
}
}

端口由之前的80换成443 ssl,然后加上ssl_certificatessl_certificate_key指定证书和私钥的存储位置。

http跳转https

如果你们平时使用百度细心的话会发现,当输入http://www.baidu.com的时候,浏览器上的地址会自动变换成https://www.baidu.com。通过浏览器的控制台可以看到当请求http的百度时会返回一个状态码307 Internal Redirect,然后响应头里面的location对应的地址是https的百度地址,接着浏览器会根据这个https地址重新请求打开百度首页。这是就是在nginx内动了手脚。配置如下:

1
2
3
4
5
server {
listen 80;
server_name blog.itcrud.com;
rewrite ^/ https://blog.itcrud.com redirect; # 通过rewrite重定向
}

是不是很简单。

http和https的混用问题

在微服务里面,有很多子模块,每个子模块都是独立的,域名也是独立的。有时候在展示一个页面的内容,需要发送多个ajax请求到多个子模块中获取数据,然后渲染到页面上。但是这里存在一个问题就是http和https混用。

有以下两种情况:

  • 当主页面是使用的http请求,但是请求子模块是用的https,这样会导致请求子模块失败,因为这样是不支持的。建议在使用https的时候做好规划,不要盲目,有可能会导致项目的bug,解决方案就是把所有子模块都改成使用https。
  • 当主页面是使用的https请求,子模块使用的是http,这个是不受影响。但是从安全角度来考虑,还是建议都换成使用https。

注意:这个混用的问题我们是建立在跨域问题已经解决的前提下说的。


本文作者:IT-CRUD
原文地址:http://blog.itcrud.com/blogs/2019/01/nginx-https-original
版权归作者所有,转载请注明出处

推荐文章

支付宝 微信

如果文章对你有帮助,欢迎点击上方按钮打赏作者