# Nginx 安全 - HTTPS 加密实践

# 1.HTTPS 基本概述

# 1.1 为何需要 HTTPS

因为 HTTP 采用的是明文传输数据,那么在传输(账号密码、交易信息、等敏感数据)时不安全。容易遭到篡改,如果使用 HTTPS 协议,数据在传输过程中是加密的,能够有效避免网站传输时信息泄露

# 1.2 什么是 HTTPS
  • HTTPS 安全的超文本传输协议,我们现在大部分站点都是通过 HTTPS 来实现站点数据安全。
  • 早期网景公司设计了 SSL(Secure Socket Layer)安全套接层协议,主要对 HTTP 协议传输的数据进行加密。那如何将站点变成安全的 HTTPS 站点呢?我们需要了解 SSL(Secure Socket Layer)协议。
  • 而现在很多时候我们使用的是 TLS(TransportLayer Security)传输层安全协议来实现的加密与解密。

1.jpg

# 1.3 TLS 如何实现加密

TLS/SSL 是如何实现 HTTP 明文消息被加密的,TLS/SSL 工作在 OSI 七层模型中,应用层与传输层之间。

  • 1. 提供数据安全:保证数据不会被泄露。

  • 2. 提供数据的完整性:保证数据在传输过程中不会被篡改。

  • 3. 对应用层交给传输层的数据进行加密与解密。

2.jpg

# 2.HTTPS 实现原理

# 2.1 加密模型 - 对称加密

对称加密:两个想通讯的人持有相同的秘钥,进行加密与解密。如下:

  • bob 将原始文档通过秘钥加密生成一个密文文档。
  • alice 拿到这个密文文档以后,它可以用这把秘钥还原为原始的明文文档。

3.jpg

  • 对称加密究竟是如何实现的,我们可以以 RC4 这样一个对称加密序列算法来看一下。
  • 加密:秘钥序列 + 明文 = 密文
  • 解密:秘钥序列 + 密文 = 明文

4.jpg

# 2.2 加密模型 - 非对称加密

非对称加密:它根据一个数学原理,创建一对秘钥(公钥和私钥)公钥加密,私钥解密;

  • 私钥:私钥自己使用,不对外开放。
  • 公钥:公钥给大家使用,对外开放。

比如:alice 有一对公钥和私钥,他可以将公钥发布给任何人。假设 Bob 是其中一个,当 Bob 要传递一份加密文档给 alice,那么 Bob 就可以用 alice 的公钥进行加密,alice 收到密文文档后通过自己的私钥进行解密,获取原始文档。

5.jpg

注意:alice 必须知道 Bob 就是 Bob,也就是它收到的信息必须是 Bob 发来的,那么这个信任问题,在多方通讯的过程中,必须有一个公信机构来验证双方的身份,那么这个机构就是 CA 机构。

# 2.3 身份验证机构 - CA

通讯双方是如何验证双方的身份?

CA 架构是可信任组织架构,主要用来颁发证书及验证证书。那 CA 机构又是如何申请和颁发证书的呢?

6.jpg

我们首先需要申请证书,需要进行登记,登记我是谁,我是什么组织,我想做什么,到了登记机构在通过 CSR 发给 CA,CA 中心通过后,CA 中心会生成一对公钥和私钥,那么公钥会在 CA 证书链中保存,公钥和私钥证书订阅人拿到后,会将其部署在 WEB 服务器上

1. 当浏览器访问我们的 https 站点时,它会去请求我们的证书

2.Nginx 会将我们的公钥证书回传给浏览器。

3. 浏览器会去验证我们的证书是否是合法的、是否是有效的。

4.CA 机构会将过期的证书放置在 CRL 服务器,那么 CRL 服务的验证效率是非常差的,所以 CA 又推出了 OCSP 响应程序,OCSP 响应程序可以查询指定的一个证书是否过期,所以浏览器可以直接查询 OCSP 响应程序,但 OCSP 响应程序性能还不是很高。

5.Nginx 会有一个 OCSP 的开关,当我们开启后,Nginx 会主动上 OCSP 上查询,这样大量的客户端直接从 Nginx 获取,证书是否有效。

# 2.4 HTTPS 通讯原理

7.jpg

HTTPS 加密过程,HTTPS 采用混合加密算法,即对称加密、和非对称加密

通信前准备工作:申请域名对应的证书,并将其部署在 Nginx 服务器中。

  • 第一步客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件和客户端支持 TLS 协议版本等信息。
  • 服务端会向客户端发送 Server Hello 消息。返回自己的公钥证书、挑选一个合适的加密套件、另外还会生成一份随机数 Random2 推送给客户端。至此客户端和服务端都拥有了两个随机数(Random1+ Random2)
  • 客户端收到服务端传来的公钥证书后,先从 CA 验证该证书的合法性(CA 公钥去解密公钥证书),验证通过后取出证书中的服务端公钥,再生成一个随机数 Random3,再用服务端公钥非对称加密 Random3。
  • 服务端用自己的私钥解出客户端生成的 Random3。至此,客户端和服务端都拥有 Random1 + Random2 +Random3,两边根据同样的算法生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密。

# 3.HTTPS 扩展知识

# 3.1 Https 证书类型

8.jpg

# 3.2 Https 颜色标识
  • Https 不支持续费,证书到期需重新申请新并进行替换。
  • Https 不支持三级域名解析,如 test.m.hmallleasing.com *.m.hmallleasing.com
  • Https 显示绿色,说明整个网站的 url 都是 https 的,并且都是安全的。
  • Https 显示黄色,说明网站代码中有部分 URL 地址是 http 不安全协议的。(https (http url) )
  • Https 显示红色,要么证书是假的,要么证书已经过期。

# 4.HTTPS 单台配置实践

# 4.1 创建 SSL 证书

1. 创建证书存储目录

[root@web01 ~]# mkdir -p /etc/nginx/ssl_key
[root@web01 ~]# cd /etc/nginx/ssl_key

2. 使用 openssl 命令充当 CA 权威机构创建证书

[root@web01 ssl_key]# openssl genrsa -idea -out server.key 2048
Generating RSA private key, 2048 bit long modulus
.+++
................+++
e is 65537 (0x10001)
#记住配置密码,我这里是 1234
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:

3. 生成自签证书,同时去掉私钥的密码

[root@web01 ssl_key]# openssl req -days 36500 -x509 \
-sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt
Country Name (2 letter code) [XX]:CN  #国家
State or Province Name (full name) []:WH  #省
Locality Name (eg, city) [Default City]:WH  #城市
Organization Name (eg, company) [DefaultCompany Ltd]:edu #公司
Organizational Unit Name (eg, section) []: xuyong #单位
Common Name (eg, your name or your servers hostname) []: s.hmallleasing.com #服务器主机名称
Email Address []:373370405@qq.com
# req --> 用于创建新的证书
# new --> 表示创建的是新证书
# x509 --> 表示定义证书的格式为标准格式
# key --> 表示调用的私钥文件信息
# out --> 表示输出证书文件信息
# days --> 表示证书的有效期
# 4.1 配置 SSL 场景
[root@web01 conf.d]# cat s.hmallleasing.com.conf 
server {
	listen 80;
	server_name s.hmallleasing.com;
	#rewrite ^(.*)$ https://$server_name$1 redirect;
	return 302 https://$server_name$request_uri;
}
server {
	listen 443 ssl;
	server_name url.hmallleasing.com;
    ssl_prefer_server_ciphers on;
    ssl_certificate ssl_key/hmallleasing.com.pem;
    ssl_certificate_key  ssl_key/hmallleasing.com.key;
	
	location / {
		index index.html;
		root /code;
	}
}
[root@web01 conf.d]# mkdir /etc/nginx/ssl_key
[root@web01 ssl_key]# ll
-rw-r--r-- 1 root root 1675 Sep  6 21:08 hmallleasing.com.key
-rw-r--r-- 1 root root 4784 Sep  6 21:08 hmallleasing.com.pem
[root@web01 conf.d]# nginx -t
[root@web01 conf.d]# systemctl reload nginx
[root@web02 conf.d]# echo "hello https" > /code/index.html
# 4.3 访问验证 SSL

1.jpg

# 5.HTTPS 集群配置实践

# 5.1 环境准备
主机名外网 IP (NAT)内网 IP (LAN)角色
lb01eth0:10.0.0.5eth1:172.16.1.5nginx-proxy
web01eth0:10.0.0.7eth1:172.16.1.7nginx-web01
web02eth0:10.0.0.8eth1:172.16.1.8nginx-web02
# 5.2 配置应用节点
# 配置所有后端节点,监听 80 端口即可;
[root@web01 conf.d]# cat s.hmallleasing.com.conf
server {
	listen 80;
	server_name s.hmallleasing.com;
	root /code/wordpress;
	
	location / {
		index index.html;
	}
}
[root@web01 ~]# nginx -t
[root@web01 ~]# systemctl reload nginx
[root@web01 ~]# echo "web01-https..." > /code/index.html
# 5.3 配置负载均衡
# 1.Nginx 负载均衡配置文件如下
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy.conf
upstream site {
	server 172.16.1.7:80 max_fails=2 fail_timeout=10s;
	server 172.16.1.8:80 max_fails=2 fail_timeout=10s;
}
# https 站点配置信息
server {
	listen 443 ssl;
	server_name s.hmallleasing.com;
	ssl_prefer_server_ciphers on;
    ssl_certificate ssl_key/hmallleasing.com.pem;
    ssl_certificate_key  ssl_key/hmallleasing.com.key;
	
	location / {
		proxy_pass http://site;
		include proxy_params;
	}
}
# 用户请求 http 协议,强制跳转至 https 协议
server {
	listen 80;
	server_name s.hmallleasing.com;
	return 302 https://$server_name$request_uri;
}
[root@lb01 ~]# cat /etc/nginx/proxy_params 
proxy_http_version 1.1;
proxy_set_header Connectin "";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 120;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
proxy_temp_file_write_size 10240k;
proxy_max_temp_file_size 10240k;
# 2. 重启 Nginx 负载均衡
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

# 6.HTTPS 场景配置实践

# 6.1 场景实践 - 1

模拟银行网站场景:

  • 1. 用户访问网站主站,使用 http 协议提供访问。
  • 2. 当用户点击登陆时,则网站会跳转至一个新的域名,并使用的是 Https 提供安全访问。
#1. 主页展示 http://yh.hmallleasing.com(提供网页浏览)
#2. 模拟登陆 http://yh.hmallleasing.com/login(相当于点击了登陆按钮)
#3. 登陆页面 https://star.hmallleasing.com (提供安全登陆)
#1. 配置 https://star.hmallleasing.com
[root@web01 ~]# cat /etc/nginx/conf.d/star.hmallleasing.com.conf
server {
	listen 443 ssl;
	server_name start.hmallleasing.com;
	ssl_prefer_server_ciphers on;
        ssl_certificate ssl_key/hmallleasing.com.pem;
        ssl_certificate_key  ssl_key/hmallleasing.com.key;
	root /code/login;
	
	location / {
		index index.html;
	}
}
[root@web01 ~]# mkdir /code/login
[root@web01 ~]# echo "start-login..." > /code/login/index.html
#2. 配置 http://yh.hmallleasing.com
[root@web02 conf.d]# cat /etc/nginx/conf.d/yh.hmallleasing.com.conf
server {
	listen 80;
	server_name yh.hmallleasing.com;
	root /code;
	
	location / {
		index index.html;
	}
	
	location /login {
		return 302 https://start.hmallleasign.com;
	}
}
[root@web02 conf.d]# echo "yh..." > /code/index.html 
[root@web02 conf.d]# nginx -t
[root@web02 conf.d]# systemctl reload nginx
# 6.2 场景实践 - 2

需求:希望用户访问网站的所有 Url 走 Https 协议,但访问 s.hmallleasing.com/abc 时走 Http 协议

[root@lb01 conf.d]# cat s.hmallleasing.com.conf 
upstream site {
	server 192.168.40.7:80 max_fails=2 fail_timeout=10s;
	server 192.168.40.8:80 max_fails=2 fail_timeout=10s;
}
# https 站点配置信息
server {
	listen 443 ssl;
	server_name s.hmallleasing.com;
	ssl_prefer_server_ciphers on;
        ssl_certificate ssl_key/hmallleasing.com.pem;
        ssl_certificate_key  ssl_key/hmallleasing.com.key;
	
	location / {
		proxy_pass http://site;
		include proxy_params;
	}
}
# 用户请求 http 协议,强制跳转至 https 协议
server {
	listen 80;
	server_name s.hmallleasing.com;
	if ($request_uri !~ "^/abc") {
		return 302 https://$server_name$request_uri;
	}
		
	location / {
		proxy_pass http://site;
		include proxy_params;
	}
}
[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# systemctl reload nginx
# 6.3 场景实践 - 3

开启 OCSP,加速验证证书是否有效;

# 准备 OCSP 证书:
# wget -O root.pem https://ssl-tools.net/certificates/dac9024f54d8f6df94935fb1732638ca6ad77c13.pem
# wget -O intermediate.pem https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem
# cat intermediate.pem > /etc/nginx/ssl_key/ocsp.pem
# cat root.pem >> /etc/nginx/ssl_key/ocsp.pem
# 配置 Nginx
[root@lb01 conf.d]# cat s.hmallleasing.com.conf 
upstream site {
	server 192.168.40.7:80 max_fails=2 fail_timeout=10s;
	server 192.168.40.8:80 max_fails=2 fail_timeout=10s;
}
# https 站点配置信息
server {
	listen 443 ssl;
	server_name s.hmallleasing.com;
	ssl_prefer_server_ciphers on;
        ssl_certificate ssl_key/hmallleasing.com.pem;
        ssl_certificate_key  ssl_key/hmallleasing.com.key;
	
	#开启 OCSP
	ssl_stapling on;
	ssl_stapling_verify on;
	ssl_trusted_certificate ssl_key/ocsp.pem;
	location / {
		proxy_pass http://site;
		include proxy_params;
	}
}
# 用户请求 http 协议,强制跳转至 https 协议
server {
	listen 80;
	server_name s.hmallleasing.com;
	return 302 https://$server_name$request_uri;
}
[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# systemctl reload nginx

验证是否开启 OCSP 响应程序

# 命令验证
[root@lb01 ~]# echo QUIT | openssl s_client -connect s.hmallleasing.com:443 -status 2>/dev/null | grep -A 17 "OCSP response"

# 7.HTTPS 优化配置实践

SSL 的运行计算需要消耗额外的 CPU 资源,SSL 通讯过程中『握手』阶段的运算最占用 CPU 资源,有如下几个方面可以进行调整与优化。

  • 1. 设置 worker 进程数设置为等于 CPU 处理器的核心数。worker_processes auto
  • 2. 启用 keepalive 长连接,一个连接发送更多个请求
  • 3. 启用 shared 会话缓存,所有 worker 工作进程之间共享的缓存,避免进行多次 SSL『握手』
  • 4. 禁用 builtin 内置于的缓存,仅能供一个 worker 工作进程使用,使用 shared 缓存即禁止 builtin
# 7.1 优化配置实例
worker_processes auto;
	
http {
	...
	server {
		listen 443 ssl;
		server_name www.example.com;
		
		ssl_prefer_server_ciphers on;
		ssl_certificate www.example.com.crt;
		ssl_certificate_key www.example.com.key;
		#Nginx 决定使用哪些协议与浏览器进行通讯
		ssl_protocols TLSv1.2;
		
		#设置长连接
		keepalive_timeout 70;
		
		#默认不开启 session_cache: a 握手后,关闭浏览器,再次访问,需要重新握手;
		#建立握手后如果连接断开,在 session_timeout 时间内再次连接,无需再次建立握手,可直接复用之间缓存的连接。
		#1M 缓存空间能存储 4000 个会话数量
		ssl_session_cache shared:SSL:10m;
		#配置会话超时时间 1 天 ( 默认 5 分钟 )
		ssl_session_timeout 1440m;
		
}
# 7.2 优化配置实例
[root@lb01 conf.d]# cat s.hmallleasing.com.conf 
upstream site {
	server 192.168.40.7:80 max_fails=2 fail_timeout=10s;
	server 192.168.40.8:80 max_fails=2 fail_timeout=10s;
}
# https 站点配置信息
server {
	listen 443 ssl;
	server_name s.hmallleasing.com;
	ssl_prefer_server_ciphers on;
	ssl_protocols TLSv1.2;
    ssl_certificate ssl_key/hmallleasing.com.pem;
    ssl_certificate_key  ssl_key/hmallleasing.com.key;
	
	ssl_session_cache shared:SSL:10m;
	ssl_session_timeout 1440m;
	location / {
		proxy_pass http://site;
		include proxy_params;
	}
}
# 用户请求 http 协议,强制跳转至 https 协议
server {
	listen 80;
	server_name s.hmallleasing.com;
	return 302 https://$server_name$request_uri;
}
此文章已被阅读次数:正在加载...更新于

请我喝[茶]~( ̄▽ ̄)~*

Xu Yong 微信支付

微信支付

Xu Yong 支付宝

支付宝