注意: 本文内容于 2025-04-13 15:09:48 创建,可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容,请访问原文地址:手撕TCP内网穿透及配置树莓派。感谢您的关注与支持!
之前入手了树莓派5,折腾一段时间后,环境算是搭好了。
但是又不想随身携带,我刚好有个公网IP,想着通过公网访问。于是就用到了内网穿透。
清明节三天爆肝,断断续续总共耗费一周。简单测试,性能还行。
一、TCP内网穿透
1.1 起因
使用fatedier/frp的过程中,不管在Windows还是Linux,都被扫出病毒了。而且这还是Golang自身的问题,参考Why does my virus-scanning software think my Go distribution or compiled binary is infected? 。
这个内网穿透本身也没多难,因此自己用Java手撕一套内网穿透工具,还是很有必要的。
1.2 原理
原理很简单,一张时序图以蔽之。

1.3 使用示例
创建一个Java项目,JDK使用8及以上,引入依赖
xml
<dependency>
<groupId>top.meethigher</groupId>
<artifactId>tcp-reverse-proxy</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>4.5.10</version>
</dependency>
<!-- 若不使用http反向代理,可不加此依赖 -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>4.5.10</version>
</dependency>
<!-- 若不想添加日志,可只添加slf4j-api -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 若不使用TCP内网穿透,可不加此依赖 -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-javalite</artifactId>
<version>4.30.2</version>
</dependency>
假如我有一个内网SSH
服务10.0.0.10:22
,需要通过192.168.0.200:22
穿透出去。并且网络条件受限如下
10.0.0.10
可以主动连接192.168.0.200
192.168.0.200
无法主动连接10.0.0.10
- 只要双方建立连接,即可实现双向数据传输
这就需要TCP内网穿透了。假设你内网穿透使用的控制端口为44444
。
首先,在192.168.0.200
这台机器,使用如下代码启动TunnelServer
java
ReverseTcpProxyTunnelServer.create(Vertx.vertx())
.port(44444)
// 用于用户连接和数据连接的延迟判定,如果网络较差/DNS解析较慢的情况下,建议将该参数调大
.judgeDelay(2000)
.start();
在10.0.0.10
这台机器,使用如下代码启动TunnelClient
java
ReverseTcpProxyTunnelClient.create(Vertx.vertx())
.backendHost("10.0.0.10")
.backendPort(22)
.dataProxyName("ssh-proxy")
.dataProxyHost("192.168.0.200")
.dataProxyPort(22)
.connect("192.168.0.200", 44444);
以上的源代码都是开源的
- 开发工具包:meethigher/tcp-reverse-proxy: 基于Vert.x实现的HTTP反向代理与TCP反向代理、内网穿透
- 可直接运行的Jar包:Release Release-v3.0.0 · meethigher/http-proxy-boot
1.4 实战
下面放一个我将树莓派用于生产环境时,使用的内网穿透配置Bash脚本。
服务端
sh
cat >/etc/systemd/system/tunnel-server.service<<EOF
[Unit]
Description=tunnel-server
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/sh -c "java -jar tunnel-server.jar >/dev/null 2>&1"
WorkingDirectory=/usr/local/tunnel-server
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable tunnel-server
systemctl start tunnel-server
客户端
sh
cat >/etc/systemd/system/tunnel-client.service<<EOF
[Unit]
Description=tunnel-client
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/sh -c "java -jar tunnel-client.jar >/dev/null 2>&1"
WorkingDirectory=/usr/local/tunnel-client
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable tunnel-client
systemctl start tunnel-client
由于客户端所在局域网内的IP经常变,因此我添加了一个固定的VIP
sh
cat >/etc/systemd/system/vip.service<<EOF
[Unit]
Description=vip
After=network.target
[Service]
Type=oneshot
ExecStartPre=/usr/bin/sleep 30
ExecStart=/usr/sbin/ip addr add 192.168.1.222/32 dev wlan0
ExecStop=/usr/sbin/ip addr del 192.168.1.222/32 dev wlan0
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
以上配置完了,就是再将内网穿透出来的SSH服务,配置为私钥登录。不多赘述。

二、无显示器树莓派5
树莓派入门视频,参考树莓派教程第一课 树莓派简介 十分钟玩转系列入门篇_哔哩哔哩_bilibili
又额外买了512GB存储,总共花费1007元。


2.1 系统烧录
下载系统镜像,选择环境最全的这个。
我没有显示器,需要采用远程SSH使用。但是需要到了SSH服务器拒绝了密码的情况。通过启用无屏幕 SSH Raspberry Pi - Thinbug进行解决。而在简易版系统上,无法使用该功能。

使用镜像烧录工具下载也可,但是我个人比较喜欢留存离线镜像。
下载镜像烧录工具。

打开镜像烧录工具,选择设备、选择操作系统镜像、选择存储卡。

点击Next,编辑设置。
WIFI国家一定要设置为CN

之后就等待烧录即可。

2.2 远程SSH
我在远程连接树莓派SSH时,遭拒绝了,是因为树莓派OS设置了不允许直接通过root登录。
需要执行如下操作。参考自启用无屏幕 SSH Raspberry Pi - Thinbug
- 在SD卡内创建
ssh
文件,内容为空。 - 在SD卡内创建
userconf.txt
文件,内容为pi:$6$/4.VdYgDm7RJ0qM1$FwXCeQgDKkqrOU3RIRuDSKpauAbBvP11msq9X58c8Que2l1Dwq3vdJMgiZlQSbEXGaY5esVHGBNbCxKLVNqZW1
,表示设置用户pi
的密码是raspberry
上面这个密码也可以自己生成,使用命令
sh
openssl passwd -6 '你的密码'
搞定之后,将SD卡插入树莓派,获取树莓派在局域网的IP地址,直接通过SSH进行登录。
sh
ssh -p 22 [email protected]
或者使用图形界面工具,比如XShell

安装neofetch
,查看系统信息
sh
apt -y install neofetch
neofetch

2.3 说明
树莓派OS是基于DebianOS。
我平时使用的系统是CentOS(停止维护)或者RockyLinux。
本质都是Linux,注意下使用细节即可。
项目 | CentOS(RockyLinux) | Debian |
---|---|---|
上游来源 | Red Hat Enterprise Linux (RHEL) | 自主开发 |
包格式 | .rpm |
.deb |
包管理器 | yum / dnf |
apt 。apt 是对旧有工具(如 apt-get 和 apt-cache )的一个综合替代 |
2.4 修改默认的反人类设置
2.4.1 vi中上下左右变成abcd
使用vi编辑文件,输入i进行insert模式,此时按上下左右时,变成了abcd,而不是光标移动。执行如下命令解决。
sh
apt -y remove vim-common && apt -y install vim
2.4.2 vi右键无法粘贴
这些新功能,对于我这种老古董来说,用起来太反人类了,因此我切到了neovim。参考Disable vim automatic visual mode on mouse select

sh
apt remove -y vim
apt install -y neovim
2.4.3 root用户终端无色
树莓派中pi
用户的终端有颜色,root
用户的终端无颜色。简单粗暴,把pi
用户的配置复制过来。
sh
cp ~/.bashrc ~/.bashrc-bak
cp /home/pi/.bashrc ~./bashrc
重连终端即可生效。
