This is an automated email from the ASF dual-hosted git repository.
cyyang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
The following commit(s) were added to refs/heads/master by this push:
new 0b0fac4a41 [bugfix] fix the collector aes decode with secret error
(#3652)
0b0fac4a41 is described below
commit 0b0fac4a411bfa9ed1a8111b3f23251a01a5b79a
Author: tomsun28 <[email protected]>
AuthorDate: Sun Aug 10 22:34:10 2025 +0800
[bugfix] fix the collector aes decode with secret error (#3652)
Signed-off-by: tomsun28 <[email protected]>
---
.../entrance/processor/GoOnlineProcessor.java | 13 ++++++
.../hertzbeat/common/entity/dto/ServerInfo.java | 40 ++++++++++++++++++
.../org/apache/hertzbeat/common/util/AesUtil.java | 12 ++++--
.../apache/hertzbeat/common/util/AesUtilTest.java | 2 +-
.../manager/config/ConfigInitializer.java | 48 ++++++++++++----------
.../manager/scheduler/CollectorJobScheduler.java | 4 ++
.../netty/process/CollectorOnlineProcessor.java | 11 ++++-
.../remoting/netty/NettyRemotingAbstract.java | 14 +++++--
8 files changed, 113 insertions(+), 31 deletions(-)
diff --git
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/entrance/processor/GoOnlineProcessor.java
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/entrance/processor/GoOnlineProcessor.java
index 1337001082..34dda15197 100644
---
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/entrance/processor/GoOnlineProcessor.java
+++
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/dispatch/entrance/processor/GoOnlineProcessor.java
@@ -22,8 +22,11 @@ import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.timer.TimerDispatch;
import org.apache.hertzbeat.common.constants.CommonConstants;
+import org.apache.hertzbeat.common.entity.dto.ServerInfo;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.support.SpringContextHolder;
+import org.apache.hertzbeat.common.util.AesUtil;
+import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.hertzbeat.remoting.netty.NettyRemotingProcessor;
/**
@@ -40,6 +43,16 @@ public class GoOnlineProcessor implements
NettyRemotingProcessor {
if (this.timerDispatch == null) {
this.timerDispatch =
SpringContextHolder.getBean(TimerDispatch.class);
}
+ if (message.getMsg().isEmpty()) {
+ log.warn("The message that server response to collector is empty,
please upgrade server");
+ } else {
+ ServerInfo serverInfo =
JsonUtil.fromJson(message.getMsg().toStringUtf8(), ServerInfo.class);
+ if (serverInfo == null || serverInfo.getAesSecret() == null) {
+ log.warn("The message that server response to collector has
not secret empty, please check");
+ } else {
+ AesUtil.setDefaultSecretKey(serverInfo.getAesSecret());
+ }
+ }
timerDispatch.goOnline();
log.info("receive online message and handle success");
return ClusterMsg.Message.newBuilder()
diff --git
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ServerInfo.java
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ServerInfo.java
new file mode 100644
index 0000000000..4b3fe8a4fc
--- /dev/null
+++
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ServerInfo.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.common.entity.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * collector info
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Schema(description = "manager server info")
+public class ServerInfo {
+
+ /**
+ * the aes secret key value for aes encode decode
+ */
+ private String aesSecret;
+}
diff --git
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/AesUtil.java
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/AesUtil.java
index 0ec608fb39..fd1279b809 100644
---
a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/AesUtil.java
+++
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/util/AesUtil.java
@@ -37,7 +37,7 @@ public final class AesUtil {
* Default encryption key The AES encryption key is 16 bits by default.
* If the AES encryption key is larger than or smaller than 16 bits, an
error message is displayed
*/
- public static final String ENCODE_RULES = "tomSun28HaHaHaHa";
+ public static final String DEFAULT_ENCODE_RULES = "tomSun28HaHaHaHa";
/**
* Default algorithm
@@ -50,13 +50,17 @@ public final class AesUtil {
* Encryption key The AES encryption key is 16 bits.
* If the AES encryption key is larger than 16 bits, an error message is
displayed
*/
- private static String secretKey = ENCODE_RULES;
+ private static String secretKey = DEFAULT_ENCODE_RULES;
private AesUtil() {}
public static void setDefaultSecretKey(String secretKeyNow) {
secretKey = secretKeyNow;
}
+
+ public static String getDefaultSecretKey() {
+ return secretKey;
+ }
public static String aesEncode(String content) {
return aesEncode(content, secretKey);
@@ -109,9 +113,9 @@ public final class AesUtil {
byte[] byteDecode = getBytes(content, decryptKey);
return new String(byteDecode, StandardCharsets.UTF_8);
} catch (BadPaddingException e) {
- if (!ENCODE_RULES.equals(decryptKey)) {
+ if (!DEFAULT_ENCODE_RULES.equals(decryptKey)) {
log.warn("There has default encode secret encode content, try
to decode with default secret key");
- return aesDecode(content, ENCODE_RULES);
+ return aesDecode(content, DEFAULT_ENCODE_RULES);
}
log.error("aes decode content error: {}, please config right
common secret key", e.getMessage());
return content;
diff --git
a/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/util/AesUtilTest.java
b/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/util/AesUtilTest.java
index 40ec65cd01..9bff2d915c 100644
---
a/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/util/AesUtilTest.java
+++
b/hertzbeat-common/src/test/java/org/apache/hertzbeat/common/util/AesUtilTest.java
@@ -95,7 +95,7 @@ class AesUtilTest {
// Test with default key
String originalText = "This is a secret message";
// encode use default secret key
- String encryptedText = aesEncode(originalText, AesUtil.ENCODE_RULES);
+ String encryptedText = aesEncode(originalText,
AesUtil.DEFAULT_ENCODE_RULES);
// decode use new secret key
String decryptedText = aesDecode(encryptedText, "newkey1234567890");
// old data can decode with default secret key
diff --git
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ConfigInitializer.java
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ConfigInitializer.java
index 129d004ce4..35d48c0fa9 100644
---
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ConfigInitializer.java
+++
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/config/ConfigInitializer.java
@@ -20,9 +20,9 @@ package org.apache.hertzbeat.manager.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.usthe.sureness.util.JsonWebTokenUtil;
import jakarta.annotation.Resource;
+import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Locale;
-import java.util.Random;
import java.util.TimeZone;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
@@ -63,7 +63,7 @@ public class ConfigInitializer implements SmartLifecycle {
@Value("${sureness.jwt.secret:" + DEFAULT_JWT_SECRET + "}")
private String currentJwtSecret;
- @Value("${common.secret:" + AesUtil.ENCODE_RULES + "}")
+ @Value("${common.secret:" + AesUtil.DEFAULT_ENCODE_RULES + "}")
private String currentAesSecret;
@Resource
@@ -114,38 +114,40 @@ public class ConfigInitializer implements SmartLifecycle {
// for template config, flush the template config in db to memory
TemplateConfig templateConfig = templateConfigService.getConfig();
appService.updateCustomTemplateConfig(templateConfig);
- // for system secrets
+ // for system jwt secrets and aes secret
boolean needUpdate = false;
- SystemSecret.SystemSecretBuilder builder = SystemSecret.builder();
+ SystemSecret.SystemSecretBuilder systemSecretBuilder =
SystemSecret.builder();
+ SystemSecret systemSecret = systemSecretService.getConfig();
+ if (systemSecret != null) {
+ systemSecretBuilder.jwtSecret(systemSecret.getJwtSecret());
+ systemSecretBuilder.aesSecret(systemSecret.getAesSecret());
+ }
if (DEFAULT_JWT_SECRET.equals(currentJwtSecret)) {
// use the random jwt secret
- SystemSecret systemSecret = systemSecretService.getConfig();
if (systemSecret == null ||
StringUtils.isBlank(systemSecret.getJwtSecret())) {
currentJwtSecret = randomizeSecret(DEFAULT_JWT_SECRET);
- builder.jwtSecret(currentJwtSecret);
+ systemSecretBuilder.jwtSecret(currentJwtSecret);
needUpdate = true;
} else {
currentJwtSecret = systemSecret.getJwtSecret();
}
}
- // else use the user custom jwt secret
- // set the jwt secret token in util
+ // else use the user custom jwt secret, set the jwt secret token in
util
JsonWebTokenUtil.setDefaultSecretKey(currentJwtSecret);
// Aes secret config
- if (AesUtil.ENCODE_RULES.equals(currentAesSecret)) {
+ if (AesUtil.DEFAULT_ENCODE_RULES.equals(currentAesSecret)) {
// use the random aes secret
- SystemSecret systemSecret = systemSecretService.getConfig();
if (systemSecret == null ||
StringUtils.isBlank(systemSecret.getAesSecret())) {
- currentAesSecret = randomizeSecret(AesUtil.ENCODE_RULES);
- builder.aesSecret(currentAesSecret);
+ currentAesSecret =
randomizeSecret(AesUtil.DEFAULT_ENCODE_RULES);
+ systemSecretBuilder.aesSecret(currentAesSecret);
+ needUpdate = true;
} else {
currentAesSecret = systemSecret.getAesSecret();
}
}
AesUtil.setDefaultSecretKey(currentAesSecret);
if (needUpdate) {
- SystemSecret systemSecret = builder.build();
- systemSecretService.saveConfig(systemSecret);
+ systemSecretService.saveConfig(systemSecretBuilder.build());
}
// init web-app mute config
MuteConfig muteConfig = muteGeneralConfigService.getConfig();
@@ -177,14 +179,16 @@ public class ConfigInitializer implements SmartLifecycle {
}
private String randomizeSecret(String secret) {
- char[] chars = secret.toCharArray();
- Random rand = new Random();
- for (int i = 0; i < chars.length; i++) {
- int index = rand.nextInt(chars.length);
- char temp = chars[i];
- chars[i] = chars[index];
- chars[index] = temp;
+ SecureRandom random = new SecureRandom();
+ StringBuilder sb = new StringBuilder(secret.length());
+ for (int i = 0; i < secret.length(); i++) {
+ char ch;
+ do {
+ int codePoint = random.nextInt('z' - '0' + 1) + '0';
+ ch = (char) codePoint;
+ } while (!Character.isLetterOrDigit(ch));
+ sb.append(ch);
}
- return new String(chars);
+ return sb.toString();
}
}
diff --git
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
index c0eed7aa9a..c939200e76 100644
---
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
+++
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/CollectorJobScheduler.java
@@ -36,6 +36,7 @@ import
org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectJobServi
import
org.apache.hertzbeat.collector.dispatch.entrance.internal.CollectResponseEventListener;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
+import org.apache.hertzbeat.common.entity.dto.ServerInfo;
import org.apache.hertzbeat.common.entity.job.Configmap;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.entity.manager.Collector;
@@ -45,6 +46,7 @@ import org.apache.hertzbeat.common.entity.manager.Param;
import org.apache.hertzbeat.common.entity.manager.ParamDefine;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
import org.apache.hertzbeat.common.entity.message.CollectRep;
+import org.apache.hertzbeat.common.util.AesUtil;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
import org.apache.hertzbeat.manager.dao.CollectorDao;
@@ -261,9 +263,11 @@ public class CollectorJobScheduler implements
CollectorScheduling, CollectJobSch
if (Objects.isNull(collector)) {
return false;
}
+ ServerInfo serverInfo =
ServerInfo.builder().aesSecret(AesUtil.getDefaultSecretKey()).build();
ClusterMsg.Message message = ClusterMsg.Message.newBuilder()
.setType(ClusterMsg.MessageType.GO_ONLINE)
.setDirection(ClusterMsg.Direction.REQUEST)
+ .setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(serverInfo)))
.setIdentity(identity)
.build();
ClusterMsg.Message response = this.manageServer.sendMsgSync(identity,
message);
diff --git
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/netty/process/CollectorOnlineProcessor.java
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/netty/process/CollectorOnlineProcessor.java
index 0c54258632..9a7e4f4e08 100644
---
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/netty/process/CollectorOnlineProcessor.java
+++
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/scheduler/netty/process/CollectorOnlineProcessor.java
@@ -17,12 +17,15 @@
package org.apache.hertzbeat.manager.scheduler.netty.process;
+import com.google.protobuf.ByteString;
import io.netty.channel.ChannelHandlerContext;
import java.net.InetSocketAddress;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
+import org.apache.hertzbeat.common.entity.dto.ServerInfo;
import org.apache.hertzbeat.common.entity.message.ClusterMsg;
+import org.apache.hertzbeat.common.util.AesUtil;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.hertzbeat.manager.scheduler.netty.ManageServer;
import org.apache.hertzbeat.remoting.netty.NettyRemotingProcessor;
@@ -52,6 +55,12 @@ public class CollectorOnlineProcessor implements
NettyRemotingProcessor {
}
this.manageServer.addChannel(collector, ctx.channel());
this.manageServer.getCollectorAndJobScheduler().collectorGoOnline(collector,
collectorInfo);
- return null;
+ ServerInfo serverInfo =
ServerInfo.builder().aesSecret(AesUtil.getDefaultSecretKey()).build();
+ return ClusterMsg.Message.newBuilder()
+ .setIdentity(message.getIdentity())
+ .setDirection(ClusterMsg.Direction.RESPONSE)
+ .setMsg(ByteString.copyFromUtf8(JsonUtil.toJson(serverInfo)))
+ .setType(ClusterMsg.MessageType.GO_ONLINE)
+ .build();
}
}
diff --git
a/hertzbeat-remoting/src/main/java/org/apache/hertzbeat/remoting/netty/NettyRemotingAbstract.java
b/hertzbeat-remoting/src/main/java/org/apache/hertzbeat/remoting/netty/NettyRemotingAbstract.java
index a9632d7c40..3d9390f467 100644
---
a/hertzbeat-remoting/src/main/java/org/apache/hertzbeat/remoting/netty/NettyRemotingAbstract.java
+++
b/hertzbeat-remoting/src/main/java/org/apache/hertzbeat/remoting/netty/NettyRemotingAbstract.java
@@ -59,7 +59,7 @@ public abstract class NettyRemotingAbstract implements
RemotingService {
if (ClusterMsg.Direction.REQUEST.equals(message.getDirection())) {
this.processRequestMsg(ctx, message);
} else {
- this.processResponseMsg(message);
+ this.processResponseMsg(ctx, message);
}
}
@@ -86,12 +86,20 @@ public abstract class NettyRemotingAbstract implements
RemotingService {
}
}
- protected void processResponseMsg(ClusterMsg.Message response) {
+ protected void processResponseMsg(ChannelHandlerContext ctx,
ClusterMsg.Message response) {
+ // for sync response
if (this.responseTable.containsKey(response.getIdentity())) {
ResponseFuture responseFuture =
this.responseTable.get(response.getIdentity());
responseFuture.putResponse(response);
} else {
- log.warn("receive response not in responseTable, identity: {}",
response.getIdentity());
+ // async response
+ NettyRemotingProcessor processor =
this.processorTable.get(response.getType());
+ if (processor != null) {
+ ClusterMsg.Message repMessage = processor.handle(ctx,
response);
+ if (repMessage != null) {
+ ctx.writeAndFlush(repMessage);
+ }
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]