双HTTPS反向代理模型研究
2021-05-07刘克礼
刘克礼
(安徽开放大学 信息与建筑工程学院,合肥 230022)
0 引 言
WEB应用是目前互联网非常重要的应用,包括电子公务,电子商务,购物支付,银行转账等日常事务都可以通过WEB实现。承载WEB应用的HTTP协议是明文协议,其中传输的信息都是明文,存在信息拦截、泄漏和篡改的风险。使用现代密码学技术对HTTP进行保护,可以有效避免上述风险[1]。HTTPS就是这样的产物,HTTPS是SSL+HTTP的简写,即使用SSL协议传输HTTP。目前互联网上采用HTTPS技术的网站越来越多,很多网站采用反向代理的方式实现HTTPS,为众多内部网站提供加密服务。主流的做法是客户端到反向代理的流量(前端流量)使用HTTPS加密,反向代理到真实服务器的流量(后端流量)还是使用HTTP,如图1。这里反向代理服务器可简称为前端,真实服务器可简称为后端。虽然客户端到反向代理的流量是加密的,但是反向代理到后端服务器的流量还是明文的。如果服务器内网有安全设备在拦截和分析流量,例如安全态势感知系统,或者配置错误,流量经过非授权设备,导致敏感信息暴露。
1 相关研究
使用反向代理对外发布WEB服务是一种流行的解决方案,可以实现集中管理,负载均衡,安全防护和节省资源等众多功能。在研究和实践中,使用最多的代理软件是Nginx。Nginx因其设计轻量,性能优异,单机能支持几十万连接,被广泛使用。Nginx支持HTTPS,通过加载网站的HTTPS证书,即可实现HTTPS访问。HTTPS证书可购买获取,也可免费获取。目前免费HTTPS证书用的比较多的是Let’s Encrypt颁发的证书。通过一个自动化脚本,即可实现Let’s Encrypt证书的申请和续签,十分方便。因此目前的HTTPS反向代理主流选择是使用Nginx+Let’s Encrypt搭建。[2]
图1 HTTPS反向代理模型
前后端之间流量加密技术,目前比较成熟的有MacSec(链路层),IPSec(网络层)和SSL/TLS(应用层)。
1.1 MacSec
MacSec是一个有线网安全标准,由IEEE于2006年制定,标准名称是802.1AE。[3]MacSec与无线网的加密功能相同,原理也相同。MacSec在两台直连的计算机之间或者直连的计算机和交换机的端口之间建立安全通道,实现通讯加密和校验,保护数据的机密性和完整性。MacSec可以使用预共享秘钥方式建立安全通道,也可以和802.1x协议协同工作,在认证通过后动态生成秘钥、安全分发秘钥和建立安全通道。MacSec工作在链路层,除了保护IP之外,还可以保护ARP、DHCP等协议。MacSec的优点是不影响上层应用就能提供安全特性,缺点是只能在局域网内提供安全,且标准较新,支持度和普及率不高。
1.2 IPSec
最初的TCP/IP协议不提供任何安全特性。针对不断增长的Internet安全需求,IETF于1998年11月颁发了IP层安全协议IPSec。它不是一个单独的协议,而是一组协议。IPsec是IP安全协议标准,是在IP层为IP业务提供保护的安全协议标准,其基本目的就是把安全机制引入IP协议。[4]IPSec在IPv6中必需支持,在IPv4中则是可选的。IPSec工作在网络层,只保护IP数据。IPSec有两种工作模式:传输模式和隧道模式。IPSec可实现3种应用场景的保护:站点到站点(Site-to-Site),端到端(End-to-End),端到站点(End-to-Site)。IPSec的优点是灵活,缺点是较复杂。
1.3 SSL/TLS
SSL (Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。[5]SSL与TLS在传输层与应用层之间对网络连接进行加密,属于应用层协议。SSL协议起源于1994年,当时网景公司推出首版网页浏览器及HTTPS协议,用于加密的就是SSL。此后相继推出SSL2.0及3.0版本,1999年IETF将SSL标准化,即 RFC 2246 ,并将其命名为TLS。2006年和2008年又分别推出TLS1.1和TLS1.2版本。在SSL/TLS发展过程中曾出现过各种安全漏洞,如Heartbleed、POODLE,这导致SSL3.0及其之前版本逐渐废弃,目前互联网使用的主流协议是TLS1.2版本。最新的TLS1.3协议针对安全强化及效率提升等方面进行了大量修改,在2018年8月份完成最终的标准化 (RFC 8446)。[6]随着HTTPS的大规模普及,TLS应用范围更加广泛、成熟,可以满足绝大部分的安全需求,其缺点是需要改造应用程序。
2 双HTTPS反向代理模型
浏览器访问HTTPS站点的一般流程如下:浏览器访问URL(含域名);浏览器解析域名,连接服务器,开始TLS握手;浏览器向服务器请求证书;浏览器验证证书;如果验证成功则认为证书有效,继续后面的流程,否则无效,断开连接。
标准的证书验证流程是:先验证根CA(Certificate Authority)证书,如果根CA有效,则按照证书链递进验证,直至网站证书。
为了保证HTTPS反向代理的兼容性,前端均采用标准CA证书,也就是经过浏览器认证的CA签发的证书。后端服务器都支持PKIX(Internet X.509 Public Key Infrastructure)证书,也不能更改。只能对证书验证方法进行修改。根据验证证书方法的不同,可有三种模式供选择:公有CA签发的证书,私有CA签发的证书[7]和基于DANE(DNS-Based Authentication of Named Entities)的自签名证书。[8]
2.1 公有CA
本模式后端流量使用标准的CA 证书进行流量加密。该模式可选的证书配置方式有很多。
(1)一个网站配置一个证书,前后端证书相同。这种方式需要申请足够的证书数量,而申请证书是有成本的,证书的更新也比较麻烦,前后端都要同步更新。由于证书必须在反向代理和后端服务器上都要配置,那么反向代理上会有大量的证书和私钥,如果反向代理被攻破,那么所有的私钥都会泄漏。
(2)一个网站配置一个证书,前后端证书和私钥不同。这种方式与(1)不同的地方是前端和后端的证书私钥不同,因此风险点稍小。缺点是证书数量翻倍。
(3)前后端都使用通配符证书,只需要一个证书,应用于一批网站。如果反向代理或者任一个后端服务器被攻破,那么唯一私钥也会泄漏。
(4)前端使用通配符证书,后端使用普通证书。这种方式的缺点也很明显。
基于标准CA的双HTTPS反向代理模型的四种证书配置对比如表1所示。
表1 基于标准CA的证书配置对比
表1中,证书的更新频率受CA控制,最新的政策是CA最多只能签发有效期为398天的证书。这表明证书更新频率基本上是一年一次。
目前,有很多公有CA,因此有很多受信任的根证书。每个CA可签发很多证书,包括多个中级证书和终端证书。从根证书到每个终端证书都形成一个完整的证书链。每个根证书的证书链形成一棵证书链树,如图2所示。因此公有CA是多信任链树体系。
图2 证书链树
公有CA的优点是兼容性非常好,使用SSL的软件都能很好地支持。理论上一个网站的证书可以由多个CA签发,也就是一个网站可以由多个合法的证书。当这种特点被滥用时,就会发生风险。例如网站虽然只申请了一个证书,但黑客可通过其他CA签发该网站的影子证书。那么当客户访问该网站时,黑客可以扮演中间人角色,将影子证书发给客户端。由于影子证书是合法证书,因此客户端不会有任何察觉,黑客从而可以解密客户端和服务器之前的通讯,也确实有这样的攻击发生过。公有CA的缺点是多个根证书导致的潜在中间人攻击风险。
2.2 私有CA
本模式后端流量使用私有CA签发的证书进行流量加密。由于是私有CA签发的证书,私有CA并不在受信任的CA列表里,SSL在验证证书时会出错。为了解决这个问题,将私有CA导入到前端的受信任CA列表。这种操作只需要在前端进行,影响面很小,也不会有兼容性问题。或单独配置私有CA为唯一受信任CA。有了私有CA,就可以根据需要签发自己的证书,可以增加有效期长度,降低更新工作量。证书即将失效时,重新签发新证书,并更新到后端服务器即可。本模式的缺点是要自主维护一个私有证书数据库,对管理人员要求较高。如果单独配置私有CA为唯一受信任CA,还可以避免公有CA的潜在中间人攻击问题。
2.3 DANE自签名
本模式后端流量使用自签名证书进行流量加密,反向代理使用DANE验证自签名证书。本模式要维护两个数据库:私有证书数据库和DNS数据库。本模式的优缺点同私有CA。此外还要对前端进行代码层面的改造和升级,以支持DANE。
DNS(域名管理系统)是互联网的基础,日常应用都离不开它。而DNS是明文的,不提供任何安全保证。DNSSEC使用现代密码学技术对DNS进行安全保护,可防止DNS篡改和伪造。[9]DNSSEC的工作原理如图3所示。每个区(Zone)都有两个非对称秘钥对,KSK(Key Signing Key)和ZSK(Zone Signing Key)。KSK要求高,难破解,是长期秘钥,ZSK要求低一些,是短期秘钥,可以滚动更新。KSK和ZSK的公钥以DNSKEY记录的方式保存在Zone中。KSK对ZSK的DNSKEY记录进行签名,ZSK则对整个Zone中的每条DNS记录(除ZSK的DNSKEY记录)进行签名,并生成对应的RRSIG(Resource Record Signature)记录。每个Zone都需要生成DS(Delegation Signer)记录,其中包括该Zone的KSK的摘要信息。DS记录会上传给上级Zone,使用上级的Zone的ZSK进行签名。这样就形成了根KSK->根ZSK->子DS->子KSK->子ZSK的完整签名和验证链条。根KSK的公钥可公开获取。任何人使用根KSK的公钥,即可验证一条DNS记录的RRSIG是否合法,从而得到对应的DNS记录是否合法。
图3 DNSSEC的工作原理
DANE是一种证书验证机制,基于DNSSEC提供安全保证。DANE具体是由TLSA域名记录提供验证信息。DANE提供了4种证书验证模式,其中类型为3的模式是基于域名的证书模式,可以使用自签名证书,然后由DANE提供安全保证。DANE验证证书的流程是:服务器返回自签名证书;客户端(浏览器或则前端)根据域名等信息从DNSSEC中获取证书验证信息;客户端根据证书验证信息和服务器的自签名证书进行比对。DANE(包括DNSSEC)的缺点是浏览器支持度欠缺,普及率尚待提高。但这不影响特定应用,例如在Web服务器中增加DANE支持。
自签名证书即将失效时,需要签发新的自签名证书。由于DNS的缓存特性,还不能将新证书立即更新到后端服务器上,否则可能会验证失败。需要先将新证书的验证信息更新到DNSSEC中。等到新的记录生效后,再将新证书更新到后端服务器上。最后再将旧的记录删除。
由于客户端需要先查询DNSSEC获取证书验证信息,才能继续验证流程,这增加了延时。为了解决这个问题,在客户端上配置后端服务器证书的域名信息,提前查询证书验证信息并缓存,甚至直接缓存验证结果信息,提高后端访问性能。
DNSSEC提供的服务是不可靠的。中间人无法篡改和伪造DNSSEC记录,但是可以丢弃记录,完成拒绝服务攻击。拒绝服务攻击造成解析无法完成,这会影响本模式的可靠性。
和公有CA不同,DANE是单信任链树模型,因此DANE不存在潜在中间人攻击问题。
DANE的验证信息和域名绑定,为了保证验证过程安全,TLSA域名需要单独配置,而不能通过嵌入证书的方式提供。RFC6698规定了默认域名生成规则是_端口._协议.原域名,例如访问https://www.example.com网站,那么TLSA域名就是_443._tcp.www.example.com.综合三种模式的优缺点,结果如表2所示。
表2 三种模式优缺点对比
3 系统实现
由于系统实现和系统架构、部署环境等有关,本研究前端采用linux+nginx,后端采用 windows+IIS的构架,证书管理工具使用openssl。
3.1 公有CA
按照各个CA提供商的要求申请和更新证书,证书文件及时更新到服务器上。nginx的主要配置如下:
proxy_pass https://10.1.11.39/;//指定后端
proxy_ssl_name test.example.cn;//指定域名
proxy_ssl_verify on;//必须验证证书
proxy_ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt;//公有CA的根证书列表
3.2 私有CA
采用二级证书链,先生成根证书的秘钥对,然后生成根CA自签名证书。将该证书导入系统信任CA列表,最后签发服务器证书。
建立私有CA具体步骤:
(1)生成私钥文件
openssl genrsa -out /cakey.pem 4096
(2)生成自签名证书
openssl req -new -x509 -key cakey.pem -out cacert.pem -days 3650
服务器申请证书步骤如下:
(1)生成私钥
openssl genrsa -out server.key 2048
(2)生成证书申请文件
openssl req -new -key server.key -out server.csr
(3)将申请文件发给CA,CA颁发证书
touch index.txt //这个文件会自动更新
echo 0F > serial //下一个要颁发的证书的编号
openssl ca -in server.csr -out server.crt //签发证书
(4)证书和私钥打包,发送客户端,在IIS中导入证书并使用
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx
(5)配置反向代理
proxy_pass https://10.1.11.39:444/;
proxy_ssl_name test2.example.com;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate cacert.pem;
3.3 DANE自签名
先生成服务器自签名证书,然后生成DANE验证信息并更新到DNSSEC,最后更新服务器。建立服务器自签名证书具体步骤:
(1)生成私钥文件
openssl genrsa -out server.pem 2048
(2)生成自签名证书
openssl req -new -x509 -key server.pem -out server.crt -days 3650
(3)证书和私钥打包,发送客户端,在IIS中导入证书并使用
openssl pkcs12 -export -in server.crt -inkey server.pem -out server.pfx
(4)生成证书摘要信息
openssl x509 -in server.crt -outform DER | shasum -a 256 | awk ’{print $1;}’
(5)添加TLSA记录
test3.example.com tlsa 3 0 1 摘要
(6)增加和配置nginx选项
proxy_ssl_verify on;//必须验证证书
proxy_use_dane_tlsa on;//启用dane
proxy_dane_tlsa_domain test3.example.com;//指定tlsa域名
(7)nginx中增加支持DANE的代码
openssl从1.1.0版本开始支持DANE证书验证功能,为此新增加了一批函数接口开放给上层应用。openssl子命令s_client也支持进行DANE验证,可以参考相关代码实现DANE验证。
ldns是github上的开源项目,是轻量的DNS函数库实现,能够执行DNSSEC相关查询。此外该项目的examples目录下的ldns-dane程序使用openssl也能进行DANE验证。也可以参考相关代码实现DANE验证。
使用nginx的模块开发技术,调研ldns的DNSSEC查询接口和openssl的DANE证书验证接口,在proxy模块中增加支持DANE的功能,具体代码略。
4 性能测试
为了对比后端采用HTTP和HTTPS三种模式的性能,搭建测试环境进行测试。前端配置是Intel(R) Xeon(TM) MP CPU 3.16GHz,内存8G,操作系统RHEL 6.2,nginx 1.18.0,openssl 1.1.1c。后端配置是
图4 测试网络拓扑
AMD 6376 4核,内存8G,Windows 2008 R2(sp1),IIS 7.5。测试拓扑如图4所示。
图4中,在后端服务器上搭建了三个站点,分别采用了不同的HTTPS部署模式。在各个站点下,建立大小依次为1KB,10KB,100KB,1MB,10MB的静态文件。使用AB(Apache Bench)工具进行下载测试,统计RPS(Requests per second)值。RPS表示服务器每秒能够处理的请求数,直接反应系统性能。使用的命令是 ab-c 100-n 1000 https://test.example.com/1k.html,结果如表3所示。
表3 四种后端部署模式压力测试
表3中显示,四种部署模式性能差距不明显,且后端采用HTTPS协议并不比HTTP协议更耗费资源。说明HTTPS的三种部署模式均能很好地满足加密和性能需求。
5 结束语
HTTPS+HTTP反向代理模型能够保护很多内网网站,提高访问网站的安全性能,该模型的后端流量仍然是明文,存在安全风险。本文设计双HTTPS反向代理模型,对前后端流量均进行加密。进一步提出了三种后端部署模式:标准CA,私有CA和DANE自签名,详细讨论了每种模式的工作原理和优缺点。在探讨了系统实现关键技术后,测试了几种部署模式的性能,结果表明几种后端部署模式的性能差别不明显,而采用HTTPS显然更能提高安全性,且部署模式灵活,能够满足绝大部分需求。