fix(nodes): apply a rotated master mTLS certificate without restarting the panel (#6194)

* fix(mtls): invalidate pooled clients after credential rotation

* fix(mtls): make connection reload read-only

---------

Co-authored-by: n0ctal <293235942+n0ctal@users.noreply.github.com>
This commit is contained in:
n0ctal
2026-08-15 19:03:42 +05:00
committed by GitHub
parent 1230559e69
commit 7ecd88b9e3
24 changed files with 747 additions and 101 deletions
+18
View File
@@ -1,11 +1,13 @@
package service
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"strings"
"github.com/mhsanaei/3x-ui/v3/internal/util/common"
"github.com/mhsanaei/3x-ui/v3/internal/web/runtime"
)
// NodeMtlsCaCert returns the PEM of this panel's node-auth CA certificate (the
@@ -24,6 +26,22 @@ func (s *NodeService) NodeMtlsCaCert() (string, error) {
return string(ca.CertPEM), nil
}
// ReloadMasterMtlsClient validates the master credential currently stored by
// the panel and drops cached mTLS connection pools. This makes an intentional
// out-of-process credential rotation take effect without restarting x-ui (and
// therefore without stopping the xray child process in the same service).
func (s *NodeService) ReloadMasterMtlsClient() error {
stored, err := (&SettingService{}).LoadMasterClientCert()
if err != nil {
return err
}
if _, err := tls.X509KeyPair(stored.CertPEM, stored.KeyPEM); err != nil {
return err
}
runtime.InvalidateMasterClientConnections()
return nil
}
// SetNodeMtlsTrustCA stores the CA certificate this panel trusts for incoming
// node-API client certificates. An empty value clears it (mTLS off). A
// non-empty value must be a PEM certificate (fail closed). Takes effect on the