2111 字
11 分钟
接入 Cloudflare CDN 网络后如何防止源站IP泄露
源站IP泄露的成因与防护指南
在现代互联网环境中,保护源站IP的隐私至关重要。以下将详细说明源站IP泄露的原理、常见成因以及防护措施,并提供清晰的操作方法,帮助您有效保护您的源站。
源站IP是如何被发现的?
HTTP/HTTPS 请求的底层通讯原理 当我们在浏览器中输入一个域名并发起访问请求时,浏览器通过以下步骤完成与目标网站的交互:
- DNS解析:域名解析服务会将域名转换为IP地址。
- TCP通信:通过IP地址和端口号(HTTP 默认端口为 80,HTTPS 默认端口为 443),封装为符合 HTTP/HTTPS 协议的数据包。
- 目标主机请求:通过
Host
头字段向服务器发送请求。
工具演示: 使用
curl
查看 HTTP 请求过程:curl -svo /dev/null http://104.20.20.20 -H "host:www.example.com"
指定 HTTPS 请求过程:
curl --resolve "www.example.com:443:104.20.20.20" -svo /dev/null https://www.example.com/
IPv4 网络扫描 IPv4 地址空间有限,总计约 42.9 亿个地址(2^32 = 4,294,967,296)。现代基础设施可以轻松扫描整个 IPv4 网络:
- 利用带宽充足的服务器,通过工具(如 Nmap)扫描全网。
- 扫描常见端口(如 HTTPS 的 443),提取 SSL/TLS 证书中的域名信息。
SSL/TLS 证书中的域名信息 网站部署 HTTPS 必须配置 SSL 证书,证书中通常包含域名等详细信息。扫描全网的 HTTPS 端口并读取证书内容,便可能发现源站IP。
在线服务的利用 多个互联网测绘服务(如 Censys、Shodan、Fofa)会实时扫描 IPv4 网络并记录特征信息。您可以通过查询这些平台快速找到目标域名对应的源站IP:
- 查找 IPv4 全网域名匹配:
https://censys.io/ipv4?q=www.example.com
- 查找 SSL 证书中包含的域名:
https://censys.io/certificates?q=www.example.com
- 查找 IPv4 全网域名匹配:
如何防止源站IP被扫描发现?
- 限制入站访问 通过配置防火墙,仅允许可信来源(如 CDN IP 段)访问源站的 HTTP 和 HTTPS 端口。
示例脚本:
以下示例以 Cloudflare CDN 为例,使用 iptables
配置防火墙规则:
NOTE脚本会根据系统,自动部署持久化包,确保重启服务器也不会导致规则失效
#!/bin/bash
# 设置严格模式
set -euo pipefail
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 检查root权限
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}此脚本必须以root权限运行${NC}"
exit 1
fi
# 检查系统类型
check_system() {
if [ -f /etc/debian_version ]; then
if [ -f /etc/lsb-release ]; then
echo -e "${GREEN}检测到 Ubuntu 系统${NC}"
SYSTEM="ubuntu"
else
echo -e "${GREEN}检测到 Debian 系统${NC}"
SYSTEM="debian"
fi
elif [ -f /etc/redhat-release ]; then
echo -e "${GREEN}检测到 RHEL/CentOS 系统${NC}"
SYSTEM="rhel"
elif [ -f /etc/arch-release ]; then
echo -e "${GREEN}检测到 Arch Linux 系统${NC}"
SYSTEM="arch"
elif [ -f /etc/fedora-release ]; then
echo -e "${GREEN}检测到 Fedora 系统${NC}"
SYSTEM="fedora"
else
echo -e "${YELLOW}未能精确识别系统类型,将使用通用配置${NC}"
SYSTEM="generic"
fi
}
# 检查并安装必要工具
check_requirements() {
local missing_tools=()
# 检查基本工具
for tool in curl iptables ip6tables; do
if ! command -v $tool >/dev/null 2>&1; then
missing_tools+=($tool)
fi
done
# 根据不同系统安装缺失工具和持久化包
case $SYSTEM in
"debian"|"ubuntu")
apt-get update >/dev/null 2>&1
if [ ${#missing_tools[@]} -ne 0 ]; then
apt-get install -y ${missing_tools[*]}
fi
# 安装持久化包
if ! dpkg -l | grep -q "iptables-persistent"; then
echo -e "${YELLOW}正在安装 iptables-persistent...${NC}"
DEBIAN_FRONTEND=noninteractive apt-get install -y iptables-persistent
fi
;;
"rhel"|"fedora")
if [ ${#missing_tools[@]} -ne 0 ]; then
yum -y install ${missing_tools[*]}
fi
# 安装持久化包
if ! rpm -q iptables-services >/dev/null 2>&1; then
echo -e "${YELLOW}正在安装 iptables-services...${NC}"
yum -y install iptables-services
systemctl enable iptables ip6tables
systemctl start iptables ip6tables
fi
;;
"arch")
if [ ${#missing_tools[@]} -ne 0 ]; then
pacman -Sy --noconfirm ${missing_tools[*]}
fi
if ! pacman -Qs iptables >/dev/null 2>&1; then
echo -e "${YELLOW}正在安装 iptables...${NC}"
pacman -Sy --noconfirm iptables
fi
;;
esac
}
# 下载Cloudflare IP列表
download_cf_ips() {
local type=$1
local tmp_file=""
if [ "$type" = "v4" ]; then
tmp_file="/tmp/cf_ipv4.txt"
echo -e "${YELLOW}正在下载 Cloudflare IPv4 列表...${NC}"
curl -s https://www.cloudflare.com/ips-v4 -o "$tmp_file"
else
tmp_file="/tmp/cf_ipv6.txt"
echo -e "${YELLOW}正在下载 Cloudflare IPv6 列表...${NC}"
curl -s https://www.cloudflare.com/ips-v6 -o "$tmp_file"
fi
if [ ! -s "$tmp_file" ]; then
echo -e "${RED}下载的 IP 列表为空${NC}"
exit 1
fi
}
# 配置防火墙规则
configure_firewall() {
echo -e "${YELLOW}正在配置防火墙规则...${NC}"
# 备份当前规则
mkdir -p /etc/iptables/backup
iptables-save > /etc/iptables/backup/rules.v4.$(date +%Y%m%d_%H%M%S)
ip6tables-save > /etc/iptables/backup/rules.v6.$(date +%Y%m%d_%H%M%S)
# 配置IPv4规则
echo -e "${YELLOW}配置 IPv4 规则...${NC}"
# 清除现有规则
iptables -F
iptables -X
iptables -Z
# 设置默认策略
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
# 允许已建立的连接和本地连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
# 允许SSH(防止锁定)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许Cloudflare IP
while IFS= read -r ip; do
[[ -n "$ip" ]] && iptables -A INPUT -s "$ip" -p tcp -m multiport --dports 80,443 -j ACCEPT
done < /tmp/cf_ipv4.txt
# 阻止其他HTTP/HTTPS访问
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j DROP
# 配置IPv6规则
echo -e "${YELLOW}配置 IPv6 规则...${NC}"
# 清除现有规则
ip6tables -F
ip6tables -X
ip6tables -Z
# 设置默认策略
ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT
# 允许已建立的连接和本地连接
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -i lo -j ACCEPT
# 允许SSH(防止锁定)
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许Cloudflare IPv6
while IFS= read -r ip; do
[[ -n "$ip" ]] && ip6tables -A INPUT -s "$ip" -p tcp -m multiport --dports 80,443 -j ACCEPT
done < /tmp/cf_ipv6.txt
# 阻止其他HTTP/HTTPS访问
ip6tables -A INPUT -p tcp -m multiport --dports 80,443 -j DROP
}
# 确保规则持久化
ensure_persistence() {
echo -e "${YELLOW}正在确保规则持久化...${NC}"
case $SYSTEM in
"debian")
# Debian 使用 netfilter-persistent
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# 启用 netfilter-persistent 服务
systemctl enable netfilter-persistent
systemctl restart netfilter-persistent
;;
"ubuntu")
# Ubuntu 使用 iptables-persistent
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# 启用 iptables-persistent 服务
systemctl enable iptables-persistent
systemctl restart iptables-persistent
;;
"rhel"|"fedora")
# RHEL/CentOS 使用 iptables-services
service iptables save
service ip6tables save
systemctl enable iptables
systemctl enable ip6tables
systemctl restart iptables
systemctl restart ip6tables
;;
*)
# 通用系统采用启动脚本方案
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# 创建通用启动脚本
mkdir -p /etc/network/if-pre-up.d/
cat > /etc/network/if-pre-up.d/iptables << 'EOF'
#!/bin/sh
/sbin/iptables-restore < /etc/iptables/rules.v4
/sbin/ip6tables-restore < /etc/iptables/rules.v6
EOF
chmod +x /etc/network/if-pre-up.d/iptables
;;
esac
# 添加双重保险(对所有系统)
mkdir -p /etc/network/if-pre-up.d/
cat > /etc/network/if-pre-up.d/iptables << 'EOF'
#!/bin/sh
if [ -f /etc/iptables/rules.v4 ]; then
/sbin/iptables-restore < /etc/iptables/rules.v4
fi
if [ -f /etc/iptables/rules.v6 ]; then
/sbin/ip6tables-restore < /etc/iptables/rules.v6
fi
EOF
chmod +x /etc/network/if-pre-up.d/iptables
}
# 验证规则
verify_rules() {
echo -e "${YELLOW}验证防火墙规则配置...${NC}"
case $SYSTEM in
"debian")
if systemctl is-active netfilter-persistent >/dev/null 2>&1; then
echo -e "${GREEN}netfilter-persistent 服务运行中${NC}"
else
echo -e "${RED}netfilter-persistent 服务未运行${NC}"
return 1
fi
;;
"ubuntu")
if systemctl is-active iptables-persistent >/dev/null 2>&1; then
echo -e "${GREEN}iptables-persistent 服务运行中${NC}"
else
echo -e "${RED}iptables-persistent 服务未运行${NC}"
return 1
fi
;;
"rhel"|"fedora")
if systemctl is-active iptables >/dev/null 2>&1; then
echo -e "${GREEN}iptables 服务运行中${NC}"
else
echo -e "${RED}iptables 服务未运行${NC}"
return 1
fi
;;
esac
# 检查规则文件
if [ -f /etc/iptables/rules.v4 ] && [ -f /etc/iptables/rules.v6 ]; then
echo -e "${GREEN}规则文件已保存${NC}"
# 显示当前规则
echo -e "${GREEN}当前IPv4规则:${NC}"
iptables -L INPUT -n -v | grep -E "80|443"
echo -e "${GREEN}当前IPv6规则:${NC}"
ip6tables -L INPUT -n -v | grep -E "80|443"
else
echo -e "${RED}规则文件未找到${NC}"
return 1
fi
}
# 清理临时文件
cleanup() {
rm -f /tmp/cf_ipv4.txt /tmp/cf_ipv6.txt
}
# 主函数
main() {
echo -e "${GREEN}开始配置 Cloudflare IP 防护...${NC}"
check_system
check_requirements
# 下载IP列表
download_cf_ips "v4"
download_cf_ips "v6"
# 配置防火墙
configure_firewall
# 确保持久化
ensure_persistence
# 验证配置
verify_rules
# 清理
cleanup
echo -e "${GREEN}Cloudflare IP 防护配置完成!${NC}"
echo -e "${YELLOW}规则备份保存在 /etc/iptables/backup/ 目录下${NC}"
echo -e "${GREEN}请重启系统以验证规则是否正确持久化${NC}"
}
main
exit 0
验证配置是否生效:
- 检查当前规则:
iptables -L INPUT -v -n --line-numbers ip6tables -L INPUT -v -n --line-numbers
- 测试访问:
curl -svo /dev/null http://源站IP -H "host:域名"
防止出站请求泄露 出站请求可能暴露源站IP,例如:
- 自建邮件服务器的 MX 记录。
- 源站的跳转、错误配置的 SSL 证书。
- 网站中存在漏洞或后门被利用。
解决措施:
- 隔离服务:将对外的服务(如邮件)拆分到独立服务器。
- 限制出站端口:仅开放必要的出站端口。
- 及时修补漏洞:保持系统和程序的最新版本,避免使用弱密码。
清除历史 DNS 解析记录 某些服务商(如 SecurityTrails)会缓存域名的历史解析记录。这些记录可能暴露源站旧 IP。
解决措施:
- 更换源站服务器的IP。
- 确保新的 DNS 解析配置与源站解耦。
接入 Cloudflare CDN 网络后如何防止源站IP泄露
https://devniko.com/posts/shell-share-iptablescloudflareiponly/