在网站上了CDN之后,提高站点访问的同时,也可以一定程度上防范攻击,保护了源站IP。毕竟如果攻击者拿到的是CDN节点的IP,一般情况下只能对CDN节点进行攻击,我们通过对CDN节点进行配置,配置WAF防火墙,进行流量清洗,攻击请求就不会到达源站服务器。但是如果攻击者知道了源站的IP地址,攻击者就可以直接将DDOS、CC攻击施加在源站IP上,站点很快就会崩溃。
上面讲的是一般情况,CDN能够一定程度保护你的源站IP。但是启用CDN一定能保护源站IP不被泄露吗?答案是否定的。Nginx服务器在直接以HTTPS访问IP地址时,如果没有为IP地址绑定专用的HTTPS证书,那么Nginx就会返回一张配置文件中已经存在的证书进行HTTPS通信。如果你的网站是example.com
,直接以HTTPS方式访问你的源站IP,Nginx就会返回example.com
的HTTPS证书。攻击者可以利用这一点,用肉鸡,扫描全网的IP地址,对全网IP尝试建立HTTPS连接。如果扫描到一个IP地址,返回了你网站的证书;同时这个IP不是CDN节点,那么这个IP所背后就是你的源站,你的源站就已经被暴露了。
那么我们能不能不让Nginx返回站点的HTTPS证书,而是返回一张其他的证书呢?答案当然是能,否则我也不会写下下面的文字咯~下面就简单介绍一下,如何使用自签名证书,放在服务器IP地址泄露。
为防止网络上的恶意扫描,例如通过访问 https://IP
获取 SSL 证书里的域名信息,以穷举匹配方式找出源站 IP。最好禁止 IP 访问 Web 服务器,并且设置一个自签证书避免泄露服务器上的网站域名。
大致设置流程:生成自签名 SSL 证书,修改 Web Server 配置文件限制以 IP 访问。
检查 OpenSSL 安装
# 若未返回结果则表示没安装 openssl version # CentOS & Fedora 安装 yum -y install openssl # Debian & Ubuntu 安装 apt -y install openssl
生成自签 SSL 证书
用下面命令生成自签名证书。它会先生成私钥文件,然后根据给定的信息生成证书并用私钥签名,这样一个自签名证书就生成完成了。解释下其中用到的三个参数(更多介绍请查阅 openssl-req 文档)。
-nodes
表示不设置私钥保护密码(设置会带来麻烦,例如启动或刷新 Nginx & Apache 服务时要求输入密码验证);-subj
设置 CSR 证书签名请求信息(这里只设置了 Common Name),为避免其它几个常见选项使用 OpenSSL 配置文件里缺省值(如果未设置的话),这里设置了空值,这将在生成证书时跳过。如果想在生成证书时询问输入,可以删除这个参数;-days
设置证书有效期,单位/天,这里设置了 10 年有效期;
openssl req -newkey rsa:2048 -nodes -keyout private_key.pem -x509 -subj "/C=/L=/O=/CN=127.0.0.1" -days 3650 -out certificate_crt.pem
将证书和私钥文件写入到相关目录存储,然后清除工作目录下文件。
cat private_key.pem > /etc/pki/tls/private/private_key.pem cat certificate_crt.pem > /etc/pki/tls/certs/certificate_crt.pem rm -f private_key.pem certificate_crt.pem
修改 Web Server 配置文件
以 Nginx 为例,修改 /etc/nginx/nginx.conf
配置文件里监听 80 和 443 端口的 server{...}
块,改为下面这样(对以 IP 访问关闭连接不响应,设置 SSL 证书。其中 default_server
参数别漏了,不然因为顺序问题可能加载其它 server{...}
里的证书)。
server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 444; } server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name _; return 444; ssl_certificate "/etc/pki/tls/certs/certificate_crt.pem"; ssl_certificate_key "/etc/pki/tls/private/private_key.pem"; }
之后用 nginx -t
命令测试下语法是否有问题,然后 nginx -s reload
生效,以后再用 https://IP
访问就不会泄露证书域名了。