瀏覽代碼

fix(tls): ping the inbound's own port for remote cert pinning

The pin-from-remote button passed only the SNI to 'xray tls ping', which defaults to :443 — so it never reached a self-hosted inbound on another port and failed with a vague 'no certificate hash found'. Append the inbound's port when the SNI carries none, and surface the underlying ping failure (dial refused, timeout) in the error.
MHSanaei 18 小時之前
父節點
當前提交
03e89683dd
共有 2 個文件被更改,包括 15 次插入1 次删除
  1. 6 1
      frontend/src/pages/inbounds/form/useSecurityActions.ts
  2. 9 0
      internal/web/service/server.go

+ 6 - 1
frontend/src/pages/inbounds/form/useSecurityActions.ts

@@ -143,9 +143,14 @@ export function useSecurityActions({ form, setSaving, messageApi, nodeId }: UseS
       messageApi.warning(t('pages.inbounds.form.pinFromRemoteNoSni'));
       return;
     }
+    // `xray tls ping` defaults to :443, but a self-hosted inbound rarely
+    // listens there. Append the inbound's own port (unless the SNI already
+    // carries one) so the ping reaches the actual TLS endpoint.
+    const port = form.getFieldValue('port') as number | undefined;
+    const target = /:\d+$/.test(server) || !port ? server : `${server}:${port}`;
     setSaving(true);
     try {
-      const msg = await HttpUtil.post('/panel/api/server/getRemoteCertHash', { server });
+      const msg = await HttpUtil.post('/panel/api/server/getRemoteCertHash', { server: target });
       if (!msg?.success) {
         messageApi.warning(msg?.msg || t('pages.inbounds.form.pinFromRemoteFailed'));
         return;

+ 9 - 0
internal/web/service/server.go

@@ -1896,6 +1896,15 @@ func (s *ServerService) GetRemoteCertHash(server string) ([]string, error) {
 		}
 	}
 	if len(leaves) == 0 {
+		// Surface why the ping produced no cert (dial refused, timeout, …)
+		// instead of the bare "not found" — the inbound is usually just not
+		// listening for TLS on the pinged port.
+		for _, line := range strings.Split(out.String(), "\n") {
+			line = strings.TrimSpace(line)
+			if strings.Contains(line, "Failed") || strings.Contains(line, "error") {
+				return nil, common.NewError("no certificate hash for ", server, ": ", line)
+			}
+		}
 		return nil, common.NewError("no certificate hash found for ", server)
 	}
 	return leaves, nil