需求
内网部署safeline,通过frp让外网访问内部web网站服务,让safeline记录真实外网攻击IP
safeline 跟 frp都部署在同一台服务器:192.168.2.103
frp client 配置
frpc只需要在https上添加transport.proxyProtocolVersion = "v2"
即可,例如
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地址
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. 执行脚本进行批量修改
执行脚本,可传入参数true
或false
用法
代码语言:bash复制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复制bash config-proxy_protocol.sh true
2)批量取消proxy_protocol添加示例
代码语言:bash复制bash config-proxy_protocol.sh false
因为我们添加有白名单,而所有的防护站点都是监听同一个443端口,所以当有站点加白没有添加protocol
支持的时候,执行会打印如下告警
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. 测试
上面都配置好之后,访问配置好的域名,发现小地图已经正常显示归属地,配置成功