feat(tls,reality): port xray TLS/REALITY fields, cert-hash helpers, fallback UX

TLS: add verifyPeerCertByName (vcn) to inbound settings + emit in both share-link generators (frontend + Go sub) and outbound parser; the allowInsecure replacement xray removed after 2026-06-01. Add server-side curvePreferences, masterKeyLog, echSockopt (passthrough + form) at tlsSettings top-level so they survive the panel-only settings strip.

REALITY: add limitFallbackUpload/Download (afterBytes/bytesPerSec/burstBytesPerSec) with per-field tooltips, plus masterKeyLog. Verified field names/semantics against pinned xray v1.260327.1 (bytesPerSec=0 disables).

Hosts: fix verify_peer_cert_by_name column bool->string (xray expects comma-separated names) with an idempotent, history-gate-free migration (SQLite typeof blank; Postgres ALTER once); emit vcn for hosts/external proxies.

Server: add getCertHash (local cert DER SHA-256) and getRemoteCertHash (xray tls ping) endpoints + api-docs; wire pinned-cert field buttons. Drop the meaningless random-hash button.

Xray UI: metrics endpoint (listen/tag) config in Basics; import/export for routing rules and outbounds.

Fallbacks card: compact empty state, header-aligned actions, responsive labeled grid rows.

i18n: add all new keys to every locale; drop unused generateRandomPin.
This commit is contained in:
MHSanaei
2026-06-21 15:51:50 +02:00
parent 315ecc2588
commit 7c8889466b
48 changed files with 1316 additions and 173 deletions
+33 -5
View File
@@ -591,7 +591,6 @@
"pinnedPeerCertSha256": "SHA-256 Sertifikat Peer Tersemat",
"pinnedPeerCertSha256Tip": "Hash SHA-256 dari sertifikat peer sebagai string heksadesimal (mis. e8e2d3…), dipisah koma. Hanya panel — tidak ditulis ke konfig xray server, tetapi disertakan dalam link berbagi agar klien dapat menyematkan sertifikat.",
"pinnedPeerCertSha256Placeholder": "hash heksadesimal, dipisah koma",
"generateRandomPin": "Hasilkan hash acak",
"getNewEchCert": "Dapatkan sertifikat ECH baru",
"show": "Tampilkan",
"xver": "Xver",
@@ -620,7 +619,28 @@
"node": "Alamat node",
"listen": "Alamat listen inbound",
"custom": "Kustom"
}
},
"echSockopt": "ECH Sockopt",
"echSockoptTip": "Opsi socket untuk koneksi yang dipakai Xray guna mengambil daftar konfig ECH (mis. mengarahkan pencarian melalui outbound dialerProxy). Biarkan nonaktif untuk memakai bawaan.",
"curvePreferences": "Preferensi kurva",
"curvePreferencesTip": "Batasi kurva pertukaran kunci TLS yang ditawarkan server, sesuai urutan preferensi (mis. X25519MLKEM768, X25519). Biarkan kosong untuk memakai bawaan Xray-core.",
"masterKeyLog": "Log master key",
"masterKeyLogTip": "Path untuk menulis master key TLS (format SSLKEYLOGFILE) untuk debug dengan Wireshark. Biarkan kosong di produksi — ini memungkinkan siapa pun yang memiliki file tersebut mendekripsi lalu lintas.",
"verifyPeerCertByName": "Verifikasi sertifikat peer berdasarkan nama",
"verifyPeerCertByNameTip": "Minta klien memverifikasi sertifikat server terhadap nama ini, bukan SNI. Nama dipisahkan koma. Hanya panel — disertakan dalam tautan berbagi (vcn). Pengganti modern untuk allowInsecure, yang dihapus Xray setelah 2026-06-01.",
"pinFromCert": "Isi dari sertifikat inbound ini",
"pinFromRemote": "Ambil hash dengan melakukan ping ke SNI (xray tls ping)",
"pinFromRemoteNoSni": "Atur SNI (serverName) terlebih dahulu untuk melakukan ping ke sertifikat jarak jauh.",
"pinFromRemoteFailed": "Tidak dapat mengambil hash sertifikat jarak jauh.",
"limitFallback": "Batasi fallback",
"limitFallbackUpload": "Batasi unggah fallback",
"limitFallbackDownload": "Batasi unduh fallback",
"afterBytes": "Setelah byte",
"afterBytesTip": "Biarkan fallback berjalan pada kecepatan penuh untuk sejumlah byte ini, lalu mulai membatasi. 0 = batasi sejak byte pertama.",
"bytesPerSec": "Byte per detik",
"bytesPerSecTip": "Batas kecepatan (byte/detik) yang diterapkan pada lalu lintas fallback setelah ambang batas, agar probe tidak dapat memakai server Anda sebagai bandwidth gratis menuju target. 0 = tanpa batas (menonaktifkan arah ini).",
"burstBytesPerSec": "Byte per detik burst",
"burstBytesPerSecTip": "Kelonggaran untuk burst singkat di atas laju tetap (ukuran token-bucket). Jika lebih kecil dari Byte per detik, nilainya dinaikkan agar sama."
},
"info": {
"mode": "Mode",
@@ -1338,6 +1358,14 @@
"Inbounds": "Inbound",
"InboundsDesc": "Menerima klien tertentu.",
"Outbounds": "Outbound",
"importRules": "Impor aturan",
"exportRules": "Ekspor aturan",
"importOutbounds": "Impor outbound",
"exportOutbounds": "Ekspor outbound",
"importInvalidJson": "JSON tidak valid — diharapkan berupa array atau objek dengan kunci yang sesuai.",
"metricsListen": "Endpoint metrik",
"metricsListenDesc": "Tampilkan metrik gaya Prometheus dari Xray pada alamat:port ini (mis. 127.0.0.1:11111). Biarkan kosong untuk menonaktifkan. Ikat ke localhost dan reverse-proxy — endpoint ini tanpa autentikasi.",
"metricsTag": "Tag metrik",
"OutboundSubscriptions": "Langganan Outbound",
"OutboundSubscriptionsDesc": "Impor outbound dari URL langganan jarak jauh (vmess/vless/trojan/ss/...). Tag dijaga tetap stabil untuk digunakan pada penyeimbang dan aturan routing. Pembaruan berjalan otomatis.",
"Balancers": "Penyeimbang",
@@ -1729,7 +1757,6 @@
"alpn": "ALPN",
"fingerprint": "Fingerprint",
"pins": "SHA-256 sertifikat tersemat",
"verifyPeerCertByName": "Verifikasi sertifikat peer berdasarkan nama",
"allowInsecure": "Izinkan tidak aman",
"echConfigList": "Daftar konfig ECH",
"muxParams": "Mux",
@@ -1741,7 +1768,8 @@
"shuffleHost": "Acak host",
"tags": "Tag",
"nodeGuids": "Node",
"excludeFromSubTypes": "Kecualikan dari format"
"excludeFromSubTypes": "Kecualikan dari format",
"verifyPeerCertByName": "Verifikasi sertifikat peer berdasarkan nama"
},
"hints": {
"address": "Biarkan kosong untuk mewarisi alamat inbound itu sendiri.",
@@ -2015,4 +2043,4 @@
"statusDown": "MATI",
"statusUp": "AKTIF"
}
}
}