Linux,security,nginx,network,http,web,Authentication

Nginx使用https通信及实现多域名https

概述

  HTTP协议是明文传输的,没有经过任何安全处理.那么这个时候就很容易在传输过程中被中间人窃听,篡改,冒充等风险.这里提到的中间人主要指一些网络节点,是用户数据在浏览器和服务器中间传输必须要经过的节点,比如WIFI热点,路由器,防火墙,反向代理,缓存服务器等.HTTP协议中间人可以窃听隐私,使用户的敏感数据暴露无遗,篡改网页,例如往页面插的广告内容,甚至进行流量劫持,比如有的时候你会发现域名没输错,结果却跑到了一个钓鱼网站上,因为被它劫持了

  此时,HTTPS的价值就体现出来了,HTTPS协议在应用层的HTTP协议和以及传输层TCP协议之间的会话层加入了SSL/TLS协议,用作加密数据包.在真正数据传输之前,进行握手通信,握手的信息交换主要包括: 双方确认加密协议的版本,确认身份(其中浏览器客户端的身份有时是不需要确认的),确认传输真正数据的加密密码(对称加密).在用作信息传输的加密密码确认之后,接下来的通信数据都会加密后再传输,从而达到防窃取的作用

https通信过程

<center>
</center>

客户端发起https请求

  • 客户端访问某个web端的https地址,一般都是443端口

服务器端向客户端发送自己的数字证书

  • 服务端给客户端传递证书,其实就是公钥,里面包含了很多信息,例如证书得到颁发机构,过期时间等等

客户端解析证书

  • 客户端收到服务器端的证书后,它会去验证这个数字证书是不是服务器的,数字证书有没有什么问题,数字证书如果检查没有问题,就说明数字证书中的公钥确实是服务器的.检查数字证书后,如果证书没有问题就生成一个随机值,然后用证书对该随机值进行加密

传送加密信息

  • 将用证书加密后的随机值传递给服务器,目的就是为了让服务器得到这个随机值,以后客户端和服务端的通信,就可以通过这个随机值进行加密解密了

服务端解密信息

  • 服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密.所谓对称加密就是将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容.而正好客户端和服务端都知道这个私钥,所以只要机密算法够复杂就可以保证数据的安全性

传输加密后的信息

  • 服务端将用私钥加密后的数据传递给客户端,在客户端可以被还原出原数据内容

客户端解密信息

  • 客户端用之前生成的私钥获解密服务端传递过来的数据,由于数据一直是加密的,因此即使第三方获取到数据也无法知道其详细内容

配置实现

  在nginx编译安装完成后,即可对其进行配置.采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请.区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务).这套证书其实就是一对公钥和私钥

生成子签名证书

  • 自签名CA证书
mkdir /app/ngx/ssl
cd /app/ngx/ssl
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
  • 生成私钥和证书签发请求文件
openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.s4lm0x.org.key -out www.s4lm0x.org.csr
  • 签发证书
openssl x509 -req -days 3650 -in www.s4lm0x.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.s4lm0x.org.crt

Nginx证书配置

  • nginx的https功能基于模块ngx_http_ssl_module实现,如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数--with-http_ssl_module开启,官方文档: https://nginx.org/en/docs/http/ngx_http_ssl_ module.html,配置参数如下:
ssl on | off;    #为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
ssl_certificate /path/to/file;   #当前虚拟主机使用使用的公钥文件,一般是crt文件
ssl_certificate_key /path/to/file;   #当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];    #支持ssl协议版本,早期为ssl现在是TSL,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];     #配置ssl缓存
    off: 关闭缓存
    none: 通知客户端支持ssl session cache,但实际不支持
    builtin[:size]:使用OpenSSL内建缓存,为每worker进程私有
    [shared:name:size]:在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
ssl_session_timeout time;    #客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
  • nginx虚拟主机配置
server {
    listen 443 ssl;
    server_name ngx.s4lm0x.org;
    ssl_certificate /app/ngx/ssl/www.s4lm0x.org.crt;
    ssl_certificate_key /app/ngx/ssl/www.s4lm0x.org.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;

    location / {
        root /app/data;
        index index.html;
    }
}

实现多域名HTTPS

  Nginx支持基于单个IP实现多域名的功能,并且还支持单IP多域名的基础之上实现HTTPS,其实是基于Nginx的SNI(Server Name Indication)功能实现,SNI是为了解决一个Nginx服务器内使用一个IP绑定多个域名和证书的功能,其具体功能是客户端在连接到服务器建立SSL链接之前先发送要访问站点的域名(Hostname),这样服务器再根据这个域名返回给客户端一个合适的证书

  • 生成私钥和证书签发请求文件
openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.s4lm0x.net.key -out www.s4lm0x.net.csr
  • 签发证书
openssl x509 -req -days 3650 -in www.s4lm0x.net.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.s4lm0x.net.crt
  • nginx虚拟主机配置
server {
    listen 443 ssl;
    server_name www.s4lm0x.org;
    ssl_certificate /app/ngx/ssl/www.s4lm0x.org.crt;
    ssl_certificate_key /app/ngx/ssl/www.s4lm0x.org.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;

    location / {
        root /app/data/org;
        index index.html;
    }
}

server {
    listen 443 ssl;
    server_name www.s4lm0x.net;
    ssl_certificate /app/ngx/ssl/www.s4lm0x.net.crt;
    ssl_certificate_key /app/ngx/ssl/www.s4lm0x.net.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;

    location / {
        root /app/data/net;
        index index.html;
    }
}
微信扫一扫,向我赞赏

微信扫一扫,向我赞赏

微信扫一扫,向我赞赏

支付宝扫一扫,向我赞赏

回复

This is just a placeholder img.