Skip to content

Commit a96a989

Browse files
committed
feat: tunnel支持通信中的关键信息加密
1 parent 3aa2f74 commit a96a989

File tree

8 files changed

+42
-22
lines changed

8 files changed

+42
-22
lines changed

src/main/java/top/meethigher/proxy/tcp/tunnel/ReverseTcpProxyTunnelClient.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public class ReverseTcpProxyTunnelClient extends TunnelClient {
4242
protected static final long MAX_DELAY_DEFAULT = 64000;// 毫秒
4343

4444

45-
protected final String secret;
4645
protected final String name;
4746

4847
protected long heartbeatDelay;
@@ -75,8 +74,7 @@ public static String generateName() {
7574
protected ReverseTcpProxyTunnelClient(Vertx vertx, NetClient netClient,
7675
long minDelay, long maxDelay,
7776
String secret, String name) {
78-
super(vertx, netClient, minDelay, maxDelay);
79-
this.secret = secret;
77+
super(vertx, netClient, minDelay, maxDelay, secret);
8078
this.name = name;
8179
addMessageHandler();
8280
}
@@ -148,7 +146,7 @@ protected void addMessageHandler() {
148146
protected boolean doHandle(Vertx vertx, NetSocket netSocket, TunnelMessageType type, byte[] bodyBytes) {
149147
boolean result = false;
150148
try {
151-
TunnelMessage.OpenDataPortAck parsed = TunnelMessage.OpenDataPortAck.parseFrom(bodyBytes);
149+
TunnelMessage.OpenDataPortAck parsed = TunnelMessage.OpenDataPortAck.parseFrom(aesBase64Decode(bodyBytes));
152150
if (parsed.getSuccess()) {
153151
// 如果认证 + 开通端口成功,那么就需要进行长连接保持,并开启定期心跳。
154152
result = true;

src/main/java/top/meethigher/proxy/tcp/tunnel/ReverseTcpProxyTunnelServer.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,10 @@ public class ReverseTcpProxyTunnelServer extends TunnelServer {
5353

5454

5555
protected final Map<NetSocket, DataProxyServer> authedSockets;// 授权成功的控制连接与数据服务的对应关系
56-
protected final String secret; // 鉴权密钥
5756
protected final String name; // 控制服务的名称
5857

5958
protected ReverseTcpProxyTunnelServer(Vertx vertx, NetServer netServer, String secret, Map<NetSocket, DataProxyServer> authedSockets, String name) {
60-
super(vertx, netServer);
61-
this.secret = secret;
59+
super(vertx, netServer, secret);
6260
this.name = name;
6361
this.authedSockets = authedSockets;
6462
addMessageHandler();
@@ -444,7 +442,7 @@ protected boolean doHandle(Vertx vertx, NetSocket netSocket, TunnelMessageType t
444442
// 如果授权通过,并且成功开通端口。则返回成功;否则则返回失败,并关闭连接
445443
boolean result = false;
446444
try {
447-
TunnelMessage.OpenDataPort parsed = TunnelMessage.OpenDataPort.parseFrom(bodyBytes);
445+
TunnelMessage.OpenDataPort parsed = TunnelMessage.OpenDataPort.parseFrom(aesBase64Decode(bodyBytes));
448446
TunnelMessage.OpenDataPortAck.Builder builder = TunnelMessage.OpenDataPortAck
449447
.newBuilder();
450448
builder.setHeartbeatDelay(heartbeatDelay);
@@ -507,7 +505,7 @@ protected boolean doHandle(Vertx vertx, NetSocket netSocket, TunnelMessageType t
507505
protected boolean doHandle(Vertx vertx, NetSocket netSocket, TunnelMessageType type, byte[] bodyBytes) {
508506
boolean result = false;
509507
try {
510-
TunnelMessage.OpenDataConnAck openDataConnAck = TunnelMessage.OpenDataConnAck.parseFrom(bodyBytes);
508+
TunnelMessage.OpenDataConnAck openDataConnAck = TunnelMessage.OpenDataConnAck.parseFrom(aesBase64Decode(bodyBytes));
511509
result = openDataConnAck.getSuccess();
512510
} catch (Exception ignore) {
513511
}

src/main/java/top/meethigher/proxy/tcp/tunnel/Tunnel.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010
import top.meethigher.proxy.tcp.tunnel.codec.TunnelMessageType;
1111
import top.meethigher.proxy.tcp.tunnel.handler.TunnelHandler;
1212

13+
import javax.crypto.SecretKey;
14+
import java.nio.charset.StandardCharsets;
1315
import java.util.LinkedHashMap;
1416
import java.util.Map;
1517

18+
import static top.meethigher.proxy.FastAes.*;
19+
1620
/**
1721
* 封装通用的 TCP 交互API
1822
* 参考<a href="https://github.com/socketio/socket.io-client-java/blob/socket.io-client-2.1.0/src/main/java/io/socket/client/Socket.java">socket.io-client-java</a>
@@ -24,18 +28,20 @@ public abstract class Tunnel {
2428

2529
private static final Logger log = LoggerFactory.getLogger(Tunnel.class);
2630
protected final Vertx vertx;
27-
protected static final String SECRET_DEFAULT = "0123456789";
31+
protected final String secret;
32+
public static final String SECRET_DEFAULT = "hello,meethigher";
2833

2934
// 数据连接建立后立马发送4字节标识符cafebabe
30-
protected static final byte[] DATA_CONN_FLAG = new byte[]{
35+
public static final byte[] DATA_CONN_FLAG = new byte[]{
3136
(byte) 0xca,
3237
(byte) 0xfe,
3338
(byte) 0xba,
3439
(byte) 0xbe
3540
};
3641

37-
protected Tunnel(Vertx vertx) {
42+
protected Tunnel(Vertx vertx, String secret) {
3843
this.vertx = vertx;
44+
this.secret = secret;
3945
}
4046

4147
/**
@@ -62,6 +68,23 @@ public void on(TunnelMessageType type, TunnelHandler tunnelHandler) {
6268
tunnelHandlers.put(type, tunnelHandler);
6369
}
6470

71+
72+
/**
73+
* 返回加密base64串(无换行)
74+
*/
75+
public byte[] aesBase64Encode(byte[] bodyBytes) {
76+
SecretKey key = restoreKey(secret.getBytes(StandardCharsets.UTF_8));
77+
return encrypt(bodyBytes, key);
78+
}
79+
80+
/**
81+
* 将加密内容还原
82+
*/
83+
public byte[] aesBase64Decode(byte[] bodyBytes) {
84+
SecretKey key = restoreKey(secret.getBytes(StandardCharsets.UTF_8));
85+
return decrypt(bodyBytes, key);
86+
}
87+
6588
/**
6689
* 将请求体按照{@code TunnelMessageCodec} 规范进行编码
6790
*
@@ -70,7 +93,7 @@ public void on(TunnelMessageType type, TunnelHandler tunnelHandler) {
7093
* @return 编码结果
7194
*/
7295
public Buffer encode(TunnelMessageType type, byte[] bodyBytes) {
73-
return TunnelMessageCodec.encode(type.code(), bodyBytes);
96+
return TunnelMessageCodec.encode(type.code(), aesBase64Encode(bodyBytes));
7497
}
7598

7699
/**

src/main/java/top/meethigher/proxy/tcp/tunnel/TunnelClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ public abstract class TunnelClient extends Tunnel {
4949
protected NetSocket netSocket;
5050

5151

52-
protected TunnelClient(Vertx vertx, NetClient netClient, long minDelay, long maxDelay) {
53-
super(vertx);
52+
protected TunnelClient(Vertx vertx, NetClient netClient, long minDelay, long maxDelay, String secret) {
53+
super(vertx, secret);
5454
this.netClient = netClient;
5555
this.minDelay = minDelay;
5656
this.maxDelay = maxDelay;

src/main/java/top/meethigher/proxy/tcp/tunnel/TunnelServer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ public abstract class TunnelServer extends Tunnel {
1616

1717
protected final NetServer netServer;
1818

19-
protected TunnelServer(Vertx vertx, NetServer netServer) {
20-
super(vertx);
19+
protected TunnelServer(Vertx vertx, NetServer netServer, String secret) {
20+
super(vertx, secret);
2121
this.netServer = netServer;
2222
}
2323
}

src/test/java/top/meethigher/proxy/tcp/tunnel/ReverseTcpProxyTunnelClientTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ public void client() {
132132
new AddressResolverOptions().setQueryTimeout(2000)
133133
));
134134
// ssh内网穿透
135-
ReverseTcpProxyTunnelClient.create(ReverseTcpProxyTunnelClientTest.vertx, vertx.createNetClient(), "helloworld")
136-
.backendHost("10.0.0.9")
135+
ReverseTcpProxyTunnelClient.create(ReverseTcpProxyTunnelClientTest.vertx, vertx.createNetClient(), Tunnel.SECRET_DEFAULT)
136+
.backendHost("10.0.0.30")
137137
.backendPort(22)
138138
.dataProxyName("ssh-proxy")
139139
.dataProxyHost("10.0.0.1")

src/test/java/top/meethigher/proxy/tcp/tunnel/ReverseTcpProxyTunnelServerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public class ReverseTcpProxyTunnelServerTest {
1414
public void server() {
1515
Vertx vertx = Vertx.vertx();
1616
ReverseTcpProxyTunnelServer server = ReverseTcpProxyTunnelServer.create(vertx, vertx.createNetServer(
17-
new NetServerOptions().setTcpNoDelay(true)
18-
), "helloworld", new ConcurrentHashMap<>())
17+
new NetServerOptions().setTcpNoDelay(true)
18+
), Tunnel.SECRET_DEFAULT, new ConcurrentHashMap<>())
1919
.port(44444)
2020
.judgeDelay(300);
2121
server.start();

src/test/java/top/meethigher/proxy/tcp/tunnel/codec/ClientCodecTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.junit.Test;
77
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
9+
import top.meethigher.proxy.tcp.tunnel.Tunnel;
910
import top.meethigher.proxy.tcp.tunnel.TunnelClient;
1011
import top.meethigher.proxy.tcp.tunnel.handler.AbstractTunnelHandler;
1112

@@ -26,7 +27,7 @@ public class ClientCodecTest {
2627
@Test
2728
public void client() {
2829
Vertx vertx = Vertx.vertx(new VertxOptions().setMaxWorkerExecuteTimeUnit(TimeUnit.DAYS));
29-
TunnelClient tunnelClient = new TunnelClient(vertx, vertx.createNetClient(), 1000, 64000) {
30+
TunnelClient tunnelClient = new TunnelClient(vertx, vertx.createNetClient(), 1000, 64000, Tunnel.SECRET_DEFAULT) {
3031

3132
};
3233
tunnelClient.connect("127.0.0.1", 8080);

0 commit comments

Comments
 (0)