feat: add tls.ech-key for external-controller-tls

This commit is contained in:
wwqgtxx 2025-05-17 21:21:02 +08:00
parent a1350d4985
commit 188372cb04
4 changed files with 31 additions and 7 deletions

View File

@ -174,6 +174,7 @@ type Profile struct {
type TLS struct {
Certificate string
PrivateKey string
EchKey string
CustomTrustCert []string
}
@ -360,6 +361,7 @@ type RawSniffingConfig struct {
type RawTLS struct {
Certificate string `yaml:"certificate" json:"certificate"`
PrivateKey string `yaml:"private-key" json:"private-key"`
EchKey string `yaml:"ech-key" json:"ech-key"`
CustomTrustCert []string `yaml:"custom-certifactes" json:"custom-certifactes"`
}
@ -814,6 +816,7 @@ func parseTLS(cfg *RawConfig) (*TLS, error) {
return &TLS{
Certificate: cfg.TLS.Certificate,
PrivateKey: cfg.TLS.PrivateKey,
EchKey: cfg.TLS.EchKey,
CustomTrustCert: cfg.TLS.CustomTrustCert,
}, nil
}

View File

@ -48,6 +48,13 @@ ipv6: true # 开启 IPv6 总开关,关闭阻断所有 IPv6 链接和屏蔽 DNS
tls:
certificate: string # 证书 PEM 格式,或者 证书的路径
private-key: string # 证书对应的私钥 PEM 格式,或者私钥路径
# 如果填写则开启ech可由 mihomo generate ech-keypair <明文域名> 生成)
# ech-key: |
# -----BEGIN ECH KEYS-----
# ACATwY30o/RKgD6hgeQxwrSiApLaCgU+HKh7B6SUrAHaDwBD/g0APwAAIAAgHjzK
# madSJjYQIf9o1N5GXjkW4DEEeb17qMxHdwMdNnwADAABAAEAAQACAAEAAwAIdGVz
# dC5jb20AAA==
# -----END ECH KEYS-----
custom-certifactes:
- |
-----BEGIN CERTIFICATE-----

View File

@ -57,6 +57,7 @@ func applyRoute(cfg *config.Config) {
Secret: cfg.Controller.Secret,
Certificate: cfg.TLS.Certificate,
PrivateKey: cfg.TLS.PrivateKey,
EchKey: cfg.TLS.EchKey,
DohServer: cfg.Controller.ExternalDohServer,
IsDebug: cfg.General.LogLevel == log.DEBUG,
Cors: route.Cors{

View File

@ -3,7 +3,6 @@ package route
import (
"bytes"
"crypto/subtle"
"crypto/tls"
"encoding/json"
"net"
"net/http"
@ -17,6 +16,8 @@ import (
"github.com/metacubex/mihomo/adapter/inbound"
"github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/component/ca"
"github.com/metacubex/mihomo/component/ech"
tlsC "github.com/metacubex/mihomo/component/tls"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log"
"github.com/metacubex/mihomo/tunnel/statistic"
@ -27,6 +28,8 @@ import (
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
"github.com/sagernet/cors"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
var (
@ -62,6 +65,7 @@ type Config struct {
Secret string
Certificate string
PrivateKey string
EchKey string
DohServer string
IsDebug bool
Cors Cors
@ -186,7 +190,7 @@ func startTLS(cfg *Config) {
// handle tlsAddr
if len(cfg.TLSAddr) > 0 {
c, err := ca.LoadTLSKeyPair(cfg.Certificate, cfg.PrivateKey, C.Path)
cert, err := ca.LoadTLSKeyPair(cfg.Certificate, cfg.PrivateKey, C.Path)
if err != nil {
log.Errorln("External controller tls listen error: %s", err)
return
@ -199,14 +203,23 @@ func startTLS(cfg *Config) {
}
log.Infoln("RESTful API tls listening at: %s", l.Addr().String())
tlsConfig := &tlsC.Config{}
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
tlsConfig.Certificates = []tlsC.Certificate{tlsC.UCertificate(cert)}
if cfg.EchKey != "" {
err = ech.LoadECHKey(cfg.EchKey, tlsConfig, C.Path)
if err != nil {
log.Errorln("External controller tls serve error: %s", err)
return
}
}
server := &http.Server{
Handler: router(cfg.IsDebug, cfg.Secret, cfg.DohServer, cfg.Cors),
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{c},
},
// using h2c.NewHandler to ensure we can work in plain http2 and some tls conn is not *tls.Conn
Handler: h2c.NewHandler(router(cfg.IsDebug, cfg.Secret, cfg.DohServer, cfg.Cors), &http2.Server{}),
}
tlsServer = server
if err = server.ServeTLS(l, "", ""); err != nil {
if err = server.Serve(tlsC.NewListener(l, tlsConfig)); err != nil {
log.Errorln("External controller tls serve error: %s", err)
}
}