Update On Fri Dec 19 19:41:39 CET 2025

This commit is contained in:
github-action[bot]
2025-12-19 19:41:40 +01:00
parent f649634e7c
commit 095f4a24d3
406 changed files with 14464 additions and 10964 deletions

View File

@@ -10,7 +10,6 @@ import (
"sync"
"github.com/metacubex/mihomo/common/once"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/ntp"
"github.com/metacubex/tls"
@@ -107,12 +106,13 @@ func GetTLSConfig(opt Option) (tlsConfig *tls.Config, err error) {
}
if len(opt.Certificate) > 0 || len(opt.PrivateKey) > 0 {
var cert tls.Certificate
cert, err = LoadTLSKeyPair(opt.Certificate, opt.PrivateKey, C.Path)
certLoader, err := NewTLSKeyPairLoader(opt.Certificate, opt.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetClientCertificate = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
return certLoader()
}
}
return tlsConfig, nil
}

View File

@@ -12,67 +12,80 @@ import (
"fmt"
"math/big"
"os"
"runtime"
"sync"
"time"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/fswatch"
"github.com/metacubex/tls"
)
type Path interface {
Resolve(path string) string
IsSafePath(path string) bool
ErrNotSafePath(path string) error
}
// LoadTLSKeyPair loads a TLS key pair from the provided certificate and private key data or file paths, supporting fallback resolution.
// Returns a tls.Certificate and an error, where the error indicates issues during parsing or file loading.
// NewTLSKeyPairLoader creates a loader function for TLS key pairs from the provided certificate and private key data or file paths.
// If both certificate and privateKey are empty, generates a random TLS RSA key pair.
// Accepts a Path interface for resolving file paths when necessary.
func LoadTLSKeyPair(certificate, privateKey string, path Path) (tls.Certificate, error) {
func NewTLSKeyPairLoader(certificate, privateKey string) (func() (*tls.Certificate, error), error) {
if certificate == "" && privateKey == "" {
var err error
certificate, privateKey, _, err = NewRandomTLSKeyPair(KeyPairTypeRSA)
if err != nil {
return tls.Certificate{}, err
return nil, err
}
}
cert, painTextErr := tls.X509KeyPair([]byte(certificate), []byte(privateKey))
if painTextErr == nil {
return cert, nil
}
if path == nil {
return tls.Certificate{}, painTextErr
return func() (*tls.Certificate, error) {
return &cert, nil
}, nil
}
certificate = path.Resolve(certificate)
privateKey = path.Resolve(privateKey)
certificate = C.Path.Resolve(certificate)
privateKey = C.Path.Resolve(privateKey)
var loadErr error
if !path.IsSafePath(certificate) {
loadErr = path.ErrNotSafePath(certificate)
} else if !path.IsSafePath(privateKey) {
loadErr = path.ErrNotSafePath(privateKey)
if !C.Path.IsSafePath(certificate) {
loadErr = C.Path.ErrNotSafePath(certificate)
} else if !C.Path.IsSafePath(privateKey) {
loadErr = C.Path.ErrNotSafePath(privateKey)
} else {
cert, loadErr = tls.LoadX509KeyPair(certificate, privateKey)
}
if loadErr != nil {
return tls.Certificate{}, fmt.Errorf("parse certificate failed, maybe format error:%s, or path error: %s", painTextErr.Error(), loadErr.Error())
return nil, fmt.Errorf("parse certificate failed, maybe format error:%s, or path error: %s", painTextErr.Error(), loadErr.Error())
}
return cert, nil
gcFlag := new(os.File)
updateMutex := sync.RWMutex{}
if watcher, err := fswatch.NewWatcher(fswatch.Options{Path: []string{certificate, privateKey}, Callback: func(path string) {
updateMutex.Lock()
defer updateMutex.Unlock()
if newCert, err := tls.LoadX509KeyPair(certificate, privateKey); err == nil {
cert = newCert
}
}}); err == nil {
if err = watcher.Start(); err == nil {
runtime.SetFinalizer(gcFlag, func(f *os.File) {
_ = watcher.Close()
})
}
}
return func() (*tls.Certificate, error) {
defer runtime.KeepAlive(gcFlag)
updateMutex.RLock()
defer updateMutex.RUnlock()
return &cert, nil
}, nil
}
func LoadCertificates(certificate string, path Path) (*x509.CertPool, error) {
func LoadCertificates(certificate string) (*x509.CertPool, error) {
pool := x509.NewCertPool()
if pool.AppendCertsFromPEM([]byte(certificate)) {
return pool, nil
}
painTextErr := fmt.Errorf("invalid certificate: %s", certificate)
if path == nil {
return nil, painTextErr
}
certificate = path.Resolve(certificate)
certificate = C.Path.Resolve(certificate)
var loadErr error
if !path.IsSafePath(certificate) {
loadErr = path.ErrNotSafePath(certificate)
if !C.Path.IsSafePath(certificate) {
loadErr = C.Path.ErrNotSafePath(certificate)
} else {
certPEMBlock, err := os.ReadFile(certificate)
if pool.AppendCertsFromPEM(certPEMBlock) {
@@ -83,6 +96,9 @@ func LoadCertificates(certificate string, path Path) (*x509.CertPool, error) {
if loadErr != nil {
return nil, fmt.Errorf("parse certificate failed, maybe format error:%s, or path error: %s", painTextErr.Error(), loadErr.Error())
}
//TODO: support dynamic update pool too
// blocked by: https://github.com/golang/go/issues/64796
// maybe we can direct add `GetRootCAs` and `GetClientCAs` to ourselves tls fork
return pool, nil
}

View File

@@ -8,9 +8,12 @@ import (
"errors"
"fmt"
"os"
"runtime"
"sync"
"github.com/metacubex/mihomo/component/ca"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/fswatch"
"github.com/metacubex/tls"
"golang.org/x/crypto/cryptobyte"
)
@@ -104,40 +107,65 @@ func UnmarshalECHKeys(raw []byte) ([]tls.EncryptedClientHelloKey, error) {
return keys, nil
}
func LoadECHKey(key string, tlsConfig *tls.Config, path ca.Path) error {
func LoadECHKey(key string, tlsConfig *tls.Config) error {
if key == "" {
return nil
}
painTextErr := loadECHKey([]byte(key), tlsConfig)
echKeys, painTextErr := loadECHKey([]byte(key))
if painTextErr == nil {
tlsConfig.GetEncryptedClientHelloKeys = func(info *tls.ClientHelloInfo) ([]tls.EncryptedClientHelloKey, error) {
return echKeys, nil
}
return nil
}
key = path.Resolve(key)
key = C.Path.Resolve(key)
var loadErr error
if !path.IsSafePath(key) {
loadErr = path.ErrNotSafePath(key)
if !C.Path.IsSafePath(key) {
loadErr = C.Path.ErrNotSafePath(key)
} else {
var echKey []byte
echKey, loadErr = os.ReadFile(key)
if loadErr == nil {
loadErr = loadECHKey(echKey, tlsConfig)
echKeys, loadErr = loadECHKey(echKey)
}
}
if loadErr != nil {
return fmt.Errorf("parse ECH keys failed, maybe format error:%s, or path error: %s", painTextErr.Error(), loadErr.Error())
}
gcFlag := new(os.File)
updateMutex := sync.RWMutex{}
if watcher, err := fswatch.NewWatcher(fswatch.Options{Path: []string{key}, Callback: func(path string) {
updateMutex.Lock()
defer updateMutex.Unlock()
if echKey, err := os.ReadFile(key); err == nil {
if newEchKeys, err := loadECHKey(echKey); err == nil {
echKeys = newEchKeys
}
}
}}); err == nil {
if err = watcher.Start(); err == nil {
runtime.SetFinalizer(gcFlag, func(f *os.File) {
_ = watcher.Close()
})
}
}
tlsConfig.GetEncryptedClientHelloKeys = func(info *tls.ClientHelloInfo) ([]tls.EncryptedClientHelloKey, error) {
defer runtime.KeepAlive(gcFlag)
updateMutex.RLock()
defer updateMutex.RUnlock()
return echKeys, nil
}
return nil
}
func loadECHKey(echKey []byte, tlsConfig *tls.Config) error {
func loadECHKey(echKey []byte) ([]tls.EncryptedClientHelloKey, error) {
block, rest := pem.Decode(echKey)
if block == nil || block.Type != "ECH KEYS" || len(rest) > 0 {
return errors.New("invalid ECH keys pem")
return nil, errors.New("invalid ECH keys pem")
}
echKeys, err := UnmarshalECHKeys(block.Bytes)
if err != nil {
return fmt.Errorf("parse ECH keys: %w", err)
return nil, fmt.Errorf("parse ECH keys: %w", err)
}
tlsConfig.EncryptedClientHelloKeys = echKeys
return nil
return echKeys, err
}

View File

@@ -1,7 +1,10 @@
package tls
import (
"context"
"net"
"reflect"
"unsafe"
"github.com/metacubex/mihomo/common/once"
"github.com/metacubex/mihomo/common/utils"
@@ -126,8 +129,11 @@ type EncryptedClientHelloKey = utls.EncryptedClientHelloKey
type Config = utls.Config
var tlsCertificateRequestInfoCtxOffset = utils.MustOK(reflect.TypeOf((*tls.CertificateRequestInfo)(nil)).Elem().FieldByName("ctx")).Offset
var tlsClientHelloInfoCtxOffset = utils.MustOK(reflect.TypeOf((*tls.ClientHelloInfo)(nil)).Elem().FieldByName("ctx")).Offset
func UConfig(config *tls.Config) *utls.Config {
return &utls.Config{
cfg := &utls.Config{
Rand: config.Rand,
Time: config.Time,
Certificates: utils.Map(config.Certificates, UCertificate),
@@ -147,6 +153,52 @@ func UConfig(config *tls.Config) *utls.Config {
SessionTicketsDisabled: config.SessionTicketsDisabled,
Renegotiation: utls.RenegotiationSupport(config.Renegotiation),
}
if config.GetClientCertificate != nil {
cfg.GetClientCertificate = func(info *utls.CertificateRequestInfo) (*utls.Certificate, error) {
tlsInfo := &tls.CertificateRequestInfo{
AcceptableCAs: info.AcceptableCAs,
SignatureSchemes: utils.Map(info.SignatureSchemes, func(it utls.SignatureScheme) tls.SignatureScheme {
return tls.SignatureScheme(it)
}),
Version: info.Version,
}
*(*context.Context)(unsafe.Add(unsafe.Pointer(tlsInfo), tlsCertificateRequestInfoCtxOffset)) = info.Context() // for tlsInfo.ctx
cert, err := config.GetClientCertificate(tlsInfo)
if err != nil {
return nil, err
}
uCert := UCertificate(*cert)
return &uCert, err
}
}
if config.GetCertificate != nil {
cfg.GetCertificate = func(info *utls.ClientHelloInfo) (*utls.Certificate, error) {
tlsInfo := &tls.ClientHelloInfo{
CipherSuites: info.CipherSuites,
ServerName: info.ServerName,
SupportedCurves: utils.Map(info.SupportedCurves, func(it utls.CurveID) tls.CurveID {
return tls.CurveID(it)
}),
SupportedPoints: info.SupportedPoints,
SignatureSchemes: utils.Map(info.SignatureSchemes, func(it utls.SignatureScheme) tls.SignatureScheme {
return tls.SignatureScheme(it)
}),
SupportedProtos: info.SupportedProtos,
SupportedVersions: info.SupportedVersions,
Extensions: info.Extensions,
Conn: info.Conn,
//HelloRetryRequest: info.HelloRetryRequest,
}
*(*context.Context)(unsafe.Add(unsafe.Pointer(tlsInfo), tlsClientHelloInfoCtxOffset)) = info.Context() // for tlsInfo.ctx
cert, err := config.GetCertificate(tlsInfo)
if err != nil {
return nil, err
}
uCert := UCertificate(*cert)
return &uCert, err
}
}
return cfg
}
// BuildWebsocketHandshakeState it will only send http/1.1 in its ALPN.

View File

@@ -1292,7 +1292,7 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rulePro
}
kLower := strings.ToLower(k)
if strings.Contains(kLower, ",") {
if strings.Contains(kLower, "geosite:") {
if strings.HasPrefix(kLower, "geosite:") {
subkeys := strings.Split(k, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
@@ -1300,7 +1300,7 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rulePro
newKey := "geosite:" + subkey
policy = append(policy, dns.Policy{Domain: newKey, NameServers: nameservers})
}
} else if strings.Contains(kLower, "rule-set:") {
} else if strings.HasPrefix(kLower, "rule-set:") {
subkeys := strings.Split(k, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
@@ -1315,9 +1315,9 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rulePro
}
}
} else {
if strings.Contains(kLower, "geosite:") {
if strings.HasPrefix(kLower, "geosite:") {
policy = append(policy, dns.Policy{Domain: "geosite:" + k[8:], NameServers: nameservers})
} else if strings.Contains(kLower, "rule-set:") {
} else if strings.HasPrefix(kLower, "rule-set:") {
policy = append(policy, dns.Policy{Domain: "rule-set:" + k[9:], NameServers: nameservers})
} else {
policy = append(policy, dns.Policy{Domain: k, NameServers: nameservers})
@@ -1712,7 +1712,7 @@ func parseSniffer(snifferRaw RawSniffer, ruleProviders map[string]P.RuleProvider
}
snifferConfig.SkipSrcAddress = skipSrcAddress
skipDstAddress, err := parseIPCIDR(snifferRaw.SkipDstAddress, nil, "sniffer.skip-src-address", ruleProviders)
skipDstAddress, err := parseIPCIDR(snifferRaw.SkipDstAddress, nil, "sniffer.skip-dst-address", ruleProviders)
if err != nil {
return nil, fmt.Errorf("error in skip-dst-address, error:%w", err)
}
@@ -1731,7 +1731,7 @@ func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string
var matcher C.IpMatcher
for _, ipcidr := range addresses {
ipcidrLower := strings.ToLower(ipcidr)
if strings.Contains(ipcidrLower, "geoip:") {
if strings.HasPrefix(ipcidrLower, "geoip:") {
subkeys := strings.Split(ipcidr, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
@@ -1742,7 +1742,7 @@ func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string
}
matchers = append(matchers, matcher)
}
} else if strings.Contains(ipcidrLower, "rule-set:") {
} else if strings.HasPrefix(ipcidrLower, "rule-set:") {
subkeys := strings.Split(ipcidr, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
@@ -1778,7 +1778,7 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapte
var matcher C.DomainMatcher
for _, domain := range domains {
domainLower := strings.ToLower(domain)
if strings.Contains(domainLower, "geosite:") {
if strings.HasPrefix(domainLower, "geosite:") {
subkeys := strings.Split(domain, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
@@ -1789,7 +1789,7 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapte
}
matchers = append(matchers, matcher)
}
} else if strings.Contains(domainLower, "rule-set:") {
} else if strings.HasPrefix(domainLower, "rule-set:") {
subkeys := strings.Split(domain, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")

View File

@@ -191,7 +191,7 @@ func startTLS(cfg *Config) {
// handle tlsAddr
if len(cfg.TLSAddr) > 0 {
cert, err := ca.LoadTLSKeyPair(cfg.Certificate, cfg.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(cfg.Certificate, cfg.PrivateKey)
if err != nil {
log.Errorln("External controller tls listen error: %s", err)
return
@@ -206,7 +206,9 @@ func startTLS(cfg *Config) {
log.Infoln("RESTful API tls listening at: %s", l.Addr().String())
tlsConfig := &tls.Config{Time: ntp.Now}
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
tlsConfig.ClientAuth = ca.ClientAuthTypeFromString(cfg.ClientAuthType)
if len(cfg.ClientAuthCert) > 0 {
if tlsConfig.ClientAuth == tls.NoClientCert {
@@ -214,7 +216,7 @@ func startTLS(cfg *Config) {
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(cfg.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(cfg.ClientAuthCert)
if err != nil {
log.Errorln("External controller tls listen error: %s", err)
return
@@ -223,7 +225,7 @@ func startTLS(cfg *Config) {
}
if cfg.EchKey != "" {
err = ech.LoadECHKey(cfg.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(cfg.EchKey, tlsConfig)
if err != nil {
log.Errorln("External controller tls serve error: %s", err)
return

View File

@@ -45,14 +45,16 @@ func New(config LC.AnyTLSServer, tunnel C.Tunnel, additions ...inbound.Addition)
tlsConfig := &tls.Config{Time: ntp.Now}
if config.Certificate != "" && config.PrivateKey != "" {
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}
@@ -65,7 +67,7 @@ func New(config LC.AnyTLSServer, tunnel C.Tunnel, additions ...inbound.Addition)
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
@@ -108,7 +110,7 @@ func New(config LC.AnyTLSServer, tunnel C.Tunnel, additions ...inbound.Addition)
if err != nil {
return nil, err
}
if len(tlsConfig.Certificates) > 0 {
if tlsConfig.GetCertificate != nil {
l = tls.NewListener(l, tlsConfig)
} else {
return nil, errors.New("disallow using AnyTLS without certificates config")

View File

@@ -71,14 +71,16 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
var realityBuilder *reality.Builder
if config.Certificate != "" && config.PrivateKey != "" {
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}
@@ -91,14 +93,14 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
tlsConfig.ClientCAs = pool
}
if config.RealityConfig.PrivateKey != "" {
if tlsConfig.Certificates != nil {
if tlsConfig.GetCertificate != nil {
return nil, errors.New("certificate is unavailable in reality")
}
if tlsConfig.ClientAuth != tls.NoClientCert {
@@ -112,7 +114,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
if realityBuilder != nil {
l = realityBuilder.NewListener(l)
} else if len(tlsConfig.Certificates) > 0 {
} else if tlsConfig.GetCertificate != nil {
l = tls.NewListener(l, tlsConfig)
}

View File

@@ -67,14 +67,16 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
var realityBuilder *reality.Builder
if config.Certificate != "" && config.PrivateKey != "" {
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}
@@ -87,14 +89,14 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
tlsConfig.ClientCAs = pool
}
if config.RealityConfig.PrivateKey != "" {
if tlsConfig.Certificates != nil {
if tlsConfig.GetCertificate != nil {
return nil, errors.New("certificate is unavailable in reality")
}
if tlsConfig.ClientAuth != tls.NoClientCert {
@@ -108,7 +110,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
if realityBuilder != nil {
l = realityBuilder.NewListener(l)
} else if len(tlsConfig.Certificates) > 0 {
} else if tlsConfig.GetCertificate != nil {
l = tls.NewListener(l, tlsConfig)
}

View File

@@ -56,15 +56,17 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
sl = &Listener{false, config, nil, nil}
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
if err != nil {
return nil, err
}
tlsConfig := &tls.Config{
Time: ntp.Now,
MinVersion: tls.VersionTLS13,
}
tlsConfig.Certificates = []tls.Certificate{cert}
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
tlsConfig.ClientAuth = ca.ClientAuthTypeFromString(config.ClientAuthType)
if len(config.ClientAuthCert) > 0 {
if tlsConfig.ClientAuth == tls.NoClientCert {
@@ -72,7 +74,7 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
@@ -80,7 +82,7 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}

View File

@@ -81,14 +81,16 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
var httpServer http.Server
if config.Certificate != "" && config.PrivateKey != "" {
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}
@@ -101,14 +103,14 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
tlsConfig.ClientCAs = pool
}
if config.RealityConfig.PrivateKey != "" {
if tlsConfig.Certificates != nil {
if tlsConfig.GetCertificate != nil {
return nil, errors.New("certificate is unavailable in reality")
}
if tlsConfig.ClientAuth != tls.NoClientCert {
@@ -153,7 +155,7 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
}
if realityBuilder != nil {
l = realityBuilder.NewListener(l)
} else if len(tlsConfig.Certificates) > 0 {
} else if tlsConfig.GetCertificate != nil {
l = tls.NewListener(l, tlsConfig)
} else if sl.decryption == nil {
return nil, errors.New("disallow using Vless without any certificates/reality/decryption config")

View File

@@ -81,14 +81,16 @@ func New(config LC.VmessServer, tunnel C.Tunnel, additions ...inbound.Addition)
var httpServer http.Server
if config.Certificate != "" && config.PrivateKey != "" {
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}
@@ -101,14 +103,14 @@ func New(config LC.VmessServer, tunnel C.Tunnel, additions ...inbound.Addition)
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
tlsConfig.ClientCAs = pool
}
if config.RealityConfig.PrivateKey != "" {
if tlsConfig.Certificates != nil {
if tlsConfig.GetCertificate != nil {
return nil, errors.New("certificate is unavailable in reality")
}
if tlsConfig.ClientAuth != tls.NoClientCert {
@@ -153,7 +155,7 @@ func New(config LC.VmessServer, tunnel C.Tunnel, additions ...inbound.Addition)
}
if realityBuilder != nil {
l = realityBuilder.NewListener(l)
} else if len(tlsConfig.Certificates) > 0 {
} else if tlsConfig.GetCertificate != nil {
l = tls.NewListener(l, tlsConfig)
}
sl.listeners = append(sl.listeners, l)

View File

@@ -66,14 +66,16 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
var realityBuilder *reality.Builder
if config.Certificate != "" && config.PrivateKey != "" {
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}
@@ -86,14 +88,14 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
tlsConfig.ClientCAs = pool
}
if config.RealityConfig.PrivateKey != "" {
if tlsConfig.Certificates != nil {
if tlsConfig.GetCertificate != nil {
return nil, errors.New("certificate is unavailable in reality")
}
if tlsConfig.ClientAuth != tls.NoClientCert {
@@ -107,7 +109,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
if realityBuilder != nil {
l = realityBuilder.NewListener(l)
} else if len(tlsConfig.Certificates) > 0 {
} else if tlsConfig.GetCertificate != nil {
l = tls.NewListener(l, tlsConfig)
}

View File

@@ -76,14 +76,16 @@ func New(config LC.TrojanServer, tunnel C.Tunnel, additions ...inbound.Addition)
var httpServer http.Server
if config.Certificate != "" && config.PrivateKey != "" {
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}
@@ -96,14 +98,14 @@ func New(config LC.TrojanServer, tunnel C.Tunnel, additions ...inbound.Addition)
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
tlsConfig.ClientCAs = pool
}
if config.RealityConfig.PrivateKey != "" {
if tlsConfig.Certificates != nil {
if tlsConfig.GetCertificate != nil {
return nil, errors.New("certificate is unavailable in reality")
}
if tlsConfig.ClientAuth != tls.NoClientCert {
@@ -148,7 +150,7 @@ func New(config LC.TrojanServer, tunnel C.Tunnel, additions ...inbound.Addition)
}
if realityBuilder != nil {
l = realityBuilder.NewListener(l)
} else if len(tlsConfig.Certificates) > 0 {
} else if tlsConfig.GetCertificate != nil {
l = tls.NewListener(l, tlsConfig)
} else if !config.TrojanSSOption.Enabled {
return nil, errors.New("disallow using Trojan without both certificates/reality/ss config")

View File

@@ -49,15 +49,17 @@ func New(config LC.TuicServer, tunnel C.Tunnel, additions ...inbound.Addition) (
return nil, err
}
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
if err != nil {
return nil, err
}
tlsConfig := &tls.Config{
Time: ntp.Now,
MinVersion: tls.VersionTLS13,
}
tlsConfig.Certificates = []tls.Certificate{cert}
certLoader, err := ca.NewTLSKeyPairLoader(config.Certificate, config.PrivateKey)
if err != nil {
return nil, err
}
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return certLoader()
}
tlsConfig.ClientAuth = ca.ClientAuthTypeFromString(config.ClientAuthType)
if len(config.ClientAuthCert) > 0 {
if tlsConfig.ClientAuth == tls.NoClientCert {
@@ -65,7 +67,7 @@ func New(config LC.TuicServer, tunnel C.Tunnel, additions ...inbound.Addition) (
}
}
if tlsConfig.ClientAuth == tls.VerifyClientCertIfGiven || tlsConfig.ClientAuth == tls.RequireAndVerifyClientCert {
pool, err := ca.LoadCertificates(config.ClientAuthCert, C.Path)
pool, err := ca.LoadCertificates(config.ClientAuthCert)
if err != nil {
return nil, err
}
@@ -73,7 +75,7 @@ func New(config LC.TuicServer, tunnel C.Tunnel, additions ...inbound.Addition) (
}
if config.EchKey != "" {
err = ech.LoadECHKey(config.EchKey, tlsConfig, C.Path)
err = ech.LoadECHKey(config.EchKey, tlsConfig)
if err != nil {
return nil, err
}