445端口被封之后,在公网实现smb文件共享

背景

在最近项目中需要使用到windows smb文件共享,并且该项目过程不允许重启系统,其使用到的TCP连接端口为445,该项目测试环境一直处在内部网络,所以一开始没发现什么问题,项目进展到一定程度后,需要在公网环境中进行仿真测试,突然发现smb通道不能使用了,查了半天,发现是ISP把445端口给禁了,这让整个项目处于一个非常尴尬的处境,同时发现很多同行遇到了在原项目中使用了smb文件共享现在公网环境也无法正常工作,所以需要找到一个优雅的方法来完美解决这个问题。

找出SMB监听445的服务

按常理会把smb通道指定别的端口进行通信即可,可研究半天,发现net use使用smb时,无法指定传输端口,其原理是在windows开机启动时加载netbt驱动,smb服务使用默认端口445进行监听,而作为smb客户端也是用这个端口进行远端连接,google半天,是有那么一个注册表可以改这个初始化端口,应该在:

HKLM:\SYSTEM\CurrentControlSet\Services\NetBT

按正常思路,修改注册表,重启对应服务。那接下来使用netstat命令查看一下监听445端口的进程:
在这里插入图片描述
可以看出是pid为4的进程进行监听,从任务管理器上看是名叫System,备注"NT Kernel & System",这玩意儿要重启,岂不是直接告诉你系统重启,但是该项目最大的特点就是不允许重启系统,事情发展到这个形态,不由得让我们Linux开发出身的程序员对一个封闭系统的感叹,唏嘘。

端口代理

但问题总要解决,这个时候我想到了端口代理/端口转发,只要网络流量在公网上不使用445端口就可以,我就设计出了一个思路:
在这里插入图片描述
Windows smb客户端访问本地445:

net use \\127.0.0.1\C$
  • 1

1.客户端通过访问本地445,端口转发成访问远端,将访问本地445转发成访问远端8445端口,假设smb服务器IP为192.168.1.81:

netsh interface portproxy add v4tov4 listenport=445 connectaddress=192.168.1.81 connectport=8445
  • 1

2.服务端由访问8445,端口转发成访问本地445:

netsh interface portproxy add v4tov4 listenport=8445 connectaddress=192.168.1.81 connectport=445
  • 1

动手操作,按图描述的结构进行配置,服务端查看端口状态,可看到已有8445端口在监听
在这里插入图片描述
而客户端查看445端口状态,依然是pid为4的服务在监听,进行net use连接测试,连上的并不是远端的smb服务,而是本地smb服务。
经分析原理,配置端口代理后,被代理的端口会创建一个监听状态,可是本地已有smb服务监听了445端口,所以在客户端侧端口代理功能相当于失效。

再了解一下windows防火墙架构,如下是示意图:
在这里插入图片描述
前面所配置的端口代理应该属于Ipnat.sys模块,但是当我们在客户端在用户态使用net use连接127.0.0.1的smb的时候,在windows sockets driver(winsock.dll)时转到对应的本地smb应用服务,流量请求根本到不了Ipnat.sys模块,导致端口代理也就不会起作用。

端口拦截、端口代理

通过windows防火墙架构理清楚原因后,我们就想是否有别的办法在winsock.dll层面将流量报文拦截下来,然后转移到端口代理中去呢。
果不其然,google上找到了我们需要的驱动WinDivert:

windows 数据包转移 (WinDivert) 是一种用户模式的数据包捕获和转移包,WinDivert 允许用户模式应用程序捕获、修改、丢弃从 windows 网络堆栈发送的网络数据包。

基于这个工具,在github找到衍生开源项目divertTCPconn
这个项目利用WinDivert驱动可以把指定目的端口的流量转换成访问本地其它端口,这不就正是我们想要的东西,那问题基本解决了,跃跃欲试,重新整理架构图:
在这里插入图片描述
把WinDivert和DivertTCPconn结合编译、执行,将访问远端445端口的流量转换成访问本地8445,然后再写一条端口代理从本地8445代理到远端8445,对应命令如下:

端口拦截

divertTCPconn.exe 445 8445
  • 1

端口代理
假设远端smb服务器IP为192.168.1.81

netsh interface portproxy add v4tov4 listenport=8445 connectaddress=192.168.1.81 connectport=8445
  • 1

经过客户端smb连接

net use \\192.168.1.81\C$
  • 1

测试发现,流量并没有走8445端口,后面对divertTCPconn项目源码进行分析,发现在使用过滤器时,针对的是inbound&dst-port=445进行匹配。但对于我们这种情景来说,本地访问远端445是属于outbound&dst-port=445,赶紧把divertTCPconn代码修改:
在这里插入图片描述
经再次测试,在服务器之间走的是8445端口,而客户端和服务器内部也能够将445和8445进行转换,总结本案例是通过用户态端口拦截加端口重定向技术,最终达到我们想要的效果,并且在整个过程中,不用修改注册表,不用重启系统。

### Windows环境下使用FRP实现文件共享配置 #### 准备工作 为了使Windows上的SMB文件共享可以通过互联网访问,在家中网络不具备公网IP的情况下,可以利用阿里云或其他服务商提供的服务器作为中介来完成内网穿透的任务。由于445端口被大多数云服务提供商锁用于防止恶意攻击,因此需要调整策略以适应这一限制。 #### 服务器端(Frp Server, Frps)配置 在支持公网访问的Linux服务器上安装并启动`frps`服务。这一步骤通常涉及下载适合目标平台架构版本的FRP压缩包,并按照官方说明解压到指定位置[^2]。对于基于Ubuntu系统的服务器而言,操作命令如下所示: ```bash cd /usr/local wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_amd64.tar.gz tar -zxvf frp_0.51.3_linux_amd64.tar.gz mv frp_0.51.3_linux_amd64 frp rm frp_0.51.3_linux_amd64.tar.gz ``` 编辑位于`/usr/local/frp`目录下的`frps.ini`文件,定义监听端口号以及其他必要的参数设置,例如最大连接数、日志级别等。特别注意的是要开启HTTP或HTTPS代理模式以便处理来自客户端的数据转发请求。 #### 客户端(Frp Client, Frpc)配置 针对Windows操作系统,可以从GitHub页面获取适用于该平台的应用程序版本[^3]。将下载得到的ZIP档案解压至任意本地磁盘分区中,随后修改同级目录内的`frpc.ini`模板文档,指明远端服务器地址以及待暴露的服务详情——即欲开放给外部用户的SMB/CIFS协议对应的TCP端口80或其它自选数值而非受限于原生445端口[^1]。 具体来说,可以在`frpc.ini`中加入类似于下面的内容片段: ```ini [common] server_addr = x.x.x.x ; 替换成实际VPS IP server_port = 7000 ; 假设这是之前设定好的frps侦听端口 [smb_share] type = tcp local_ip = 192.168.1.100 ; Win机器局域网IP local_port = 445 ; SMB默认端口 remote_port = 6000 ; 自定对外提供服务使用的端口 ``` 保存更改后的配置之后,双击运行`frpc.exe`即可建立从家庭内部PC指向云端实例的安全隧道链路;与此同时,还需确保防火墙允许上述提及的新端口通信流量进出。 #### 测试验证 最后一步是在另一台具备公共网络接入能力的工作站尝试挂载远程驱动器资源。打开“此电脑”,点击左侧面板中的“映射网络驱动器”选项卡,输入形如`\tcp:<your_vps_public_ip>:<chosen_remote_port>`形式的目标UNC路径字符串,其中冒号分隔符前缀代表传输层协议类型而后面则是先前选定的公开接口编号[^5]。 成功完成后,应当能够在Explorer窗口浏览由私有LAN内计算机所提供的共享资料库项目列表了!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值