diff --git a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java
index f2d8f7eb02..a0e9fac809 100644
--- a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java
+++ b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImpl.java
@@ -98,6 +98,7 @@ public class EmailAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl
Properties props = sender.getJavaMailProperties();
props.put("mail.smtp.ssl.enable", emailNoticeSenderConfig.isEmailSsl());
props.put("mail.smtp.starttls.enable", emailNoticeSenderConfig.isEmailStarttls());
+ applySslCertVerify(props, emailNoticeSenderConfig.isEmailSslCertVerify());
fromUsername = emailNoticeSenderConfig.getEmailUsername();
useDatabase = true;
}
@@ -111,6 +112,7 @@ public class EmailAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl
Properties props = sender.getJavaMailProperties();
props.put("mail.smtp.ssl.enable", sslEnable);
props.put("mail.smtp.starttls.enable", starttlsEnable);
+ applySslCertVerify(props, true);
}
} catch (Exception e) {
log.error("Type not found {}", e.getMessage());
@@ -133,6 +135,17 @@ public class EmailAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl
}
}
+ // the sender is a singleton, so both branches must set the props to avoid stale state
+ private void applySslCertVerify(Properties props, boolean verify) {
+ if (verify) {
+ props.remove("mail.smtp.ssl.trust");
+ props.remove("mail.smtp.ssl.checkserveridentity");
+ } else {
+ props.put("mail.smtp.ssl.trust", "*");
+ props.put("mail.smtp.ssl.checkserveridentity", "false");
+ }
+ }
+
@Override
public byte type() {
return 1;
diff --git a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java
index 901b27fae5..31fe45fdad 100644
--- a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java
+++ b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/notice/impl/EmailAlertNotifyHandlerImplTest.java
@@ -17,6 +17,8 @@
package org.apache.hertzbeat.alert.notice.impl;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.lenient;
@@ -124,6 +126,40 @@ class EmailAlertNotifyHandlerImplTest {
verify(mailSender).send(any(MimeMessage.class));
}
+ @Test
+ public void testSkipSslCertVerifyTrustsAllHosts() throws Exception {
+ Properties props = stubMailConfig(false);
+ emailAlertNotifyHandler.send(receiver, template, groupAlert);
+ assertEquals("*", props.get("mail.smtp.ssl.trust"));
+ assertEquals("false", props.get("mail.smtp.ssl.checkserveridentity"));
+ }
+
+ @Test
+ public void testEnableSslCertVerifyClearsStaleTrustProps() throws Exception {
+ Properties props = stubMailConfig(true);
+ props.put("mail.smtp.ssl.trust", "*");
+ props.put("mail.smtp.ssl.checkserveridentity", "false");
+ emailAlertNotifyHandler.send(receiver, template, groupAlert);
+ assertNull(props.get("mail.smtp.ssl.trust"));
+ assertNull(props.get("mail.smtp.ssl.checkserveridentity"));
+ }
+
+ private Properties stubMailConfig(boolean sslCertVerify) {
+ MailServerConfig config = new MailServerConfig();
+ config.setEmailHost("smtp.example.com");
+ config.setEmailPort(465);
+ config.setEmailUsername("sender@example.com");
+ config.setEmailPassword("password");
+ config.setEnable(true);
+ config.setEmailSslCertVerify(sslCertVerify);
+ when(generalConfigDao.findByType(any()))
+ .thenReturn(GeneralConfig.builder().content(JsonUtil.toJson(config)).build());
+ Properties props = new Properties();
+ when(mailSender.getJavaMailProperties()).thenReturn(props);
+ when(mailSender.createMimeMessage()).thenReturn(mimeMessage);
+ return props;
+ }
+
@Test
public void testNotifyAlertFailure() {
when(mailSender.createMimeMessage()).thenThrow(new RuntimeException("Test Error"));
diff --git a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java
index 3c99b34ab6..b51b3ea06d 100644
--- a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java
+++ b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/entity/dto/MailServerConfig.java
@@ -56,5 +56,7 @@ public class MailServerConfig {
private boolean emailStarttls = false;
+ private boolean emailSslCertVerify = true;
+
private boolean enable = true;
}
diff --git a/web-app/src/app/pojo/EmailNoticeSender.ts b/web-app/src/app/pojo/EmailNoticeSender.ts
index 9d4ffea819..1a8a1c6788 100644
--- a/web-app/src/app/pojo/EmailNoticeSender.ts
+++ b/web-app/src/app/pojo/EmailNoticeSender.ts
@@ -25,6 +25,7 @@ export class EmailNoticeSender {
emailPassword!: string;
emailSsl: boolean = true;
emailStarttls: boolean = false;
+ emailSslCertVerify: boolean = true;
enable!: boolean;
creator!: string;
modifier!: string;
diff --git a/web-app/src/app/routes/setting/settings/message-server/message-server.component.html b/web-app/src/app/routes/setting/settings/message-server/message-server.component.html
index a804f51547..57290b5203 100644
--- a/web-app/src/app/routes/setting/settings/message-server/message-server.component.html
+++ b/web-app/src/app/routes/setting/settings/message-server/message-server.component.html
@@ -134,6 +134,14 @@
+
+ {{
+ 'alert.notice.sender.mail.ssl-cert-verify' | i18n
+ }}
+
+
+
+
{{ 'common.enable' | i18n }}
diff --git a/web-app/src/assets/i18n/en-US.json b/web-app/src/assets/i18n/en-US.json
index 32ac9d0b7f..0b5c837cc5 100644
--- a/web-app/src/assets/i18n/en-US.json
+++ b/web-app/src/assets/i18n/en-US.json
@@ -147,6 +147,7 @@
"alert.notice.sender.mail.port": "Email Port",
"alert.notice.sender.mail.ssl": "Enable SSL",
"alert.notice.sender.mail.starttls": "Enable STARTTLS",
+ "alert.notice.sender.mail.ssl-cert-verify": "Verify SSL Certificate",
"alert.notice.sender.mail.username": "Email Account",
"alert.notice.sender.sms.tencent.appId": "Tencent Sms AppId",
"alert.notice.sender.sms.tencent.secretId": "Tencent Sms SecretId",
diff --git a/web-app/src/assets/i18n/ja-JP.json b/web-app/src/assets/i18n/ja-JP.json
index dcdcaeef5d..8df517eec8 100644
--- a/web-app/src/assets/i18n/ja-JP.json
+++ b/web-app/src/assets/i18n/ja-JP.json
@@ -146,6 +146,7 @@
"alert.notice.sender.mail.port": "メールポート",
"alert.notice.sender.mail.ssl": "SSLを有効化",
"alert.notice.sender.mail.starttls": "STARTTLSを有効化",
+ "alert.notice.sender.mail.ssl-cert-verify": "SSL証明書を検証",
"alert.notice.sender.mail.username": "メールアカウント",
"alert.notice.sender.sms.tencent.appId": "Tencent Sms AppId",
"alert.notice.sender.sms.tencent.secretId": "Tencent Sms SecretId",
diff --git a/web-app/src/assets/i18n/ko-KR.json b/web-app/src/assets/i18n/ko-KR.json
index 0dd23716b5..1a77de3774 100644
--- a/web-app/src/assets/i18n/ko-KR.json
+++ b/web-app/src/assets/i18n/ko-KR.json
@@ -147,6 +147,7 @@
"alert.notice.sender.mail.port": "이메일 포트",
"alert.notice.sender.mail.ssl": "SSL 활성화",
"alert.notice.sender.mail.starttls": "STARTTLS 활성화",
+ "alert.notice.sender.mail.ssl-cert-verify": "SSL 인증서 검증",
"alert.notice.sender.mail.username": "이메일 계정",
"alert.notice.sender.sms.tencent.appId": "Tencent SMS AppId",
"alert.notice.sender.sms.tencent.secretId": "Tencent SMS SecretId",
diff --git a/web-app/src/assets/i18n/pt-BR.json b/web-app/src/assets/i18n/pt-BR.json
index e8761d9a90..bf2a3e6e36 100644
--- a/web-app/src/assets/i18n/pt-BR.json
+++ b/web-app/src/assets/i18n/pt-BR.json
@@ -233,6 +233,7 @@
"alert.notice.sender.mail.port": "Porta do Email",
"alert.notice.sender.mail.ssl": "Habilitar SSL",
"alert.notice.sender.mail.starttls": "Habilitar STARTTLS",
+ "alert.notice.sender.mail.ssl-cert-verify": "Verificar Certificado SSL",
"alert.notice.sender.mail.enable": "Habilitar Configuração de Email",
"alert.notice.sender.sms.type": "Tipo de SMS",
"alert.notice.sender.sms.type.tencent": "SMS Tencent",
diff --git a/web-app/src/assets/i18n/zh-CN.json b/web-app/src/assets/i18n/zh-CN.json
index 5282863db7..9c1059dbf0 100644
--- a/web-app/src/assets/i18n/zh-CN.json
+++ b/web-app/src/assets/i18n/zh-CN.json
@@ -147,6 +147,7 @@
"alert.notice.sender.mail.port": "邮箱端口",
"alert.notice.sender.mail.ssl": "是否启用SSL",
"alert.notice.sender.mail.starttls": "是否启用STARTTLS",
+ "alert.notice.sender.mail.ssl-cert-verify": "是否校验SSL证书",
"alert.notice.sender.mail.username": "邮箱账号",
"alert.notice.sender.sms.tencent.appId": "腾讯短信AppId",
"alert.notice.sender.sms.tencent.secretId": "腾讯短信SecretId",
diff --git a/web-app/src/assets/i18n/zh-TW.json b/web-app/src/assets/i18n/zh-TW.json
index 239c8375b5..8e4b95974a 100644
--- a/web-app/src/assets/i18n/zh-TW.json
+++ b/web-app/src/assets/i18n/zh-TW.json
@@ -146,6 +146,7 @@
"alert.notice.sender.mail.port": "郵件端口",
"alert.notice.sender.mail.ssl": "是否啟用SSL",
"alert.notice.sender.mail.starttls": "是否啟用STARTTLS",
+ "alert.notice.sender.mail.ssl-cert-verify": "是否校驗SSL證書",
"alert.notice.sender.mail.username": "郵件帳號",
"alert.notice.sender.sms.tencent.appId": "騰訊短訊AppId",
"alert.notice.sender.sms.tencent.secretId": "騰訊短訊SecretId",