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

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.dtcms.com/a/346578.html

相关文章:

  • Vue3 学习教程,从入门到精通,基于 Vue 3 + Element Plus + ECharts + JavaScript的51购商城项目(45)
  • Intel RealSense D435 深度相机详解
  • 小程序备案话术
  • 文献阅读笔记【物理信息神经网络】:Physics-informed neural networks: A deep learning framework...
  • Kubernetes网络服务全解析
  • 【领码方案】PageData 完整解决方案 · 自引用树全链路提速(1.1版 集成层次树)
  • chapter05_从spring.xml读取Bean
  • 网络编程-基本概念及UDP
  • [Vid-LLM] 功能分类体系 | 视频如何被“观看“ | LLM的主要作用
  • 墨刀原型设计工具操作使用指南及实践操作
  • 微信小程序和uni-app面试问题总结
  • Mysql EXPLAIN详解:从底层原理到性能优化实战
  • 探索 List 的奥秘:自己动手写一个 STL List✨
  • 【Git】分支管理
  • Claude Code GitHub Actions配置(卡在第一部,验证Claude手机号过不了!!!)(跑不通!!!)
  • 服务器常见的漏洞扫描记录参考样例
  • CTFshow Pwn入门 - pwn 19
  • GitLab CI:Auto DevOps 全解析,告别繁琐配置,拥抱自动化未来
  • 网络模型深度解析:CNI、Pod通信与NetworkPolicy
  • Java高级语言特性,注解与反射
  • 肽类药物设计新突破:PepHAR 模型如何用「热点驱动」破解三大核心难题?
  • 百年传承祛湿,循汉方古脉,焕时代生机
  • 旅行足迹App技术架构全解析
  • 【React Native】自定义轮盘(大转盘)组件Wheel
  • Krea Video:Krea AI推出的AI视频生成工具
  • JAVA国际版东郊到家同城按摩服务美容美发私教到店服务系统源码支持Android+IOS+H5
  • 大白话聊一聊,数据结构的基石:数组和链表
  • 【Kubernetes知识点】Pod调度和ConfigMaps
  • Maven快速入门
  • 【python】get_dummies()用法