【Java】Socket网络编程实现内网穿透、端口映射转发、内网穿透上网工具的编写,设置IP白名单防火墙

article/2025/11/4 15:59:15

这里写目录标题

  • 简介
    • 更新
  • 一、背景
    • 1.1 情景假设
    • 1.2 想要达到的目的
    • 1.3 局限
    • 1.3 解决方案一(路由器NAT)
    • 1.4 解决方案二(云服务器转发)
  • 二、方案介绍
    • 2.1 方案简介
    • 2.2 具体流程
    • 2.3 编程要点
    • 2.4 关于web管理IP白名单的更新
    • 2.5 关于socks5代理穿透内网上网功能的更新
  • 三、程序简介
    • 3.1 简介
    • 3.2 调试学习
  • 四、上线使用
    • 4.1 测试使用
    • 4.2 设置自启动服务
      • 4.2.1 服务端开机自启动
      • 4.2.2 客户端开机自启动
    • 4.3 IP白名单防火墙管理

简介

本篇博客将介绍内网穿透原理及方法,并将以代码的形式展现出来可靠且安全的内网穿透、端口映射转发工具
程序开源在我的GitHb仓库中,学习和使用了的麻烦给个Star啦,万分感谢

更新

  1. 更新了web管理,能够管理允许登录的IP,设置IP白名单防火墙
  2. 更新了代理上网功能,能够代理内网,例如实现在校外访问校园内网才能访问的网站

一、背景

1.1 情景假设

  1. 假如我在学校里有一台台式电脑A,这台台式电脑在实验室局域网内拥有一个局域网IP 192.168.0.A(为了方便我们这样描述IP)
  2. 我在家里有一台笔记本B,这台笔记本在家中局域网内拥有一个局域网IP192.168.0.B

1.2 想要达到的目的

  • 我在家里想使用笔记本B通过ssh登录到A电脑的22号端口进行shell相关操作

1.3 局限

  • 我们是没法直接访问到的,因为在当前网络环境下,我们使用的机子一般都不具备公网IP,这样我们在寻址时只靠对方的局域网IP是无法找到他的

1.3 解决方案一(路由器NAT)

  • 我们的A机器是处于实验室的局域网内,但如果我们有权限去控制上层的网关路由器,即这个上层的路由器具有一个公网IP,假设为123.123.123.123,那么我们可以在路由器中设置端口映射(NAT),例如将路由器的10022端口映射到局域网内A电脑的22号端口,这样我们在家中只要通过IP+端口123.123.123.123:10022就可以登录到实验室里台式机A的22号ssh服务端口了
  • 但很多时候我们并没有权限去控制这样一个网关路由,因为在现在的网络环境下,很有可能我们整个一层楼甚至一栋楼使用一个公网IP,每个实验室里又一个路由器,存在路由器多级嵌套的情况,网关路由的操作权限不会那么轻易获取,并且即使获取也将出现每一层路由器都需要配置端口映射而十分繁琐

1.4 解决方案二(云服务器转发)

  • 而换一种想法,如果我们拥有一台具有公网IP的云服务器,那么我们完全可以将云服务器作为一个中继,大家(A和B)都连接到这台具有公网IP的云服务器并保持连接,云服务器都记录好连接着的机器谁是谁,大家需要相互沟通时(B想连接A)就告诉云服务器我想和谁沟通并将想沟通的消息发送出去即可,这里可能解释的不清晰,我们后面将做进一步的详细介绍,后续的网络编程即是实现这样一个消息转发功能而最终达到端口映射。

二、方案介绍

2.1 方案简介

必要条件,一台具有公网IP的云服务器
通过云服务器将访问传输的消息进行转发

  • 假设我们的云服务器IP为101.101.101.101,我们将要编写一个服务端程序运行在云服务器上,并监听10101服务端口
  • 还需要编写一个客户端运行在实验室台式机上,该客户端需要登录并连接到服务端的10101号端口进行C/S信息交互

如果我们想将云端的40022号端口映射到实验室台式机的22号端口,那么这对C/S程序最终将达到的目的是,当我们输入公网IP+端口101.101.101.101:40022时我们将能够直接与实验室内的192.168.0.A:22进行通信。

2.2 具体流程

  1. 服务端首先监听10101端口
  2. 客户端建立与101.101.101.101:10101的TCP连接,这个连接Socket我们将之称为信息交互Socket
  3. 服务端在10101端口接收到的连接Socket我们也称为信息交互Socket
  4. 客户端将想要映射的端口通过信息交互Socket告知服务端,即告知服务端帮忙监听下云端的40022号端口
  5. 服务端通过信息交互Socket得知需要对40022号端口进行监听
  6. 当我在家中连接101.101.101.101:40022时,服务端将接收到连接请求并得到一个Socket,我们称之为SocketWan,随后将这个连接事件通过信息交互Socket告诉那个对应的客户端
  7. 客户端在信息交互Socket上得知了这个连接事件,客户端程序发起一个到本机127.0.0.1:22的连接请求,这个连接将得到一个Socket,我们称之为SocketLan
  8. 完成了所有的连接建立,后面就是进行SocketWanSocketLan之间的消息转发了,这之间的消息均需要通过信息交互Socket进行间接转发,即①SocketWan得到的消息,一并通过信息交互Socket转发给客户端,客户端在信息交互Socket上了解到有来自SocketWan的消息,立即转发到对应的SocketLan上,这就实现从101.101.101.101:40022-->192.168.0.A:22的单向消息传输;②当SocketLan得到消息时,将其得到的消息通过信息交互Socket一并转发给服务端,服务端再将消息转发至对应的SocketWan上,这就实现从192.168.0.A:22-->101.101.101.101:40022的另一单向传输,最终就实现了两者的双向消息传输

2.3 编程要点

  1. 客户端需要读取配置文件,并登录至服务端,且携带想要映射的云端端口(类似云端40022端口)
  2. 服务端监听服务端口10101,且需要处理客户端的登录事件,验证登录信息,并新开一个线程处理C/S的信息交互,并新开N个线程对需要监听的N个云端端口进行监听
  3. 服务端需要处理新连接请求,即有用户连接到40022端口了,那么我们需要通知客户端你想要监听的40022号端口有了新连接
  4. 客户端需要处理新连接事件,新建线程发起对本机或局域网内对应主机+端口的连接(例如本机127.0.0.1:22)
  5. 客户端和服务端都将收到建立了连接的端口发来的应用层消息,我们需要对这些消息进行封装、形成格式规范的消息头+消息体,客户端和服务端通过信息交互Socket传递消息,接收方获取到转发事件对消息进行解析并转发到对应端口
  6. 服务端和客户端都需要处理关闭连接请求
  7. 消息传输时需要处理TCP粘包/拆包问题,需要规范我们的消息类型,对于登录事件、新连接事件、关闭连接事件、消息转发事件以及心跳检测事件等我们都需要有具体的消息格式规范
  8. 服务端和客户端都需要处理异常断开情况,需进行心跳检测来判断是否发生了异常断开而未被捕捉产生的阻塞
  9. 为达到安全使用的目的,对于服务端<->客户端的消息传输,防止被抓包获得我们的通信内容,我们需要对传输进行加密
  10. 在登录时我们需要进行密码校验,以应对外部的攻击,例如恶意要求监听服务端1-65535所有端口
  11. 注意资源的释放,关闭连接和异常断开时的线程资源释放,很多时候会出现难以发现的资源占用,可通过相关的命令(jstack jmap jhat)等查看进程线程的资源占用情况
  12. 支持失败重试,当意外断网时,定期进行登录尝试

2.4 关于web管理IP白名单的更新

使用springboot写了一个ip白名单防火墙管理网页,因为开放端口映射是比较危险的,公网上充斥着大量的攻击,可能内网机器由于映射到公网上受到攻击,因此我实现了一个IP管理的功能,在原有程序上增加了springboot框架,使用sqlite建立了一个表格,一般的linux系统都安装了sqlite3数据库引擎,没安装的可以百度如何安装,存储内容是,

字段备注
ipip名称(主键),例如192.168.0.1
addressIP的属地,精确至市
create_time创建时间
comment备注

创建了web管理页面,登录页面认证后可添加需要放行的IP,该表外的IP将不被允许连接

2.5 关于socks5代理穿透内网上网功能的更新

例如实现当你在家中的时候依然可以访问到校内图书馆网址,或者访问实验室内局域网内任意机子,即添加代理功能,客户端让云服务器监听7890端口,校外用户将系统代理设置为云服务器IP:7890就可以愉快使用内网了,实现的需要遵从socks5协议,不了解的可以参考Socks 5 协议解析,编写过程中学习了java编写的低配版,该实现是和我想达到的目的少了一层转发

三、程序简介

3.1 简介

程序开源在我的GitHb仓库中,如果帮到了你麻烦点个star啦,万分感谢
项目是一个Maven工程,程序主要分为客户端相关、服务端相关以及公用的工具类,最新版本代码中添加了web和proxy包,分别实现web防火墙管理和socks5代理实现
在这里插入图片描述
服务端的主程序为com.liang.server.Server.java,客户端的主程序为com.liang.client.Client.java,服务端的配置文件如下,这里单机测试时ip地址都设置为127.0.0.1

common:bind_port: 10101    # 服务端口  可更换,保持与客户端一致即可token: 123456       # 密码web:bind_port: 10102  # 网页管理登录端口,可管理IP白名单username: admin   # 登录用户名password: 123456  # 登录密码

客户端配置文件config_client.yaml

common:server_addr: 127.0.0.1    # 云服务器地址server_port: 10101      # 云服务器服务端口  与服务端配置一致token: 123456         # 登录密码 与服务端配置一致nat:ssh-2:type: tcplocal_ip: 127.0.0.1 # 需要被映射的内网机器的IPlocal_port: 22      # 需要被映射的内网机器的端口remote_port: 40022  # 对应的云端服务器映射端口    # 达到的效果是访问 server_addr+40022 相当于局域网内local_ip+local_portvnc-21:type: tcplocal_ip: 127.0.0.1local_port: 5901remote_port: 45901socks5_proxy: # 代理 将浏览器的代理或系统代理改为 socks5,server_addr:7999 实现代理学校内网上网type: tcpremote_port: 7999

3.2 调试学习

运行前需确保系统上有sqlite数据库引擎,一般的linux系统都默认安装了sqlite3数据库引擎,可直接命令行sqlite3查看是否正常弹出,没安装的可以百度如何安装

  1. 运行com.liang.server.Server.java,将会弹出如下(由于加了springboot管理,打印内容变了)
    在这里插入图片描述
  2. 运行com.liang.client.Client.java后,客户端显示
    在这里插入图片描述
  3. 登录后服务端显示如下
    在这里插入图片描述
  4. 我们将可以通过本地40022号端口间接连接到本地22号端口
    例如输入ssh name@127.0.0.1 -p 40022进行连接,如遭遇报错提示主机不一致等消息执行ssh-keygen -f "/home/name/.ssh/known_hosts" -R "[127.0.0.1]:40022",其中name为你的用户名,连接后将能够使用
    程序中有许多的日志打印,但程序的默认日志级别为INFO,如想查看日志的追踪打印,将日志级别设置为TRACE即可,日志配置文件在resources/logback.xml中,也可以不更改该文件,在运行程序时使用命令进行指定,例如在idea中编辑运行、调试配置
    在这里插入图片描述
  5. 添加如下trace参数即可将日志级别设置为TRACE,这样程序中的log.trace打印出来的日志将会显示便于学习和调试
    在这里插入图片描述

四、上线使用

4.1 测试使用

  1. 上线使用时,可直接在GitHub releases中下载使用,也可以自行修改编译出来进行使用
  2. NatServer-v1.jarconfig_server.yaml放置于云端服务器中的某个文件夹NatSoft内,可视情况修改配置文件,并执行 java -jar NatServer-v1.jar即可运行,执行java -jar NatServer-v1.jar trace可以指定日志级别为TRACE,测试调试时可以这样设置,但真实上线使用时不建议打印(耗时)
    配置内容及解释示例如下
    common:bind_port: 10101    # 服务端口  可更换,保持与客户端一致即可token: 123456       # 密码web:bind_port: 10102  # 网页管理登录端口,可管理IP白名单 浏览器输入server_addr:10102可登录username: admin   # 登录用户名password: 123456  # 登录密码
    
  3. NatClient-v1.jarconfig_client.yaml放置于局域网内的电脑的某个文件夹NatSoft内,修改config_client.yaml,更改想要映射的端口和云服务器的IP密码等,执行 java -jar NatClient-v1.jar即可
    配置内容示例如下
    common:server_addr: XXX.XXX.XXX.XXX    # 云服务器地址server_port: 10101      # 云服务器服务端口  与服务端配置一致token: 123456         # 登录密码 与服务端配置一致nat:ssh-2:type: tcplocal_ip: 127.0.0.1 # 需要被映射的内网机器的IPlocal_port: 22      # 需要被映射的内网机器的端口remote_port: 40022  # 对应的云端服务器映射端口    # 达到的效果是访问 server_addr+40022 相当于局域网内local_ip+local_portvnc-21:type: tcplocal_ip: 127.0.0.1local_port: 5901remote_port: 45901socks5_proxy: # 代理 将浏览器的代理或系统代理改为 socks5,server_addr:7999 实现穿透学校内网上网type: tcpremote_port: 7999

4.2 设置自启动服务

上面的测试使用在终端断开后将停止运行,因此我们需要注册我们的服务,达到开机自启动,或者手动运行服务后终端掉线依然运行

4.2.1 服务端开机自启动

执行vim /etc/systemd/system/natServer.service创建服务,编辑如下

[Unit]
Description=nat server daemon
After=syslog.target  network.target
Wants=network.target[Service]
Type=simple
User=name	# 如果是root用户可省略
WorkingDirectory=/home/name/NatSoft			# 编辑的时候一定要删除注释 这里更改为自己放置jar包和配置的绝对路径
ExecStart=/path/to/your/java -jar NatServer-v1.jar	# 编辑的时候一定要删除注释 这里更改为自己在java命令的安装位置 可使用 which java查看
Restart= always
RestartSec=1min
[Install]
WantedBy=multi-user.target

执行如下

#启动natServer
systemctl daemon-reload
systemctl start natServer
#设置为开机启动
systemctl enable natServer

4.2.2 客户端开机自启动

执行sudo vim /etc/systemd/system/natClient.service创建服务,编辑如下

[Unit]
Description=nat client daemon
After=syslog.target  network.target
Wants=network.target[Service]
Type=simple
User=name	# 编辑的时候一定要删除注释 这样可以使得进程归用户所有,使用jps查看时可以查看到,如果不设置,那么普通用户jps查看不到
WorkingDirectory=/home/name/NatSoft			# 编辑的时候一定要删除注释 这里更改为自己放置jar包和配置文件的绝对路径
ExecStart=/path/to/your/java -jar NatClient-v1.jar # 编辑的时候一定要删除注释 这里更改为自己在java命令的安装位置 可使用 which java查看
Restart= always
RestartSec=1min
[Install]
WantedBy=multi-user.target

执行如下

#启动natServer
systemctl daemon-reload
systemctl start natClient
#设置为开机启动
systemctl enable natClient

4.3 IP白名单防火墙管理

  1. 输入你设置的web管理端口,server_addr:10102
    在这里插入图片描述
  2. IP白名单列表
    在里面可以删除和修改每条记录
    在这里插入图片描述
  3. 添加IP
    点击上方添加IP,将进入如下界面,下面的IP自动填充为访问设备的IP,属地为联网查询到并填充的,备注可以手动填写,另外我更新了一种IP过滤策略,一个IP是32位的,当添加IP为192.168.0.0/24时,则只需要IP的前24位与给定IP相同即可,即192.168.0开头即可
    在这里插入图片描述

http://chatgpt.dhexx.cn/article/aqLUX60M.shtml

相关文章

计算机网络--Windows网络测试工具

实验目的 理解上述知识点所涉及的基本概念并学会使用这些工具测试网络的状态及从网上获取信息。 实验环境 安装了TCP/IP协议的Windows系统&#xff0c;包含实用的网络工具。 实验内容 完成下列要求&#xff0c;并记录实验步骤和结果 1、 检测本机的MAC地址 2、 检测本机网…

【小工具的制作】制作一个通过HTTP请求来实现上网认证的自动登录小工具

目录 1. 前言2. 分析3. 编码3.1 Python版3.1.1 编写Python脚本3.1.2 下载Python转EXE程序工具3.1.3 打包成EXE程序 3.2 Java版3.2.1 编写代码 4. 最后一步5. 总结 1. 前言 由于学校机房联网时&#xff0c;总是需要登录个人账号。为实现快速登录&#xff0c;我们就此问题给出了自…

常见的网络抓包工具推荐

因为发现好多人想抓包&#xff0c;但是不知道有哪些工具&#xff0c;今天我给大家推荐几款抓包工具&#xff0c;希望对大家有所帮助。 网络抓包工具的用途 网络抓包工具的主要功能是将网络执行的过程&#xff0c;详细的记录下来。如果你是一个程序员&#xff0c;肯定对网络抓…

【转】Fiddler抓包工具手机添加代理后连不上网解决办法

转载&#xff1a;Fiddler抓包工具手机添加代理后连不上网解决办法_数据结构和算法的博客-CSDN博客 最近&#xff0c;在工作中需要测试一个监控网络请求的SDK&#xff0c;需要校验该SDK记录的耗时数据的准确性。根据网上大神们提供的工作经验&#xff0c;可以利用Fiddler工具给…

超好用的网络小工具

整理了一下一些自己使用的网络链路状态测试工具。 一、RAWCAP-本地回路抓包 本地使用wireshark无法抓回路包&#xff0c;为此百度了一下RawCap可以抓回路包&#xff0c;亲测可用。特记录下来。 缺点&#xff1a;有一些系统需要安装Microsoft .NET Framework 4 https://www.m…

8大轻型网管工具,网络管理好帮手

从设备发现到系统、网络和流量可视性&#xff0c;这些轻型的网管工具非常实用。在网络和服务器世界&#xff0c;重点是可视性、可视性、可视性&#xff0c;如果你不知道你的网络和服务器在每天每秒正在做什么&#xff0c;你很可能会出问题。幸运的是&#xff0c;这里有很多好工…

上网本之必备网络工具推荐

伴随着中国3G无线网络的全面商用运营&#xff0c;“上网本”已经成为2009年最炙手可热的词汇之一。“上网本”便宜实惠、小巧便携&#xff0c;但低配置却是它的一个软肋&#xff0c;所以能够完全配合“上网本”使用的低耗能软件似乎并不多。这里&#xff0c;笔者结合自己的一些…

网络测速工具

一、Speedtest测试外网网速 Speedtest是用来测试网络性能的开源软件&#xff0c;在Linux下面安装Speedtest可以用来测试网络出口的上传和下载速度&#xff0c;帮助排查网络方面导致的故障。 官网&#xff1a; Github链接&#xff1a;https://github.com/sivel/speedtest-cli …

windows - 网络流量监控工具

由于需要在本地的流量监控工具 1、DUMeterPortable 可以对当前的pc网络的上下行做记录和统计&#xff0c;可以统计每天的流量控制&#xff0c;程序实时记录 2、BW 功能比较强大&#xff0c;但是监控比较烦人&#xff0c;如果是查看流量的话&#xff0c;这个软件没有必要 3、…

上网必备 11款流氓软件清除工具推荐

2007-09-19 来源: 天极yesky 作者:李红 据调查&#xff0c;目前高达95&#xff05;以上的网民都受到过流氓软件的侵袭&#xff0c;其中&#xff0c;半数以上未成功卸载过流氓软件。流氓软件虽然不是真正的病毒&#xff0c;但是它强行弹出广告、劫持和更换IE主页&#xff0c;…

10 个免费的网络监控工具

如果你有一个网站或一个网络&#xff0c;你应该密切的关注它&#xff0c;并在问题发生之后迅速解决。最简单方便的办法是通过使用服务器/网络监视工具来监视您的设备&#xff0c;以防任何可能出现的问题。有许多免费和开源服务器和网络监控工具存在,但找到一个好用的并不是件容…

10个免费网络管理工具

作为一名资深网络工程师&#xff0c;在15年以上的职业生涯中&#xff0c;你可能经历过在各种环境中进行评估&#xff0c;使用了大量的开源网络工具。有些实在是有太多的bug&#xff0c;比如缺乏关键功能或太耗时。你可能也在苦苦寻求着好用的免费网络管理工具&#xff0c;在本文…

网络工具Network Tools

Hosts文件管理工具 Hosts文件的位置 C:\Windows\System32\drivers\etc\hosts SwitchHosts 通过界面开启或者关闭来管理多个Hosts&#xff0c;下载地址。

网管利器:七大免费网络工具

今天无意间又发现了一系列的好东西。 这里&#xff0c;我为您推荐七个免费的网络工具&#xff0c;使网络管理员的日常工作更加轻松。这七个工具大多小巧玲珑&#xff0c;无需安装&#xff0c;用一个U盘就可以轻松携带! 一、Pingplotter让Ping和Traceroute焕发青春 运行平台&am…

不用科学上网,免费的GPT-4 IDE工具Cursor保姆级使用教程

Cursor官网下载地址 我下载的是window版的 操作特别简单&#xff0c;只需要记住两个快捷键就行&#xff1a; Windows 平台&#xff1a; CtrlK : 智能生成代码 CtrlL: 询问代码含义 Mac 平台&#xff1a; CommandK : 智能生成代码 CommandL: 询问代码含义 生成示例&#xff1a…

浏览器必备的上网工具,同样也是收藏党必备工具

浏览器必备的上网工具&#xff0c;同样也是收藏党必备工具&#xff0c; 网页图片收藏工具&#xff0c;可以收藏全网的网页图片&#xff0c;无需下载到本地了&#xff0c;太方便了 工具名称&#xff1a;BdTab新标签页插件&#xff0c;支持图片收藏

21个非常有用的免费网络工具

在线服务 收集了21个在日常生活中经常会用到的免费网络工具。不管你是学生、程序开发员、设计师借是办公室职员&#xff0c;那几个工具都十分有用。一起来看看都有哪些。 1.Phonevite使用Phonevite?可以用你本人的声音发送提醒和警报&#xff0c;你只需3步即可将免费的提醒消息…

Android应用Preference相关及源码浅析(Preference组件家族篇)

1 前言 前一篇&#xff08;点我阅读前一篇《Android应用Preference相关及源码浅析(SharePreferences篇)》&#xff09;我们讨论分析使用了Android的SharePreferences&#xff0c;相信看过的朋友都有了自己的感悟与理解&#xff0c;这一篇我们继续乘热打铁来说说SharePreferenc…

Android APP:Preference使用详解和实例(附源码)

Android APP&#xff1a;Preference使用详解和实例 一、Preference 是Android app中重要的控件之一&#xff0c;Settings 模块大部分都是通过Preference 实现的&#xff0c;这里将学习preference 使用方法。 二、Perference 使用方法 一般在XML文件夹中创建xml文件来对Setting…

Android开发之 Preference首选项

首选项最常使用的地方是系统的设置列表或应用程序的设置页。本示例在android 4.0上运行。    在res/xml文件下建立xml文件&#xff0c;设置需要的控件。下面的xml文件使用了PreferenceCategory 、CheckBoxPreference、ListPreference。PreferenceCategory 是一个标题栏分隔符…