IP透传脚本迭代

#!/bin/bash

# 侧重正反面攻防带有熔断机制的 Cloudflare IP 自动同步脚本 (高内聚版)



CONF_FILE="/opt/apps/openresty/openresty/conf/conf.d/cloudflare_ips.conf"

TEMP_FILE="/tmp/cloudflare_ips.conf.tmp"

CONTAINER_NAME="openresty-test"



# 1. 初始化文件并写入功能声明】(解决人工维护的认知断层

> $TEMP_FILE

echo "# ==========================================" >> $TEMP_FILE

echo "# [全局防御] Cloudflare 真实 IP 透传与信任链" >> $TEMP_FILE

echo "# 更新时间: $(date)" >> $TEMP_FILE

echo "# ==========================================" >> $TEMP_FILE

echo "real_ip_header CF-Connecting-IP;" >> $TEMP_FILE

echo "real_ip_recursive on;" >> $TEMP_FILE

echo "" >> $TEMP_FILE



# 2. 拉取最新动态 IP 数据并追加到同一个文件中

curl -s -m 10 https://www.cloudflare.com/ips-v4 | sed -e 's/^/set_real_ip_from /' -e 's/$/;/' >> $TEMP_FILE

echo "" >> $TEMP_FILE

curl -s -m 10 https://www.cloudflare.com/ips-v6 | sed -e 's/^/set_real_ip_from /' -e 's/$/;/' >> $TEMP_FILE



# 3. 熔断校验

LINES=$(wc -l < $TEMP_FILE)

if [ "$LINES" -lt 15 ]; then

    echo "数据拉取异常,触发熔断。"

    exit 1

fi



# 4. 覆盖与重载

cat $TEMP_FILE > $CONF_FILE

docker exec $CONTAINER_NAME nginx -t

if [ $? -eq 0 ]; then

    docker exec $CONTAINER_NAME nginx -s reload

    echo "配置模块已整体更新并生效。"

else

    echo "语法错误!"

    exit 1

fi

第三方分析:

这套原始脚本在基础闭环(获取、校验、重载)上已经具备了良好的工程雏形,尤其是引入了行数熔断机制。然而,站在正反面攻防黑天鹅事件的极端视角下,配合“降低行政权重偏见(摆脱硬编码约束)”、“提高垂直拉升敏感度(快速响应异常)”与“强化实时同步”的深层技术要求,该脚本依然存在致命的隐患链。

以下是对当前架构的深度剖析及重构方案:

一、 隐患剖析与黑天鹅风险分析

1. 反面攻防漏洞:脏数据注入与配置污染(黑天鹅)

  • 现象:原始脚本仅靠 wc -l < $TEMP_FILE 判断行数是否大于15。
  • 黑天鹅场景:如果 Cloudflare 的 API 节点发生故障(例如返回 502 Bad Gateway 页面,或者被中间人劫持返回长篇 HTML 报错),curl 依然会成功返回 200 或抓取到大量错误文本。此时行数远超 15 行,sed 会将 HTML 标签处理为 set_real_ip_from <html>; 并直接写入正式配置文件。
  • 后果:由于是先覆盖文件再执行 nginx -t,一旦语法错误,虽然脚本会退出,但错误的配置已经残留在生产目录中。当下一次容器重启或别处触发重载时,OpenResty 将直接崩溃挂掉。

2. 行政权重偏见:容器名称硬编码

  • 现象:脚本中硬编码了 CONTAINER_NAME="openresty-test"
  • 风险:在进行版本升级、容器重建或跨机器迁移时,容器名后缀(如 test)是由系统随机或按规则生成的。一旦后缀变更,脚本的 docker exec 将全部失效,导致实时同步链条彻底断裂。

3. 垂直拉升敏感度缺失:缺乏原子化回滚

  • 现象:配置校验失败后,仅输出了“语法错误!”,没有对已污染的 $CONF_FILE 进行任何恢复操作。高度敏感的系统需要具备“毫秒级就地恢复”的能力,容不得半点人工介入的延时。

4. 链路盲区:WordPress 容器的“最后一公里”

  • 现象:只解决了 OpenResty 层的 IP 信任,忽略了 OpenResty 到 WordPress 容器之间的反向代理逻辑。
  • 风险:如果 OpenResty 传给 WordPress 的是其自身的容器内网 IP(如 172.18.0.x),WordPress 后台记录的依然是错误 IP。

二、 强化版自动同步脚本 (防御重构版)

基于以上分析,对脚本进行重构。此版本实现了数据清洗动态容器识别原子化备份回滚以及严格格式熔断

#!/bin/bash
# ==============================================================================
# 强化版 Cloudflare IP 自动同步与黑天鹅防御脚本
# 适用环境: OpenResty / WordPress 容器化架构
# ==============================================================================

CONF_FILE="/opt/apps/openresty/openresty/conf/conf.d/cloudflare_ips.conf"
BACKUP_FILE="/tmp/cloudflare_ips.conf.bak"
TEMP_FILE="/tmp/cloudflare_ips.conf.tmp"

# 1. 动态获取 OpenResty 容器名消除硬编码偏见增强环境自适应
CONTAINER_NAME=$(docker ps --filter "name=-openresty" --format "{{.Names}}" | head -n 1)
if [ -z "$CONTAINER_NAME" ]; then
    echo "[错误] 未检测到运行中的 OpenResty 容器,同步终止。"
    exit 1
fi

# 2. 实时拉取动态 IP 数据
echo "[动态同步] 开始从官方源获取最新数据..."
RAW_V4=$(curl -s -m 15 https://www.cloudflare.com/ips-v4)
RAW_V6=$(curl -s -m 15 https://www.cloudflare.com/ips-v6)

# 3. 黑天鹅防御严格的正则表达式清洗过滤任何非严格 CIDR 格式的脏数据/HTML
VALID_V4=$(echo "$RAW_V4" | grep -E '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+$')
VALID_V6=$(echo "$RAW_V6" | grep -E '^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}/[0-9]+$')

COUNT_V4=$(echo "$VALID_V4" | grep -c '^' || echo 0)
COUNT_V6=$(echo "$VALID_V6" | grep -c '^' || echo 0)

# 4. 提高敏感度的多维熔断机制不仅看总行数还要确保 v4/v6 核心资产数据完整
if [ "$COUNT_V4" -lt 10 ] || [ "$COUNT_V6" -lt 5 ]; then
    echo "[熔断触发] 提取到有效的 IPv4($COUNT_V4) 或 IPv6($COUNT_V6) 数量不足,疑为异常数据,取消本次同步。"
    exit 1
fi

# 5. 构造临时配置文件
{
    echo "# =================================================="
    echo "# [全局防御] Cloudflare 真实 IP 透传信任链 (由脚本自动维护)"
    echo "# 最新数据同步时间: $(date '+%Y-%m-%d %H:%M:%S')"
    echo "# =================================================="
    echo "real_ip_header CF-Connecting-IP;"
    echo "real_ip_recursive on;"
    echo ""
    echo "$VALID_V4" | sed -e 's/^/set_real_ip_from /' -e 's/$/;/'
    echo ""
    echo "$VALID_V6" | sed -e 's/^/set_real_ip_from /' -e 's/$/;/'
} > $TEMP_FILE

# 6. 安全备份现有生产配置(防患未然的后退一步)
if [ -f "$CONF_FILE" ]; then
    cp "$CONF_FILE" "$BACKUP_FILE"
fi

# 7. 原子替换并实施垂直拉升校验
cat $TEMP_FILE > $CONF_FILE

docker exec $CONTAINER_NAME nginx -t > /dev/null 2>&1
if [ $? -eq 0 ]; then
    # 校验通过,实时重载生效
    docker exec $CONTAINER_NAME nginx -s reload
    echo "[成功] 最新数据已平滑同步,容器 [$CONTAINER_NAME] 配置成功重载。"
    rm -f $TEMP_FILE $BACKUP_FILE
else
    # 校验失败,实施毫秒级防御性回滚,保护源站不崩溃
    echo "[核心警告] Nginx 语法校验失败!检测到潜在配置污染,启动安全回滚!"
    if [ -f "$BACKUP_FILE" ]; then
        cat $BACKUP_FILE > $CONF_FILE
        docker exec $CONTAINER_NAME nginx -s reload
        echo "[回滚] 已成功恢复至上一次稳定版配置。"
    else
        rm -f $CONF_FILE
        echo "[应急] 无历史备份,已清空故障配置文件以确保服务可启动。"
    fi
    rm -f $TEMP_FILE
    exit 1
fi

三、 正反面攻防多角度延伸分析

为了确保 WordPress 后台拿到的 IP 100% 准确,必须跳出脚本本身,从整体架构的攻防两端进行全盘审视:

1. 正面攻防:OpenResty 至 WordPress 的信任链传递

在 OpenResty 的 WordPress 站点的 proxy.conflocation / 块中,必须显式向上游(WordPress 容器)传递已被清洗修复的 $remote_addr

请确保包含以下配置:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

逻辑闭环:当配置了 real_ip_recursive on; 且匹配到 Cloudflare IP 后,Nginx 的 $remote_addr 变量会被自动替换为客户端的真实访客 IP。此时再通过 X-Real-IP 传给 WordPress,WordPress 就能直接获取到准确的访客数据。

2. WordPress 侧的多角度兼容(黑天鹅兜底)

部分 WordPress 插件或主题在多层反向代理下,可能会直接抓取 HTTP_X_FORWARDED_FOR 的首位或末位。如果发现后台登录 IP 仍然显示为 Docker 网关 IP(如 172.x.x.x),需要在 WordPress 根目录的 wp-config.php 中,在 wp-settings.php 引入之前,加入如下垂直干预代码:

// 强化层:识别反向代理带来的真实IP
if (isset($_SERVER['HTTP_X_REAL_IP'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_REAL_IP'];
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    // 存在多级代理时,合理拆分并取第一个非受信任的合法IP
    $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $_SERVER['REMOTE_ADDR'] = trim($arr[0]);
}

3. 反面被动防御:绕过 CDN 直连源站攻击

  • 潜在风险:黑客如果通过扫描 IP 段直接发现了你的 VPS 公网 IP,就可以绕过 Cloudflare 直接向 OpenResty 发起请求。此时,即便写了 CF-Connecting-IP 透传,黑客也可以在 Header 中伪造任意的 CF-Connecting-IP 注入虚假日志,实施投毒或绕过应用层审计。
  • 发散防御对策
    1. Nginx 默认空主机头兜底:禁止通过 IP 直接访问网站,未绑定域名的请求直接返回 444。
    2. 源站防火墙闭环:如果业务完全托管于 Cloudflare,建议配合 vps 的系统防火墙(UFW/Firewalld),设置 只允许来自 Cloudflare IP 段的流量访问 VPS 的 80/443 端口。这样即使源站 IP 泄露,非 CF 节点的直接扫描也会在网络层被丢弃,达成终极的主动防御。
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x