Repository: apache/hertzbeat (language: java)

Issue:
The SSL certificate generated by Linux cannot be detected
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

Linux 自己生成的SSL证书无法检测

### Expected Behavior

Linux 自己生成的SSL证书可以进行检测

### Steps To Reproduce

Linux Docker 环境部署，正常去配置域名证书，报错了

### Environment

```markdown
Linux Docker 环境
```


### Debug logs

![2c1457b9682a6fe9b494f1a19d60253](https://github.com/dromara/hertzbeat/assets/18541722/ca401063-0302-4c93-84c5-46a5165d3d49)


### Anything else?

No


Discussion / hints:

Fix patch:
diff --git a/collector/src/main/java/org/apache/hertzbeat/collector/collect/http/SslCertificateCollectImpl.java b/collector/src/main/java/org/apache/hertzbeat/collector/collect/http/SslCertificateCollectImpl.java
index aaa818693bf..36141ddc30e 100644
--- a/collector/src/main/java/org/apache/hertzbeat/collector/collect/http/SslCertificateCollectImpl.java
+++ b/collector/src/main/java/org/apache/hertzbeat/collector/collect/http/SslCertificateCollectImpl.java
@@ -23,12 +23,17 @@
 import java.net.ConnectException;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.Date;
 import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.collector.collect.AbstractCollect;
 import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
@@ -81,6 +86,14 @@ public void collect(CollectRep.MetricsData.Builder builder,
                 uri = "https://" + httpProtocol.getHost() + ":" + httpProtocol.getPort();
             }
             urlConnection = (HttpsURLConnection) new URL(uri).openConnection();
+
+            boolean verifySsl = Boolean.parseBoolean(httpProtocol.getSsl());
+            // ignore ssl verify
+            if (!verifySsl){
+                SSLContext ignoreSslContext = createIgnoreVerifySslContext();
+                urlConnection.setSSLSocketFactory(ignoreSslContext.getSocketFactory());
+            }
+
             urlConnection.connect();
             Certificate[] certificates = urlConnection.getServerCertificates();
             if (certificates == null || certificates.length == 0) {
@@ -160,4 +173,29 @@ public String supportProtocol() {
     private void validateParams(Metrics metrics) {
 
     }
+
+    public SSLContext createIgnoreVerifySslContext() throws NoSuchAlgorithmException, KeyManagementException {
+        SSLContext sc = SSLContext.getInstance("TLS");
+        X509TrustManager trustManager = new X509TrustManager() {
+            @Override
+            public void checkClientTrusted(
+                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
+                    String paramString) {
+            }
+
+            @Override
+            public void checkServerTrusted(
+                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
+                    String paramString) {
+            }
+
+            @Override
+            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+                return null;
+            }
+        };
+
+        sc.init(null, new TrustManager[]{trustManager}, null);
+        return sc;
+    }
 }
diff --git a/manager/src/main/resources/define/app-ssl_cert.yml b/manager/src/main/resources/define/app-ssl_cert.yml
index d48406a6700..9a2694380df 100644
--- a/manager/src/main/resources/define/app-ssl_cert.yml
+++ b/manager/src/main/resources/define/app-ssl_cert.yml
@@ -56,6 +56,17 @@ params:
     # default value
     defaultValue: 443
   # field-param field key
+  - field: verify
+    # name-param field display i18n name
+    name:
+      zh-CN: 校验证书
+      en-US: verify
+    # When the type is boolean, the frontend will display a switch for it.
+    type: boolean
+    defaultValue: true
+    # required-true or false
+    required: false
+  # field-param field key
   - field: uri
     # name-param field display i18n name
     name:
@@ -140,3 +151,4 @@ metrics:
       host: ^_^host^_^
       port: ^_^port^_^
       url: ^_^uri^_^
+      ssl: ^_^verify^_^


Test patch: