mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 11:36:21 +08:00
feat: support external-controller-unix
This commit is contained in:
parent
d84f88b50f
commit
ca84ab1a94
@ -91,10 +91,11 @@ type Inbound struct {
|
|||||||
|
|
||||||
// Controller config
|
// Controller config
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
ExternalController string `json:"-"`
|
ExternalController string `json:"-"`
|
||||||
ExternalControllerTLS string `json:"-"`
|
ExternalControllerTLS string `json:"-"`
|
||||||
ExternalUI string `json:"-"`
|
ExternalControllerUnix string `json:"-"`
|
||||||
Secret string `json:"-"`
|
ExternalUI string `json:"-"`
|
||||||
|
Secret string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NTP config
|
// NTP config
|
||||||
@ -304,6 +305,7 @@ type RawConfig struct {
|
|||||||
LogLevel log.LogLevel `yaml:"log-level" json:"log-level"`
|
LogLevel log.LogLevel `yaml:"log-level" json:"log-level"`
|
||||||
IPv6 bool `yaml:"ipv6" json:"ipv6"`
|
IPv6 bool `yaml:"ipv6" json:"ipv6"`
|
||||||
ExternalController string `yaml:"external-controller"`
|
ExternalController string `yaml:"external-controller"`
|
||||||
|
ExternalControllerUnix string `yaml:"external-controller-unix"`
|
||||||
ExternalControllerTLS string `yaml:"external-controller-tls"`
|
ExternalControllerTLS string `yaml:"external-controller-tls"`
|
||||||
ExternalUI string `yaml:"external-ui"`
|
ExternalUI string `yaml:"external-ui"`
|
||||||
ExternalUIURL string `yaml:"external-ui-url" json:"external-ui-url"`
|
ExternalUIURL string `yaml:"external-ui-url" json:"external-ui-url"`
|
||||||
@ -678,10 +680,11 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
|||||||
InboundMPTCP: cfg.InboundMPTCP,
|
InboundMPTCP: cfg.InboundMPTCP,
|
||||||
},
|
},
|
||||||
Controller: Controller{
|
Controller: Controller{
|
||||||
ExternalController: cfg.ExternalController,
|
ExternalController: cfg.ExternalController,
|
||||||
ExternalUI: cfg.ExternalUI,
|
ExternalUI: cfg.ExternalUI,
|
||||||
Secret: cfg.Secret,
|
Secret: cfg.Secret,
|
||||||
ExternalControllerTLS: cfg.ExternalControllerTLS,
|
ExternalControllerUnix: cfg.ExternalControllerUnix,
|
||||||
|
ExternalControllerTLS: cfg.ExternalControllerTLS,
|
||||||
},
|
},
|
||||||
UnifiedDelay: cfg.UnifiedDelay,
|
UnifiedDelay: cfg.UnifiedDelay,
|
||||||
Mode: cfg.Mode,
|
Mode: cfg.Mode,
|
||||||
|
@ -58,6 +58,11 @@ external-controller: 0.0.0.0:9093 # RESTful API 监听地址
|
|||||||
external-controller-tls: 0.0.0.0:9443 # RESTful API HTTPS 监听地址,需要配置 tls 部分配置文件
|
external-controller-tls: 0.0.0.0:9443 # RESTful API HTTPS 监听地址,需要配置 tls 部分配置文件
|
||||||
# secret: "123456" # `Authorization:Bearer ${secret}`
|
# secret: "123456" # `Authorization:Bearer ${secret}`
|
||||||
|
|
||||||
|
# RESTful API Unix socket 监听地址( windows版本大于17063也可以使用,即大于等于1803/RS4版本即可使用 )
|
||||||
|
# !!!注意: 从Unix socket访问api接口不会验证secret, 如果开启请自行保证安全问题 !!!
|
||||||
|
# 测试方法: curl -v --unix-socket "mihomo.sock" http://localhost/
|
||||||
|
external-controller-unix: mihomo.sock
|
||||||
|
|
||||||
# tcp-concurrent: true # TCP 并发连接所有 IP, 将使用最快握手的 TCP
|
# tcp-concurrent: true # TCP 并发连接所有 IP, 将使用最快握手的 TCP
|
||||||
|
|
||||||
# 配置 WEB UI 目录,使用 http://{{external-controller}}/ui 访问
|
# 配置 WEB UI 目录,使用 http://{{external-controller}}/ui 访问
|
||||||
|
@ -47,6 +47,10 @@ func Parse(options ...Option) error {
|
|||||||
cfg.General.Secret, cfg.TLS.Certificate, cfg.TLS.PrivateKey, cfg.General.LogLevel == log.DEBUG)
|
cfg.General.Secret, cfg.TLS.Certificate, cfg.TLS.PrivateKey, cfg.General.LogLevel == log.DEBUG)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.General.ExternalControllerUnix != "" {
|
||||||
|
go route.StartUnix(cfg.General.ExternalControllerUnix, cfg.General.LogLevel == log.DEBUG)
|
||||||
|
}
|
||||||
|
|
||||||
executor.ApplyConfig(cfg, true)
|
executor.ApplyConfig(cfg, true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/adapter/inbound"
|
"github.com/metacubex/mihomo/adapter/inbound"
|
||||||
@ -47,15 +48,7 @@ func SetUIPath(path string) {
|
|||||||
uiPath = C.Path.Resolve(path)
|
uiPath = C.Path.Resolve(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(addr string, tlsAddr string, secret string,
|
func router(isDebug bool, withAuth bool) *chi.Mux {
|
||||||
certificat, privateKey string, isDebug bool) {
|
|
||||||
if serverAddr != "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
serverAddr = addr
|
|
||||||
serverSecret = secret
|
|
||||||
|
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
corsM := cors.New(cors.Options{
|
corsM := cors.New(cors.Options{
|
||||||
AllowedOrigins: []string{"*"},
|
AllowedOrigins: []string{"*"},
|
||||||
@ -77,7 +70,9 @@ func Start(addr string, tlsAddr string, secret string,
|
|||||||
}())
|
}())
|
||||||
}
|
}
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(authentication)
|
if withAuth {
|
||||||
|
r.Use(authentication)
|
||||||
|
}
|
||||||
r.Get("/", hello)
|
r.Get("/", hello)
|
||||||
r.Get("/logs", getLogs)
|
r.Get("/logs", getLogs)
|
||||||
r.Get("/traffic", traffic)
|
r.Get("/traffic", traffic)
|
||||||
@ -107,10 +102,21 @@ func Start(addr string, tlsAddr string, secret string,
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func Start(addr string, tlsAddr string, secret string,
|
||||||
|
certificate, privateKey string, isDebug bool) {
|
||||||
|
if serverAddr != "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
serverAddr = addr
|
||||||
|
serverSecret = secret
|
||||||
|
|
||||||
if len(tlsAddr) > 0 {
|
if len(tlsAddr) > 0 {
|
||||||
go func() {
|
go func() {
|
||||||
c, err := CN.ParseCert(certificat, privateKey, C.Path)
|
c, err := CN.ParseCert(certificate, privateKey, C.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("External controller tls listen error: %s", err)
|
log.Errorln("External controller tls listen error: %s", err)
|
||||||
return
|
return
|
||||||
@ -125,7 +131,7 @@ func Start(addr string, tlsAddr string, secret string,
|
|||||||
serverAddr = l.Addr().String()
|
serverAddr = l.Addr().String()
|
||||||
log.Infoln("RESTful API tls listening at: %s", serverAddr)
|
log.Infoln("RESTful API tls listening at: %s", serverAddr)
|
||||||
tlsServe := &http.Server{
|
tlsServe := &http.Server{
|
||||||
Handler: r,
|
Handler: router(isDebug, true),
|
||||||
TLSConfig: &tls.Config{
|
TLSConfig: &tls.Config{
|
||||||
Certificates: []tls.Certificate{c},
|
Certificates: []tls.Certificate{c},
|
||||||
},
|
},
|
||||||
@ -144,12 +150,35 @@ func Start(addr string, tlsAddr string, secret string,
|
|||||||
serverAddr = l.Addr().String()
|
serverAddr = l.Addr().String()
|
||||||
log.Infoln("RESTful API listening at: %s", serverAddr)
|
log.Infoln("RESTful API listening at: %s", serverAddr)
|
||||||
|
|
||||||
if err = http.Serve(l, r); err != nil {
|
if err = http.Serve(l, router(isDebug, true)); err != nil {
|
||||||
log.Errorln("External controller serve error: %s", err)
|
log.Errorln("External controller serve error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StartUnix(addr string, isDebug bool) {
|
||||||
|
// https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
|
||||||
|
//
|
||||||
|
// Note: As mentioned above in the ‘security’ section, when a socket binds a socket to a valid pathname address,
|
||||||
|
// a socket file is created within the filesystem. On Linux, the application is expected to unlink
|
||||||
|
// (see the notes section in the man page for AF_UNIX) before any other socket can be bound to the same address.
|
||||||
|
// The same applies to Windows unix sockets, except that, DeleteFile (or any other file delete API)
|
||||||
|
// should be used to delete the socket file prior to calling bind with the same path.
|
||||||
|
_ = syscall.Unlink(addr)
|
||||||
|
|
||||||
|
l, err := inbound.Listen("unix", addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("External controller unix listen error: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
serverAddr = l.Addr().String()
|
||||||
|
log.Infoln("RESTful API unix listening at: %s", serverAddr)
|
||||||
|
|
||||||
|
if err = http.Serve(l, router(isDebug, false)); err != nil {
|
||||||
|
log.Errorln("External controller unix serve error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setPrivateNetworkAccess(next http.Handler) http.Handler {
|
func setPrivateNetworkAccess(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" {
|
if r.Method == http.MethodOptions && r.Header.Get("Access-Control-Request-Method") != "" {
|
||||||
|
Loading…
Reference in New Issue
Block a user