014.http与https

HTTPS安全证书概述

http使用明文传输信息,会遭到劫持和数据篡改,https避免了网站传输信息泄露,更加安全。实现https时需要了解ssl协议,但现在使用的更多的时TLS加密协议,在OSI七层模型中,应用层是http协议,表示层时ssl协议发挥作用的一层,它通过握手、交换秘钥、告警、加密等方式,使应用层http协议在没有感知的情况下做到了数据的安全加密

模拟DNS劫持

用户的正常访问站点流程应该是:客户端 -> DNS -> 服务器,如果此时DNS解析的IP地址被篡改,用户请求到的服务器IP是第三方地址,此时用户的访问请求会发送到假服务器,假服务器再向真实服务器请求数据,在将数据返回给用户前对数据进行篡改,例如插入广告。客户端 -> DNS -> 假服务器 -> 服务器,这个假服务器在整个请求过程中起到代理的作用

# 1.web01节点新建nginx配置文件

# 2.web01节点新建站点文件
[root@web01 ~]# vim /usr/local/nginx/html/jc.html
<h1>Title 1</h1>
<h2>Title 2</h2>
<h3>Title 3</h3>

# 3.lb01节点篡改数据
[root@lb01 ~]# vim /etc/nginx/conf.d/proxy_jc.example.com.conf
upstream jc.example.com {
	server 172.16.1.7:80;
}

server {
	...
	location / {
		sub_filter '<h3>' '<img src="图片链接" alt="">';
		proxy_pass http://jc.example.com;
		include proxy_params;
	}
}

这个实验过程中,手动修改/etc/hosts解析,就等同于模拟DNS返回的假IP

SSL安全原理

TLS/SSL发展

数据进行加密与解密的过程中,为了确定双方的身份,必须由一个权威机构来验证双方身份,这个权威机构就是CA

证书颁发流程

向CA申请证书需要在登记机构登记个人信息,通过CSR发给CA,CA中心通过后会生成一对公钥和私钥,这一对密钥会发送给证书订阅人(管理员)并部署在Web服务器上,其中CA会将生成的公钥保存在证书链中

  1. 浏览器访问Web服务器的https站点时,它会去请求证书
  2. Nginx将公钥证书发给浏览器
  3. 浏览器会通过CRL服务器、OCSP响应程序或其他方法去验证Web服务器的证书是否合法和有效

CA机构会将过期的证书存放在CRL服务器,CRL服务的验证效率是非常差的,所以CA又推出了OCSP响应程序,OCSP可以查询指定的一个证书是否过期,所以浏览器可以直接查询OCSP响应程序,但OCSP响应程序的性能仍不高。Nginx有一个OCSP的参数,开启该参数后Nginx会主动上OCSP查询,客户端可以直接从Nginx获取验证证书是否有效

CA证书分类

对比 域名型DV 企业型OV 增强型EV
地址栏 小锁标记+https 小锁标记+https 小锁标记+企业名称+https
一般用途 个人站点和应用;简单的https加密需求 电商站点和应用;中小企业站点 大型金融平台;大型企业和政府机构站点
审核内容 域名所有权验证 企业身份验证;域名所有权验证 最高等级的企业身份验证;域名所有权验证
颁发时间 10分钟~24小时 3~5个工作日 5~7个工作日
单次申请年限 1年 1~2年 1~2年
赔付保障金 / 125~175万美金 150~175万美金

https证书购买选择

  • 保护一个域名 www
  • 保护多个域名 www images cdn
  • 通配符域名 *.example.com

https注意事项

  • 证书不支持续费,到期需要重新申请并替换
  • 证书不支持多级子域名解析,如test.images.example.com
  • https显示小锁,表示整个网站的url都是https的链接
  • https显示感叹号,表示网站内容中包含部分http链接
  • https显示红色,表示证书有假或证书过期

补充:

银行或比较重要的政府部门的站点,其本身就是一个CA,用户访问这些站点的时候,浏览器会提示要下载它们的证书,或者在访问这些站点之前就必须先安装好对应的客户端、插件、证书之类的软件,如果不安装相应的软件,就无法访问站点

Nginx单节点https

生成证书

私有生成证书仅供实验学习使用,实际工作中会直接购买云服务商的证书,所以生成私有证书这个步骤不重要

  1. 环境

在使用https之前,nginx无论是通过yum或编译安装,必须加载ssl模块

[root@web03 ~]# nginx -V
[root@web03 ~]# mkdir -p /usr/local/nginx/ssl_key/	# 存放ssl证书的路径
  1. 使用openssl命令充当CA权威机构创建证书。生产环境不使用此方式生成证书,这种证书是不被互联网认可的黑户证书
[root@web03 ~]# openssl genrsa -idea -out server.key 2048
  1. 生成自签证书,同时去掉私钥密码
[root@web03 ~]# openssl req -days 36500 -x509 -sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt
	req:用于创建新证书
	newkey:表示创建的是新证书
	x509:表示定义证书的格式为标准格式
	keyout:表示调用私钥文件信息
	out:表示输出证书文件信息
	days:表示证书有效期,以天为单位
[root@web03 ~]# mv server.* /usr/local/nginx/ssl_key/

https配置

  1. 指令
# 1.启动ssl功能
Syntax: ssl on|off;
Default: ssl off;
Context: http, server

# 2.证书文件
Syntax: ssl_certificate file;
Default: -
Context: http, server

# 3.私钥文件
Syntax: ssl_certificate_key file;
Default: -
Context: http, server
  1. Nginx配置Https实例
[root@web03 ~]# vim /usr/local/nginx/conf.d/web03.example.com.conf
server {
	listen 443;
	server_name web03.example.com;
	root /usr/local/nginx/html/;
	ssl on;
	ssl_certificate ssl_key/server.crt;
	ssl_certificate_key ssl_key/server.key;

	location / {
		index index.html;
	}
}

server {
	listen 80;
	server_name web03.example.com;
	return 302 https://$server_name$request_uri;
}

全站https实现

全站https实现

负载节点与web节点一般都处于同一区域网络中,因此负载节点与web节点之间的通信不必要使用https协议,所有通过负载代理请求的数据,最终都会以https协议的形式从负载节点返回给客户端,所以从客户端的角度看来,整个站点都使用的https协议

  1. 环境准备
主机名 NAT LAN 角色
lb01 10.0.0.5 172.16.1.5 负载均衡
web01 10.0.0.7 172.16.1.7 web节点
web02 10.0.0.8 172.16.1.8 web节点
  1. web节点配置
# 1.web01新建http配置文件
[root@web01 ~]# vim /usr/local/nginx/conf.d/web.example.com.conf
server {
	listen 80;
	server_name web.example.com;
	charset utf-8,gbk;

	location / {
		root /usr/local/nginx/html/;
		index web01.html;
	}
}
[root@web01 ~]# echo "web01.example.com" > /usr/local/nginx/html/web01.html

# 2.web02新建http配置文件
[root@web02 ~]# vim /usr/local/nginx/conf.d/web.example.com.conf
server {
	listen 80;
	server_name web.example.com;
	charset utf-8,gbk;

	location / {
		root /usr/local/nginx/html/;
		index web02.html;
	}
}
[root@web02 ~]# echo "web02.example.com" > /usr/local/nginx/html/web02.html
  1. lb01配置https及代理
[root@lb01 ~]# vim /etc/nginx/conf.d/proxy_web.example.com.conf
upstream web.example.com {
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}

server {
	listen 443 ssl;
	ssl_certificate ssl_key/server.crt;
	ssl_certificate_key ssl_key/server.key;
	server_name web.example.com;
	charset utf-8,gbk;

	location / {
		proxy_pass http://web.example.com;
		include proxy_params;
	}
}
server {
	listen 80;
	server_name web.example.com;

	location / {
		rewrite (.*) https://$server_name$1 redirect;
		return 302 https://$server_name$http_request_uri;
	}
}

[root@lb01 ~]# scp -rp web03:/usr/local/nginx/ssl_key /etc/nginx/
[root@lb01 ~]# firewall-cmd --add-port=443/tcp --permanent
[root@lb01 ~]# firewall-cmd --reload

站点扩展示例

在上一示例中,负载节点与web节点之间使用http协议,这是建立在用户请求静态页面的前提下没有出现错误,但如果将静态页面换成动态资源,例如phpmyadmin站点,用户向负载节点请求的是https,而负载调度phpmyadmin又是http,这可能会导致无法正常登录站点或导致站点元素展示混乱

# 仍以前例为标准
[root@lb01 ~]# vim /etc/nginx/conf.d/proxy_web.example.com.conf
server {
        listen 443 ssl;
        server_name wordpress.example.com;
        ssl_certificate ssl_key/server.crt;
        ssl_certificate_key ssl_key/server.key;
        charset utf-8,gbk;

        location / {
                proxy_pass http://web.example.com;
                include proxy_params;
        }
}
server {
        listen 443 ssl;
        server_name phpmyadmin.example.com;
        ssl_certificate ssl_key/server.crt;
        ssl_certificate_key ssl_key/server.key;
        charset utf-8,gbk;

        location / {
                proxy_pass http://web.example.com;
                include proxy_params;
        }
}

此时访问wordpress会出现页面资源错乱的情况,这是由于php无法区分用户的请求到底是http还是https造成的,只需要在web节点的nginx配置文件中补充一个选项即可

location ~ \.php$ {
                fastcgi_index index.php;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param HTTPS on;		# 指定PHP使用https协议
                include fastcgi_params;
        }

wordpress的后台登录页面似乎无法自动跳转https,代理配置全站https后直接点击进入wordpress后台登录页面会提示404,手动补充https协议能够解决

补充:官方建议SSL性能优化参数

server {
listen 443 ssl http2; # 开启http2.0
ssl_session_cache shared:SSL:10m; # 建立完SSL握手后如果断开连接,在session_timeout时间内再次链接,无需再次下发SSL公钥,用1M的内存就可以缓存4000个连接
ssl_session_timeout 1440m; # SSL链接断开后的超时时间
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 # 使用的TLS协议版本
ssl_prefer_server_ciphers on; # Nginx决定使用哪些加密算法与浏览器进行通讯
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; # 配置加密套件
}

由于https本身在表示层也要建立SSL的握手、加密、比对等操作,对站点响应性能有较大影响,通过上述选项开启SSL缓存功能,能够提升用户端的链接速率和使用体验

四层+七层https示例

posted @ 2023-06-19 09:23  hebo  阅读(193)  评论(0)    收藏  举报