当前位置: 首页 > ds >正文

frp+go-mmproxy 实现透明代理的内网穿透

frp+go-mmproxy 实现透明代理的内网穿透

事前声明:该方法只在 Linux 系统有效,并且需要 linux 内核 2.6.28 或更高版本

参考:

[Feature Request] Make client IP accessible to upstream by spoofing source IP · 议题 #4184 · fatedier/frp

mmproxy - Creative Linux routing to preserve client IP addresses in L7 proxies

frp 是一个常用的内网穿透软件,支持多种协议,可以让 NAT 环境下的服务暴露到公网指定端口,以穿透 sshd 为例,配置 frpc.toml:

[[proxies]]
name= "ssh"
type="tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 23456

然后用 frps 对应公网的 ip 和端口访问:在内网机的 var/log/auth.log 中查看登录记录:

Accepted publickey for fsj2009yx from 127.0.0.1 port 38866 ssh2:

可以看到经过 frpc 代理转发后,源客户端 IP 被隐藏了,变成配置中的 localIP 地址

在某些业务或服务中,我们需要获取到客户端的源 IP,例如

  • Web 服务限流:根据客户端真实 IP 做访问频率限制
  • SSH 安全审计:通过登录日志统计远程来源 IP,进行异常检测。
  • 防火墙规则:限制特定公网 IP 段才能访问服务。

如果源 IP 丢失,上述场景都会失效。

获取真实 ip

frp 提供了两种获取真实 ip 的方式:HTTP X-Forwarded-Forproxy protocol(参考 获取用户真实 IP | frp)

前者在 web 开发中很常见,即配置 nginx 的 X-Forwarded-For 选项,但只局限于 http/https 协议。

proxy protocol 支持任意 TCP/UDP 协议,但是需要上游应用服务支持解析该协议,部分软件并没有原生支持该协议的版本,典型例子是 sshd——它不支持 PROXY 协议,添加支持比较困难,导致某些需要真实 ip 的服务不能正常运行,例如 fail2ban

go-mmproxy

go-mmproxymmproxy 的 golang 实现版本, mmproxy是一个 PROXY 协议网关,底层依赖于 linux 的 TProxy(透明代理)技术

mmproxy 侦听来自应用程序级负载均衡器(如 Spectrum)的远程连接。然后,它读取 PROXY 协议标头,打开与目标应用程序的本地主机连接,并适当地代理数据进出。

关键在于,mmproxy 可以通过欺骗客户端 IP 地址的方式,访问上游应用程序,这样看上去就和直接连接到应用程序的真实连接没有区别

项目地址:path-network/go-mmproxy: Golang implementation of MMProxy

软件配置

环境要求(内网主机):

  • 需要 go sdk 版本 1.21 及以上(如果了解交叉编译可不配置)
  • linux 系统,内核版本 2.6.28 或更高
  • go-mmproxy 通过环回接口转发流量,因此它必须与 目标应用程序 在同一台机器上运行。

下载 go-mmproxy

执行命令:

go install github.com/path-network/go-mmproxy@latest

下载完成后,会把可执行文件 go-mmproxy 安装到 GOPATH/bin

如果你没有显式设置 GOPATH,默认是:

  • Linux/macOS$HOME/go/bin

配置 frpc

假设将端口 22222 的服务穿透到 frps 主机的 23456 端口上:

[[proxies]]
name= "ssh"
type="tcp"
localIP = "127.0.0.1"
localPort = 22222
remotePort = 23456transport.proxyProtocolVersion = "v2"

这里 proxy protocol 配置一定要带上,否则 go-mmproxy 无法解析到 Proxy 头

配置路由

rootsudo 权限下执行以下命令:

ip rule add from 127.0.0.1/8 iif lo table 123
ip route add local 0.0.0.0/0 dev lo table 123#ipv6 可选
ip -6 rule add from ::1/128 iif lo table 123
ip -6 route add local ::/0 dev lo table 123
  • 让本机回环接口发出的流量,根据表 123 决定路由

  • 匹配表 123 的流量都会直接回环,而不会被系统当作普通输出路由出去

运行 go-mmproxy

go-mmproxy 同级目录下创建文件 path-prefixes.txt

192.168.0.0/16
10.0.0.0/8
127.0.0.1/8

表示只有这些网段的 ip 才能使用 go-mmproxy 进行转发,避免被外部利用

然后执行命令运行 go-mmproxy:

sudo ./go-mmproxy  -l 0.0.0.0:22222  -4 127.0.0.1:22 -6 [::1]:22 -p tcp --allowed-subnets ./path-prefixes.txt

之后通过公网 ip+端口访问 ssh,访问成功

在内网主机的 var/log/auth.log 记录如下:

Accepted publickey for fsj2009yx from 117.150.164.176 port 45423 ssh2:

客户端源 ip 显示在日志文件上,证明透明代理实现成功

http://www.xdnf.cn/news/18782.html

相关文章:

  • Qt5 高级功能
  • 关于说明锂电池充电芯片实际应用
  • 曲面方程的三维可视化:从数学解析到Python实现
  • 从罗永浩访谈李想中学习现代家庭教育智慧
  • 定时器互补PWM输出和死区
  • 54.Redis持久化-AOF
  • JEI(Journal of Electronic lmaging)SCI四区期刊
  • 控制建模matlab练习16:线性状态反馈控制器-⑤轨迹追踪
  • Linux内核进程管理子系统有什么第三十三回 —— 进程主结构详解(29)
  • 【KO】前端面试四
  • Java八股文-java基础面试题
  • 9.Shell脚本修炼手册---数值计算实践
  • 使用tensorRT10部署yolov5目标检测模型(2)
  • UE5.3 中键盘按键和操作绑定
  • 青少年机器人技术(六级)等级考试试卷-实操题(2021年12月)
  • 深入理解3x3矩阵
  • 11.Shell脚本修炼手册---IF 条件语句的知识与实践
  • 【数据结构】布隆过滤器的概率模型详解及其 C 代码实现
  • mysql没有mvcc之前遇到了什么问题
  • 2025年AI Agent规模化落地:企业级市场年增超60%,重构商业作业流程新路径
  • Hive中的join优化
  • 基于SpringBoot的招聘系统源码
  • 解决Conda访问官方仓库失败:切换国内镜像源的详细教程
  • STAR-CCM+|K-epsilon湍流模型溯源
  • GEO优化供应商:AI搜索时代的“答案”构建与移山科技的引领,2025高性价比实战指南
  • 基于大模型的对话式推荐系统技术架构设计
  • Linux服务环境搭建指南
  • AI绘画落地难?我用Firefly+Marmoset,将2D概念图“反向工程”为3D游戏资产
  • Deep Unfolding Net(LR到HR)
  • Linux 进程间通信之System V 共享内存