雷池+frp 批量设置proxy_protocol实现真实IP透传

需求

内网部署safeline,通过frp让外网访问内部web网站服务,让safeline记录真实外网攻击IP safeline 跟 frp都部署在同一台服务器:192.168.2.103

frp client 配置

frpc只需要在https上添加transport.proxyProtocolVersion = "v2"即可,例如

text 复制代码
root@safeline:~# cat /etc/frp/frpc.toml
[[proxies]]
name = "web1"
type = "https"
localIP = "192.168.2.103"
localPort = 443
subdomain = "web1"
transport.proxyProtocolVersion = "v2"

[[proxies]]
name = "web2"
type = "https"
localIP = "192.168.2.103"
localPort = 443
subdomain = "web2"
transport.proxyProtocolVersion = "v2"

保存并且重启frp服务

safeline配置

safeline不支持web界面添加proxy_protocol支持,无法正常搭配frp显示真实IP,需要直接修改配置文件

1. 修改proxy_params 配置文件

/data/safeline/resources/nginx/proxy_params配置文件不会随着safeline重启而重置,我们在这里给配置全局开启proxy_protocol

这里注意需要修改set_real_ip_from 服务器的 IP 地址;,改为自己frps服务器的ip地址

text 复制代码
root@safeline:/data/safeline/resources/nginx# cat /data/safeline/resources/nginx/proxy_params 
# 内网地址范围
set_real_ip_from 192.168.0.0/16;  # 覆盖 192.168.0.0 到 192.168.255.255
set_real_ip_from 172.16.0.0/12;   # 覆盖 172.16.0.0 到 172.31.255.255
set_real_ip_from 10.0.0.0/8;      # 覆盖 10.0.0.0 到 10.255.255.255

# 公网 frps 服务器的 IP 地址
set_real_ip_from 服务器的 IP 地址;

real_ip_header proxy_protocol;

# 其他代理设置
proxy_set_header X-Real-IP $realip_remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_headers_hash_max_size 1024;
proxy_headers_hash_bucket_size 128;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_hide_header X-Powered-By;

# 添加条件判断以兼容非 proxy_protocol 连接
set $proxy_x_forwarded_for $proxy_add_x_forwarded_for;
set $proxy_x_real_ip $remote_addr;

if ($proxy_protocol_addr) {
    set $proxy_x_forwarded_for "$proxy_protocol_addr, $proxy_x_forwarded_for";
    set $proxy_x_real_ip $proxy_protocol_addr;
}

proxy_set_header X-Forwarded-For $proxy_x_forwarded_for;
proxy_set_header X-Real-IP $proxy_x_real_ip;

2. 创建config-proxy_protocol.sh脚本

我们要给/data/safeline/resources/nginx/sites-enabled目录下所有的IF_backend文件,在监听部分上添加proxy_protocol支持,其中增加一个白名单域名,白名单中的域名不做任何更改,该脚本可实现批量添加或者移除所有proxy_protocol

我们把脚本放在/data/safeline/resources/nginx/sites-enabled目录下,即/data/safeline/resources/nginx/sites-enabled/config-proxy_protocol.sh

1)创建脚本

bash 复制代码
vim /data/safeline/resources/nginx/sites-enabled/config-proxy_protocol.sh

2) 脚本内容如下,请注意要修改成自己的主域名子域名

bash 复制代码
#!/bin/bash

# 主域名 ;改为自己的主域名,例如 ttxs.com
main_domain="ttxs.com"

# 白名单子域名列表,如:op1.ttxs.com、op2.ttxs.com
whitelist_subdomains=(
    "op1"
    "op2"
)

# 帮助函数
show_help() {
    echo "用法:$0 [true|false]"
    echo "  true  - 添加 proxy_protocol 支持"
    echo "  false - 移除 proxy_protocol 支持"
    echo "  ?     - 显示此帮助信息"
}

# 检查参数
case "$1" in
    true|false) action=$1 ;;
    ""|"?") show_help; exit 0 ;;
    *) echo "错误:参数必须是 true 或 false。"; exit 1 ;;
esac

# 修改配置函数
modify_config() {
    local file=$1
    local add_proxy=$2
    local changed=false

    while IFS= read -r line; do
        if [[ $line =~ listen.*:443 ]]; then
            if $add_proxy && [[ ! $line =~ proxy_protocol ]]; then
                line="${line/ssl http2;/ssl http2 proxy_protocol;}"
                changed=true
            elif ! $add_proxy && [[ $line =~ proxy_protocol ]]; then
                line="${line/ proxy_protocol/}"
                changed=true
            fi
        fi
        echo "$line"
    done < "$file" > "${file}.tmp"

    if $changed; then
        mv "${file}.tmp" "$file"
        if $add_proxy; then
            echo "已添加 proxy_protocol 支持: $file"
        else
            echo "已移除 proxy_protocol 支持: $file"
        fi
    else
        rm "${file}.tmp"
        if $add_proxy; then
            echo "已支持 proxy_protocol,无需修改: $file"
        else
            echo "无 proxy_protocol 支持,无需修改: $file"
        fi
    fi
}

# 主处理逻辑
for file in IF_backend_*; do
    [ -f "$file" ] || continue

    server_name=$(grep "server_name" "$file" | awk '{print $2}' | tr -d ';\n' | sed 's/on$//')
    subdomain=${server_name%%.*}
    
    if [[ " ${whitelist_subdomains[*]} " =~ " $subdomain " ]]; then
        echo "白名单域名,跳过修改: $file ($server_name)"
        continue
    fi
    
    case "$action" in
        true)  modify_config "$file" true ;;
        false) modify_config "$file" false ;;
        *)     modify_config "$file" true ;; # 默认添加支持
    esac
done

# 测试并重新加载 Nginx 配置
echo "测试 Nginx 配置..."
if docker exec safeline-tengine nginx -t; then
    echo "重新加载 Nginx 配置..."
    docker exec safeline-tengine nginx -s reload
    echo "操作完成"
else
    echo "Nginx 配置测试失败,未重新加载配置"
    exit 1
fi

3)给脚本添加执行权限

bash 复制代码
chmod +x /data/safeline/resources/nginx/sites-enabled/config-proxy_protocol.sh

3. 执行脚本进行批量修改

执行脚本,可传入参数truefalse 用法

text 复制代码
root@safeline:/data/safeline/resources/nginx/sites-enabled# bash config-proxy_protocol.sh 
用法:config-proxy_protocol.sh [true|false]
  true  - 添加 proxy_protocol 支持
  false - 移除 proxy_protocol 支持
  ?     - 显示此帮助信息

1)执行批量添加proxy_protocol示例

复制代码
bash config-proxy_protocol.sh true

2)批量取消proxy_protocol添加示例

复制代码
bash config-proxy_protocol.sh false

因为我们添加有白名单,而所有的防护站点都是监听同一个443端口,所以当有站点加白没有添加protocol支持的时候,执行会打印如下告警

text 复制代码
nginx: [warn] protocol options redefined for 0.0.0.0:443 in /etc/nginx/sites-enabled/IF_backend_3:13

含义是:"protocol options redefined" 表示在 Nginx 配置中,对于同一个监听地址和端口(在这个例子中是 0.0.0.0:443),协议选项被重复定义了。我们忽略这个报警即可。

当我们不做白名单,所有站点都添加proxy_protocol,那就不会打印这个告警了

如果重启服务器或者服务,IF_backend文件被重置,那么直接执行一下该脚本即可

4. 测试

上面都配置好之后,访问配置好的域名,发现小地图已经正常显示归属地,配置成功

---百川论坛转发,作者:つ微凉徒眸意浅挚半

相关推荐
见青..10 小时前
phpMyAdmin权限提升
web安全·网络安全·phpmyadmin
数据知道11 小时前
邮件安全实战:SPF/DKIM/DMARC 配置与钓鱼绕过
网络·安全·web安全·网络安全·邮件安全
世界尽头与你15 小时前
Android Root 检测原理
android·安全·网络安全·渗透测试
kp0000015 小时前
如何平衡模型输出的“有用性”和“安全性
人工智能·安全·网络安全·信息安全·ai安全
世界尽头与你17 小时前
iOS 越狱检测原理
安全·网络安全·ios·信息安全·渗透测试
kp000001 天前
大模型输出造成信息泄露类型
人工智能·网络安全·信息安全·ai安全
kp000001 天前
System Prompt Leakage(系统提示词泄露)及安全防御
网络·安全·网络安全·信息安全·prompt·ai安全
X7x51 天前
攻防对抗的结构化思维:深度拆解网络杀伤链(Kill Chain)与现代防御演进
网络安全·网络攻击模型·安全架构·网络杀伤链·kill chain
kp000001 天前
AI大模型,如何区分善意提问与Prompt注入攻击
人工智能·网络安全·信息安全·prompt·ai安全
kp000002 天前
AI系统输入安全基线
人工智能·安全·网络安全·信息安全·ai安全