mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-16 15:17:14 +00:00
feat(reality): warn when target cert chain is too small for ML-DSA-65 (#6470)
* feat(reality): warn when target cert chain is too small for ML-DSA-65 Expose peer cert-chain DER size from the REALITY scanner and surface a UI warning when ML-DSA-65 is enabled but the chain is under xray-core's 3500-byte minimum, so silent fallback failures are easier to catch. Fixes #5973 * fix(reality): gate scanner ML-DSA tag and sync docs OpenAPI Only warn on short cert chains in the target scanner when ML-DSA-65 is enabled. Copy frontend/public/openapi.json to docs/public/openapi.json and fix oxfmt wrapping in the new test. --------- Co-authored-by: mrchatam <287639636+mrchatam@users.noreply.github.com>
This commit is contained in:
@@ -57,7 +57,10 @@ type RealityScanResult struct {
|
||||
CertValid bool `json:"certValid" example:"true"`
|
||||
// CertChainValid ignores the name: a trusted chain presented for other names
|
||||
// still has serverNames the panel can offer instead of the failing SNI.
|
||||
CertChainValid bool `json:"certChainValid" example:"true"`
|
||||
CertChainValid bool `json:"certChainValid" example:"true"`
|
||||
// CertChainBytes is the sum of DER lengths of the presented peer chain.
|
||||
// xray-core ML-DSA-65 REALITY needs >= 3500 bytes (constant lives in xray-core).
|
||||
CertChainBytes int `json:"certChainBytes" example:"3427"`
|
||||
CertSubject string `json:"certSubject" example:"cloudflare.com"`
|
||||
CertIssuer string `json:"certIssuer" example:"Google Trust Services"`
|
||||
NotAfter string `json:"notAfter" example:"2026-08-01T00:00:00Z"`
|
||||
@@ -253,6 +256,9 @@ func (s *ServerService) probeRealityAddr(dialHost string, port int, sni string,
|
||||
verifyHost := sni
|
||||
if len(st.PeerCertificates) > 0 {
|
||||
leaf := st.PeerCertificates[0]
|
||||
for _, cert := range st.PeerCertificates {
|
||||
res.CertChainBytes += len(cert.Raw)
|
||||
}
|
||||
res.CertSubject = leaf.Subject.CommonName
|
||||
if res.CertSubject == "" && len(leaf.DNSNames) > 0 {
|
||||
res.CertSubject = leaf.DNSNames[0]
|
||||
|
||||
@@ -628,6 +628,8 @@
|
||||
"scanCert": "الشهادة",
|
||||
"scanCertInvalid": "غير موثوق",
|
||||
"scanCertExpiry": "انتهاء صلاحية الشهادة",
|
||||
"scanCertChain": "سلسلة الشهادات",
|
||||
"scanMldsaCertChainTooSmall": "سلسلة شهادات الهدف {length} بايت، وهي أقل من الحد الأدنى {min} بايت المطلوب لـ ML-DSA-65. سيؤدي ذلك إلى فشل الاتصال بصمت. يُرجى اختيار هدف مختلف أو تعطيل ML-DSA-65.",
|
||||
"scanSniUsed": "SNI المستخدم",
|
||||
"scanPrivateNote": "تم الفحص عبر شبكة خاصة/محلية — هذا العنوان غير قابل للوصول من الإنترنت.",
|
||||
"scanPrivateConfirmTitle": "الهدف في شبكة محلية",
|
||||
|
||||
@@ -642,6 +642,8 @@
|
||||
"scanCert": "Certificate",
|
||||
"scanCertInvalid": "Not trusted",
|
||||
"scanCertExpiry": "Certificate expires",
|
||||
"scanCertChain": "Cert chain",
|
||||
"scanMldsaCertChainTooSmall": "Target certificate chain is {length} bytes, which is below the {min}-byte minimum required for ML-DSA-65. This will cause silent connection failures. Please choose a different target or disable ML-DSA-65.",
|
||||
"scanSniUsed": "SNI used",
|
||||
"scanPrivateNote": "Checked over a private/local network — this address is not reachable from the internet.",
|
||||
"scanPrivateConfirmTitle": "Target on a local network",
|
||||
|
||||
@@ -649,6 +649,8 @@
|
||||
"scanCert": "Certificado",
|
||||
"scanCertInvalid": "No confiable",
|
||||
"scanCertExpiry": "El certificado caduca",
|
||||
"scanCertChain": "Cadena de certificados",
|
||||
"scanMldsaCertChainTooSmall": "La cadena de certificados del destino mide {length} bytes, por debajo del mínimo de {min} bytes que requiere ML-DSA-65. Las conexiones fallarán en silencio. Elige otro destino o desactiva ML-DSA-65.",
|
||||
"scanSniUsed": "SNI utilizado",
|
||||
"scanPrivateNote": "Comprobado en una red privada/local: esta dirección no es accesible desde internet.",
|
||||
"scanPrivateConfirmTitle": "Destino en una red local",
|
||||
|
||||
@@ -640,6 +640,8 @@
|
||||
"scanCert": "گواهی",
|
||||
"scanCertInvalid": "نامعتبر",
|
||||
"scanCertExpiry": "انقضای گواهی",
|
||||
"scanCertChain": "زنجیره گواهی",
|
||||
"scanMldsaCertChainTooSmall": "زنجیره گواهی هدف {length} بایت است که کمتر از حداقل {min} بایت مورد نیاز ML-DSA-65 است. این باعث شکست بیصدای اتصال میشود. هدف دیگری انتخاب کنید یا ML-DSA-65 را غیرفعال کنید.",
|
||||
"scanSniUsed": "SNI استفادهشده",
|
||||
"scanPrivateNote": "بررسی از طریق شبکهٔ خصوصی/محلی انجام شد — این نشانی از اینترنت قابل دسترسی نیست.",
|
||||
"scanPrivateConfirmTitle": "هدف در شبکهٔ محلی",
|
||||
|
||||
@@ -628,6 +628,8 @@
|
||||
"scanCert": "Sertifikat",
|
||||
"scanCertInvalid": "Tidak tepercaya",
|
||||
"scanCertExpiry": "Sertifikat kedaluwarsa",
|
||||
"scanCertChain": "Rantai sertifikat",
|
||||
"scanMldsaCertChainTooSmall": "Rantai sertifikat target berukuran {length} byte, di bawah minimum {min} byte yang dibutuhkan ML-DSA-65. Ini akan menyebabkan koneksi gagal tanpa pesan error. Pilih target lain atau nonaktifkan ML-DSA-65.",
|
||||
"scanSniUsed": "SNI yang dipakai",
|
||||
"scanPrivateNote": "Diperiksa melalui jaringan privat/lokal — alamat ini tidak dapat dijangkau dari internet.",
|
||||
"scanPrivateConfirmTitle": "Target di jaringan lokal",
|
||||
|
||||
@@ -649,6 +649,8 @@
|
||||
"scanCert": "証明書",
|
||||
"scanCertInvalid": "信頼できません",
|
||||
"scanCertExpiry": "証明書の有効期限",
|
||||
"scanCertChain": "証明書チェーン",
|
||||
"scanMldsaCertChainTooSmall": "ターゲットの証明書チェーンは {length} バイトで、ML-DSA-65 に必要な下限 {min} バイトを下回っています。接続はエラーなく失敗します。別のターゲットを選ぶか ML-DSA-65 を無効にしてください。",
|
||||
"scanSniUsed": "使用した SNI",
|
||||
"scanPrivateNote": "プライベート/ローカルネットワーク経由で確認しました。このアドレスはインターネットからは到達できません。",
|
||||
"scanPrivateConfirmTitle": "ローカルネットワーク上のターゲット",
|
||||
|
||||
@@ -649,6 +649,8 @@
|
||||
"scanCert": "Certificado",
|
||||
"scanCertInvalid": "Não confiável",
|
||||
"scanCertExpiry": "Certificado expira",
|
||||
"scanCertChain": "Cadeia de certificados",
|
||||
"scanMldsaCertChainTooSmall": "A cadeia de certificados do destino tem {length} bytes, abaixo do mínimo de {min} bytes exigido pelo ML-DSA-65. Isso causará falhas silenciosas de conexão. Escolha outro destino ou desative o ML-DSA-65.",
|
||||
"scanSniUsed": "SNI utilizado",
|
||||
"scanPrivateNote": "Verificado em uma rede privada/local — este endereço não é acessível pela internet.",
|
||||
"scanPrivateConfirmTitle": "Destino em uma rede local",
|
||||
|
||||
@@ -651,6 +651,8 @@
|
||||
"scanCert": "Сертификат",
|
||||
"scanCertInvalid": "Не доверенный",
|
||||
"scanCertExpiry": "Сертификат истекает",
|
||||
"scanCertChain": "Цепочка сертификатов",
|
||||
"scanMldsaCertChainTooSmall": "Цепочка сертификатов цели занимает {length} байт — меньше минимума {min} байт, требуемого для ML-DSA-65. Соединения будут молча уходить в fallback. Выберите другую цель или отключите ML-DSA-65.",
|
||||
"scanSniUsed": "Использованный SNI",
|
||||
"scanPrivateNote": "Проверено во внутренней (локальной) сети — этот адрес недоступен из интернета.",
|
||||
"scanPrivateConfirmTitle": "Цель в локальной сети",
|
||||
|
||||
@@ -628,6 +628,8 @@
|
||||
"scanCert": "Sertifika",
|
||||
"scanCertInvalid": "Güvenilmez",
|
||||
"scanCertExpiry": "Sertifika bitiş tarihi",
|
||||
"scanCertChain": "Sertifika zinciri",
|
||||
"scanMldsaCertChainTooSmall": "Hedef sertifika zinciri {length} bayt; ML-DSA-65 için gereken {min} bayt minimumunun altında. Bu, bağlantıların sessizce başarısız olmasına yol açar. Farklı bir hedef seçin veya ML-DSA-65'i kapatın.",
|
||||
"scanSniUsed": "Kullanılan SNI",
|
||||
"scanPrivateNote": "Özel/yerel ağ üzerinden kontrol edildi — bu adrese internetten erişilemez.",
|
||||
"scanPrivateConfirmTitle": "Hedef yerel ağda",
|
||||
|
||||
@@ -628,6 +628,8 @@
|
||||
"scanCert": "Сертифікат",
|
||||
"scanCertInvalid": "Ненадійний",
|
||||
"scanCertExpiry": "Сертифікат діє до",
|
||||
"scanCertChain": "Ланцюжок сертифікатів",
|
||||
"scanMldsaCertChainTooSmall": "Ланцюжок сертифікатів цілі має {length} байт, що менше мінімуму {min} байт для ML-DSA-65. З’єднання мовчки потраплятимуть у fallback. Оберіть іншу ціль або вимкніть ML-DSA-65.",
|
||||
"scanSniUsed": "Використаний SNI",
|
||||
"scanPrivateNote": "Перевірено у внутрішній (локальній) мережі — ця адреса недоступна з інтернету.",
|
||||
"scanPrivateConfirmTitle": "Ціль у локальній мережі",
|
||||
|
||||
@@ -649,6 +649,8 @@
|
||||
"scanCert": "Chứng chỉ",
|
||||
"scanCertInvalid": "Không tin cậy",
|
||||
"scanCertExpiry": "Chứng chỉ hết hạn",
|
||||
"scanCertChain": "Chuỗi chứng chỉ",
|
||||
"scanMldsaCertChainTooSmall": "Chuỗi chứng chỉ của đích dài {length} byte, thấp hơn mức tối thiểu {min} byte mà ML-DSA-65 yêu cầu. Kết nối sẽ thất bại im lặng. Hãy chọn đích khác hoặc tắt ML-DSA-65.",
|
||||
"scanSniUsed": "SNI đã dùng",
|
||||
"scanPrivateNote": "Đã kiểm tra qua mạng riêng/nội bộ — địa chỉ này không truy cập được từ internet.",
|
||||
"scanPrivateConfirmTitle": "Đích trong mạng nội bộ",
|
||||
|
||||
@@ -648,6 +648,8 @@
|
||||
"scanCert": "证书",
|
||||
"scanCertInvalid": "不受信任",
|
||||
"scanCertExpiry": "证书有效期至",
|
||||
"scanCertChain": "证书链",
|
||||
"scanMldsaCertChainTooSmall": "目标证书链为 {length} 字节,低于 ML-DSA-65 所需的 {min} 字节下限。这会导致连接静默失败。请更换目标或关闭 ML-DSA-65。",
|
||||
"scanSniUsed": "使用的 SNI",
|
||||
"scanPrivateNote": "已通过内网/本地网络检测 — 该地址无法从互联网访问。",
|
||||
"scanPrivateConfirmTitle": "目标位于本地网络",
|
||||
|
||||
@@ -628,6 +628,8 @@
|
||||
"scanCert": "憑證",
|
||||
"scanCertInvalid": "不受信任",
|
||||
"scanCertExpiry": "憑證有效期限",
|
||||
"scanCertChain": "憑證鏈",
|
||||
"scanMldsaCertChainTooSmall": "目標憑證鏈為 {length} 位元組,低於 ML-DSA-65 所需的 {min} 位元組下限。這會導致連線靜默失敗。請更換目標或關閉 ML-DSA-65。",
|
||||
"scanSniUsed": "使用的 SNI",
|
||||
"scanPrivateNote": "已透過內網/本機網路檢測 — 此位址無法從網際網路存取。",
|
||||
"scanPrivateConfirmTitle": "目標位於本機網路",
|
||||
|
||||
Reference in New Issue
Block a user