解决SSL证书导致源站IP被泄露的问题
原文网址:解决SSL证书导致源站IP被泄露的问题_IT利刃出鞘的博客-CSDN博客
简介
本文介绍如何解决SSL证书导致源站IP被泄露的问题。
问题描述
众所周知,可以用CDN隐藏真实IP。但是,仍然可以通过域名查到IP!
原因是:SSL证书会泄露源站IP!具体原因是:有一类网站,比如:censys,它会扫描所有的ip+端口,当它用https+ip的方式访问时,会获取到这个服务器的SSL证书信息,而证书信息里就有域名!这时候,这些网站就会把这个域名和ip关联起来,这样就可以通过域名搜到源站ip了!如图:
复现SSL证书泄露IP
例如:我们以百度为例
先用ping命令找到baidu的某个ip:
然后这样访问:https://39.156.66.10/,结果如下
上边红框中可以直接显示域名!
也可以用curl测试:
防御方案
- 用源站的IP颁发一个SSL证书
- 可以是自签的证书(免费),也可以是正规可信机构颁发的(几千块一年)。
- 这样一来,通过https+ip的方式,获得到的证书是内容为ip的证书,没有域名信息了。
- 直接屏蔽censys扫描的IP段
- 不可靠,因为除了censys还有很多其他类似的网站
- 需要通过防火墙设置大量的黑白名单IP段,不利于维护和更新
- 源站仅使用IPv6。并且只允许CDN服务器访问源站,其他一律拒绝。
- IPv6拥有非常庞大的总量,Censys扫描起来时间很长,不容易被找到
- 需要通过防火墙设置黑白名单IP段,不利于维护和更新
如上三种方法,方案1是最好的,下边介绍具体方案。
自颁发SSL证书
用服务器的IP自己生成一个SSL证书。可以将证书时间设置的长一些,比如:十年。
方法见:SSL证书系列--手动生成自签名IP证书-CSDN博客
Nginx配置
在nginx.conf里的http{}里添加如下配置:
# ip证书server {# 所有IPV4的地址listen 80 default_server;listen 443 ssl default_server;# 所有IPV6的地址# listen [::]:9102;client_max_body_size 10m;charset utf-8;#填写证书文件名称ssl_certificate cert/self/test.crt;#填写证书私钥文件名称ssl_certificate_key cert/self/test.key;ssl_session_cache shared:SSL:1m;ssl_session_timeout 5m;#默认加密套件ssl_ciphers HIGH:!aNULL:!MD5;#自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)#TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差。#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;#ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;#表示优先使用服务端加密套件。默认开启ssl_prefer_server_ciphers on;location / {# 通过IP访问的,直接报错return 403;}}
上边的关键点如下:
1.默认服务器(即:没有匹配到域名的请求。也就是:ip直接请求)
listen 80 default_server;
listen 443 ssl default_server;
2.证书的位置
#填写证书文件名称
ssl_certificate cert/self/test.crt;
#填写证书私钥文件名称
ssl_certificate_key cert/self/test.key;
如上边所示,我是在nginx.conf文件的同级路径新建了个目录:cert/self,然后把上边生成的证书放进去了。
3.只允许CDN访问
这里我没有像其他人一样直接return 444,因为我是要用CDN的,CDN请求源站时是直接请求的IP。所以,我在自己的CDN服务器那里自己加了个header:key为custom_header,value为mycdn。其他过来的请求直接报错403。
# 如果不是来自CDN,则直接报错
if ($http_custom_header != "mycdn") {return 403;
}
现在,我们再用浏览器访问一下:(可见,看不到域名信息了)
再用curl看看:(可见:看不到域名信息)