mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-25 07:15:01 +03:00
feat(sub): make the host "Mihomo X25519" switch drop ML-KEM (#6803)
The per-host Mihomo X25519 switch has been stored since managed hosts landed, but no renderer read it, while every REALITY proxy was forced to support-x25519mlkem768: true. On some networks DPI drops the second segment of an ML-KEM ClientHello and blackholes the server for that client. A host with the switch on now gets support-x25519mlkem768: false and no ML-KEM hint in its vless link; switches saved while they had no effect are cleared once, so upgrading does not silently change existing subscriptions. A REALITY host's fingerprint now reaches the Clash and JSON outputs, and every host endpoint gets its own deep copy of the stream, so one host's blank SNI, fingerprint, Host header or path no longer inherits another host's value.
This commit is contained in:
+18
-1
@@ -428,6 +428,17 @@ func migrateHostVerifyPeerCertByNameColumn() error {
|
||||
return db.Exec(`UPDATE hosts SET verify_peer_cert_by_name = '' WHERE verify_peer_cert_by_name IS NULL OR typeof(verify_peer_cert_by_name) <> 'text'`).Error
|
||||
}
|
||||
|
||||
// mihomo_x25519 was saved but ignored until it began dropping ML-KEM, so rows set
|
||||
// back then are cleared once rather than silently changing their subscriptions.
|
||||
func resetPreexistingMihomoX25519() error {
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&model.Host{}).Where("mihomo_x25519 = ?", true).Update("mihomo_x25519", false).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Create(&model.HistoryOfSeeders{SeederName: "HostMihomoX25519Reset"}).Error
|
||||
})
|
||||
}
|
||||
|
||||
// AutoMigrate casts the boolean-era column to text before the migration above runs,
|
||||
// so a saved false/true reads back as the cert name "0"/"false"/"1"/"true".
|
||||
func blankLegacyBoolVerifyPeerCertByName() error {
|
||||
@@ -1476,7 +1487,7 @@ func runSeeders(isUsersEmpty bool) error {
|
||||
}
|
||||
|
||||
if empty && isUsersEmpty {
|
||||
seeders := []string{"UserPasswordHash", "ClientsTable", "InboundClientsArrayFix", "InboundClientTgIdFix2", "InboundClientSubIdFix", "FreedomFinalRulesReverseFix", "FreedomFinalRulesPrivateEgressBlock", "UppercaseFreedomFinalRulesFix", "InboundRealityFinalmaskTcpStrip", "ApiTokensHash", "LegacyProxySettingsCleanup", "OutboundRemovedKeysFix", "FreedomDomainStrategyFix", "DNSOutboundLegacyKeysFix", "DNSOutboundQTypeZeroFix", "WireguardDomainStrategyFix", "XdnsFinalmaskNamesAddrsFix", "UDPHopClientMaskFix", "HostVerifyPeerCertByNameBoolFix", "WireguardPeersToClients", "MtprotoSecretsToClients", "NodeInboundsAdopted", "NodeDownNotified", "ResetIpLimitNoFail2ban"}
|
||||
seeders := []string{"UserPasswordHash", "ClientsTable", "InboundClientsArrayFix", "InboundClientTgIdFix2", "InboundClientSubIdFix", "FreedomFinalRulesReverseFix", "FreedomFinalRulesPrivateEgressBlock", "UppercaseFreedomFinalRulesFix", "InboundRealityFinalmaskTcpStrip", "ApiTokensHash", "LegacyProxySettingsCleanup", "OutboundRemovedKeysFix", "FreedomDomainStrategyFix", "DNSOutboundLegacyKeysFix", "DNSOutboundQTypeZeroFix", "WireguardDomainStrategyFix", "XdnsFinalmaskNamesAddrsFix", "UDPHopClientMaskFix", "HostVerifyPeerCertByNameBoolFix", "HostMihomoX25519Reset", "WireguardPeersToClients", "MtprotoSecretsToClients", "NodeInboundsAdopted", "NodeDownNotified", "ResetIpLimitNoFail2ban"}
|
||||
for _, name := range seeders {
|
||||
if err := db.Create(&model.HistoryOfSeeders{SeederName: name}).Error; err != nil {
|
||||
return err
|
||||
@@ -1635,6 +1646,12 @@ func runSeeders(isUsersEmpty bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !slices.Contains(seedersHistory, "HostMihomoX25519Reset") {
|
||||
if err := resetPreexistingMihomoX25519(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !slices.Contains(seedersHistory, "NodeInboundsAdopted") {
|
||||
if err := seedNodeInboundsAdopted(); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user