mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-02-23 20:52:15 +08:00
refactor: adjust config
This commit is contained in:
parent
2fe271f19f
commit
ba884c29bd
18
common/net/tls.go
Normal file
18
common/net/tls.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
func ParseCert(certificate,privateKey string) (tls.Certificate, error) {
|
||||||
|
cert, painTextErr := tls.X509KeyPair([]byte(certificate), []byte(privateKey))
|
||||||
|
if painTextErr == nil {
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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 cert, nil
|
||||||
|
}
|
@ -77,12 +77,10 @@ type Inbound struct {
|
|||||||
|
|
||||||
// Controller config
|
// Controller config
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
ExternalController string `json:"-"`
|
ExternalController string `json:"-"`
|
||||||
ExternalUI string `json:"-"`
|
ExternalControllerTLS string `json:"-"`
|
||||||
Secret string `json:"-"`
|
ExternalUI string `json:"-"`
|
||||||
TLSPort int `json:"-"`
|
Secret string `json:"-"`
|
||||||
Cert string `json:"-"`
|
|
||||||
PrivateKey string `json:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNS config
|
// DNS config
|
||||||
@ -130,6 +128,11 @@ type TuicServer struct {
|
|||||||
MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"`
|
MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TLS struct {
|
||||||
|
Certificate string `yaml:"certificate"`
|
||||||
|
PrivateKey string `yaml:"private-key"`
|
||||||
|
}
|
||||||
|
|
||||||
func (t TuicServer) String() string {
|
func (t TuicServer) String() string {
|
||||||
b, _ := json.Marshal(t)
|
b, _ := json.Marshal(t)
|
||||||
return string(b)
|
return string(b)
|
||||||
@ -230,12 +233,10 @@ type Sniffer struct {
|
|||||||
ParsePureIp bool
|
ParsePureIp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Experimental config
|
// Experimental config
|
||||||
type Experimental struct {
|
type Experimental struct {
|
||||||
Fingerprints []string `yaml:"fingerprints"`
|
Fingerprints []string `yaml:"fingerprints"`
|
||||||
TLSPort int `yaml:"tls-port,omitempty"`
|
|
||||||
Cert string `yaml:"cert,omitempty"`
|
|
||||||
PrivateKey string `yaml:"private-key,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is clash config manager
|
// Config is clash config manager
|
||||||
@ -254,6 +255,7 @@ type Config struct {
|
|||||||
RuleProviders map[string]providerTypes.RuleProvider
|
RuleProviders map[string]providerTypes.RuleProvider
|
||||||
Tunnels []Tunnel
|
Tunnels []Tunnel
|
||||||
Sniffer *Sniffer
|
Sniffer *Sniffer
|
||||||
|
TLS *TLS
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawDNS struct {
|
type RawDNS struct {
|
||||||
@ -381,31 +383,32 @@ func (t *Tunnel) UnmarshalYAML(unmarshal func(any) error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RawConfig struct {
|
type RawConfig struct {
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
SocksPort int `yaml:"socks-port"`
|
SocksPort int `yaml:"socks-port"`
|
||||||
RedirPort int `yaml:"redir-port"`
|
RedirPort int `yaml:"redir-port"`
|
||||||
TProxyPort int `yaml:"tproxy-port"`
|
TProxyPort int `yaml:"tproxy-port"`
|
||||||
MixedPort int `yaml:"mixed-port"`
|
MixedPort int `yaml:"mixed-port"`
|
||||||
ShadowSocksConfig string `yaml:"ss-config"`
|
ShadowSocksConfig string `yaml:"ss-config"`
|
||||||
VmessConfig string `yaml:"vmess-config"`
|
VmessConfig string `yaml:"vmess-config"`
|
||||||
InboundTfo bool `yaml:"inbound-tfo"`
|
InboundTfo bool `yaml:"inbound-tfo"`
|
||||||
Authentication []string `yaml:"authentication"`
|
Authentication []string `yaml:"authentication"`
|
||||||
AllowLan bool `yaml:"allow-lan"`
|
AllowLan bool `yaml:"allow-lan"`
|
||||||
BindAddress string `yaml:"bind-address"`
|
BindAddress string `yaml:"bind-address"`
|
||||||
Mode T.TunnelMode `yaml:"mode"`
|
Mode T.TunnelMode `yaml:"mode"`
|
||||||
UnifiedDelay bool `yaml:"unified-delay"`
|
UnifiedDelay bool `yaml:"unified-delay"`
|
||||||
LogLevel log.LogLevel `yaml:"log-level"`
|
LogLevel log.LogLevel `yaml:"log-level"`
|
||||||
IPv6 bool `yaml:"ipv6"`
|
IPv6 bool `yaml:"ipv6"`
|
||||||
ExternalController string `yaml:"external-controller"`
|
ExternalController string `yaml:"external-controller"`
|
||||||
ExternalUI string `yaml:"external-ui"`
|
ExternalControllerTLS string `yaml:"external-controller-tls"`
|
||||||
Secret string `yaml:"secret"`
|
ExternalUI string `yaml:"external-ui"`
|
||||||
Interface string `yaml:"interface-name"`
|
Secret string `yaml:"secret"`
|
||||||
RoutingMark int `yaml:"routing-mark"`
|
Interface string `yaml:"interface-name"`
|
||||||
Tunnels []Tunnel `yaml:"tunnels"`
|
RoutingMark int `yaml:"routing-mark"`
|
||||||
GeodataMode bool `yaml:"geodata-mode"`
|
Tunnels []Tunnel `yaml:"tunnels"`
|
||||||
GeodataLoader string `yaml:"geodata-loader"`
|
GeodataMode bool `yaml:"geodata-mode"`
|
||||||
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
|
GeodataLoader string `yaml:"geodata-loader"`
|
||||||
EnableProcess bool `yaml:"enable-process" json:"enable-process"`
|
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
|
||||||
|
EnableProcess bool `yaml:"enable-process" json:"enable-process"`
|
||||||
|
|
||||||
Sniffer RawSniffer `yaml:"sniffer"`
|
Sniffer RawSniffer `yaml:"sniffer"`
|
||||||
ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
|
ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
|
||||||
@ -423,6 +426,7 @@ type RawConfig struct {
|
|||||||
ProxyGroup []map[string]any `yaml:"proxy-groups"`
|
ProxyGroup []map[string]any `yaml:"proxy-groups"`
|
||||||
Rule []string `yaml:"rules"`
|
Rule []string `yaml:"rules"`
|
||||||
SubRules map[string][]string `yaml:"sub-rules"`
|
SubRules map[string][]string `yaml:"sub-rules"`
|
||||||
|
RawTLS TLS `yaml:"tls"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawGeoXUrl struct {
|
type RawGeoXUrl struct {
|
||||||
@ -572,6 +576,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
|||||||
config.Experimental = &rawCfg.Experimental
|
config.Experimental = &rawCfg.Experimental
|
||||||
config.Profile = &rawCfg.Profile
|
config.Profile = &rawCfg.Profile
|
||||||
config.IPTables = &rawCfg.IPTables
|
config.IPTables = &rawCfg.IPTables
|
||||||
|
config.TLS=&rawCfg.RawTLS
|
||||||
|
|
||||||
general, err := parseGeneral(rawCfg)
|
general, err := parseGeneral(rawCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -640,6 +645,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
elapsedTime := time.Since(startTime) / time.Millisecond // duration in ms
|
elapsedTime := time.Since(startTime) / time.Millisecond // duration in ms
|
||||||
log.Infoln("Initial configuration complete, total time: %dms", elapsedTime) //Segment finished in xxm
|
log.Infoln("Initial configuration complete, total time: %dms", elapsedTime) //Segment finished in xxm
|
||||||
|
|
||||||
@ -652,7 +658,6 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
|||||||
// checkout externalUI exist
|
// checkout externalUI exist
|
||||||
if externalUI != "" {
|
if externalUI != "" {
|
||||||
externalUI = C.Path.Resolve(externalUI)
|
externalUI = C.Path.Resolve(externalUI)
|
||||||
|
|
||||||
if _, err := os.Stat(externalUI); os.IsNotExist(err) {
|
if _, err := os.Stat(externalUI); os.IsNotExist(err) {
|
||||||
return nil, fmt.Errorf("external-ui: %s not exist", externalUI)
|
return nil, fmt.Errorf("external-ui: %s not exist", externalUI)
|
||||||
}
|
}
|
||||||
@ -675,9 +680,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
|||||||
ExternalController: cfg.ExternalController,
|
ExternalController: cfg.ExternalController,
|
||||||
ExternalUI: cfg.ExternalUI,
|
ExternalUI: cfg.ExternalUI,
|
||||||
Secret: cfg.Secret,
|
Secret: cfg.Secret,
|
||||||
TLSPort: cfg.Experimental.TLSPort,
|
ExternalControllerTLS: cfg.ExternalControllerTLS,
|
||||||
Cert: cfg.Experimental.Cert,
|
|
||||||
PrivateKey: cfg.Experimental.PrivateKey,
|
|
||||||
},
|
},
|
||||||
UnifiedDelay: cfg.UnifiedDelay,
|
UnifiedDelay: cfg.UnifiedDelay,
|
||||||
Mode: cfg.Mode,
|
Mode: cfg.Mode,
|
||||||
|
@ -16,7 +16,7 @@ log-level: debug # 日志等级 silent/error/warning/info/debug
|
|||||||
ipv6: true # 开启 IPv6 总开关,关闭阻断所有 IPv6 链接和屏蔽 DNS 请求 AAAA 记录
|
ipv6: true # 开启 IPv6 总开关,关闭阻断所有 IPv6 链接和屏蔽 DNS 请求 AAAA 记录
|
||||||
|
|
||||||
external-controller: 0.0.0.0:9093 # RESTful API 监听地址
|
external-controller: 0.0.0.0:9093 # RESTful API 监听地址
|
||||||
|
external-controller-tls: 0.0.0.0:9443 # RESTful API HTTPS 监听地址,需要配置 tls 部分配置文件
|
||||||
# secret: "123456" # `Authorization: Bearer ${secret}`
|
# secret: "123456" # `Authorization: Bearer ${secret}`
|
||||||
|
|
||||||
# tcp-concurrent: true # TCP并发连接所有IP, 将使用最快握手的TCP
|
# tcp-concurrent: true # TCP并发连接所有IP, 将使用最快握手的TCP
|
||||||
@ -51,28 +51,28 @@ tun:
|
|||||||
- 0.0.0.0/1
|
- 0.0.0.0/1
|
||||||
- 128.0.0.0/1
|
- 128.0.0.0/1
|
||||||
inet6_route_address: # 启用 auto_route 时使用自定义路由而不是默认路由
|
inet6_route_address: # 启用 auto_route 时使用自定义路由而不是默认路由
|
||||||
- '::/1'
|
- "::/1"
|
||||||
- '8000::/1'
|
- "8000::/1"
|
||||||
# endpoint_independent_nat: false # 启用独立于端点的 NAT
|
# endpoint_independent_nat: false # 启用独立于端点的 NAT
|
||||||
# include_uid: # UID 规则仅在 Linux 下被支持,并且需要 auto_route
|
# include_uid: # UID 规则仅在 Linux 下被支持,并且需要 auto_route
|
||||||
# - 0
|
# - 0
|
||||||
# include_uid_range: # 限制被路由的的用户范围
|
# include_uid_range: # 限制被路由的的用户范围
|
||||||
# - 1000-99999
|
# - 1000-99999
|
||||||
# exclude_uid: # 排除路由的的用户
|
# exclude_uid: # 排除路由的的用户
|
||||||
#- 1000
|
#- 1000
|
||||||
# exclude_uid_range: # 排除路由的的用户范围
|
# exclude_uid_range: # 排除路由的的用户范围
|
||||||
# - 1000-99999
|
# - 1000-99999
|
||||||
|
|
||||||
# Android 用户和应用规则仅在 Android 下被支持
|
# Android 用户和应用规则仅在 Android 下被支持
|
||||||
# 并且需要 auto_route
|
# 并且需要 auto_route
|
||||||
|
|
||||||
# include_android_user: # 限制被路由的 Android 用户
|
# include_android_user: # 限制被路由的 Android 用户
|
||||||
# - 0
|
# - 0
|
||||||
# - 10
|
# - 10
|
||||||
# include_package: # 限制被路由的 Android 应用包名
|
# include_package: # 限制被路由的 Android 应用包名
|
||||||
# - com.android.chrome
|
# - com.android.chrome
|
||||||
# exclude_package: # 排除被路由的 Android 应用包名
|
# exclude_package: # 排除被路由的 Android 应用包名
|
||||||
# - com.android.captiveportallogin
|
# - com.android.captiveportallogin
|
||||||
|
|
||||||
#ebpf配置
|
#ebpf配置
|
||||||
ebpf:
|
ebpf:
|
||||||
@ -219,7 +219,8 @@ proxies:
|
|||||||
server: server
|
server: server
|
||||||
port: 443
|
port: 443
|
||||||
cipher: chacha20-ietf-poly1305
|
cipher: chacha20-ietf-poly1305
|
||||||
password: "password"
|
password:
|
||||||
|
"password"
|
||||||
# udp: true
|
# udp: true
|
||||||
# udp-over-tcp: false
|
# udp-over-tcp: false
|
||||||
# ip-version: ipv4 # 设置节点使用 IP 版本,可选:dual,ipv4,ipv6,ipv4-prefer,ipv6-prefer。默认使用 dual
|
# ip-version: ipv4 # 设置节点使用 IP 版本,可选:dual,ipv4,ipv6,ipv4-prefer,ipv6-prefer。默认使用 dual
|
||||||
@ -657,3 +658,7 @@ sub-rules:
|
|||||||
- IP-CIDR,1.1.1.1/32,REJECT
|
- IP-CIDR,1.1.1.1/32,REJECT
|
||||||
- IP-CIDR,8.8.8.8/32,ss1
|
- IP-CIDR,8.8.8.8/32,ss1
|
||||||
- DOMAIN,dns.alidns.com,REJECT
|
- DOMAIN,dns.alidns.com,REJECT
|
||||||
|
|
||||||
|
tls:
|
||||||
|
certificate: string # 证书 PEM 格式,或者 证书的路径
|
||||||
|
private-key: string # 证书对应的私钥 PEM 格式,或者私钥路径
|
||||||
|
10
hub/hub.go
10
hub/hub.go
@ -1,8 +1,6 @@
|
|||||||
package hub
|
package hub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/config"
|
"github.com/Dreamacro/clash/config"
|
||||||
"github.com/Dreamacro/clash/hub/executor"
|
"github.com/Dreamacro/clash/hub/executor"
|
||||||
"github.com/Dreamacro/clash/hub/route"
|
"github.com/Dreamacro/clash/hub/route"
|
||||||
@ -44,12 +42,8 @@ func Parse(options ...Option) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.General.ExternalController != "" {
|
if cfg.General.ExternalController != "" {
|
||||||
if cfg.General.TLSPort != 0 && (len(cfg.General.PrivateKey) == 0 || len(cfg.General.Cert) == 0) {
|
go route.Start(cfg.General.ExternalController,cfg.General.ExternalControllerTLS,
|
||||||
return errors.New("Must be provided certificates and keys, for tls controller")
|
cfg.General.Secret,cfg.TLS.Certificate,cfg.TLS.PrivateKey)
|
||||||
}
|
|
||||||
|
|
||||||
go route.Start(cfg.General.ExternalController, cfg.General.Secret, cfg.General.TLSPort,
|
|
||||||
cfg.General.Cert, cfg.General.PrivateKey)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
executor.ApplyConfig(cfg, true)
|
executor.ApplyConfig(cfg, true)
|
||||||
|
@ -4,15 +4,14 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/adapter/inbound"
|
"github.com/Dreamacro/clash/adapter/inbound"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
|
CN "github.com/Dreamacro/clash/common/net"
|
||||||
"github.com/Dreamacro/clash/tunnel/statistic"
|
"github.com/Dreamacro/clash/tunnel/statistic"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
@ -43,7 +42,8 @@ func SetUIPath(path string) {
|
|||||||
uiPath = C.Path.Resolve(path)
|
uiPath = C.Path.Resolve(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(addr string, secret string, tlsPort int, cert string, privateKey string) {
|
func Start(addr string, tlsAddr string, secret string,
|
||||||
|
certificat, privateKey string) {
|
||||||
if serverAddr != "" {
|
if serverAddr != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -58,7 +58,6 @@ func Start(addr string, secret string, tlsPort int, cert string, privateKey stri
|
|||||||
AllowedHeaders: []string{"Content-Type", "Authorization"},
|
AllowedHeaders: []string{"Content-Type", "Authorization"},
|
||||||
MaxAge: 300,
|
MaxAge: 300,
|
||||||
})
|
})
|
||||||
r.Use()
|
|
||||||
r.Use(corsM.Handler)
|
r.Use(corsM.Handler)
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(authentication)
|
r.Use(authentication)
|
||||||
@ -85,31 +84,31 @@ func Start(addr string, secret string, tlsPort int, cert string, privateKey stri
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if tlsPort >0 {
|
|
||||||
|
if len(tlsAddr) > 0 {
|
||||||
go func() {
|
go func() {
|
||||||
if host, _, err := net.SplitHostPort(addr); err != nil {
|
c, err := CN.ParseCert(certificat, privateKey)
|
||||||
log.Errorln("External controller tls serve error,%s", err)
|
if err != nil {
|
||||||
} else {
|
log.Errorln("External controller tls listen error: %s", err)
|
||||||
l, err := inbound.Listen("tcp", net.JoinHostPort(host, strconv.Itoa(tlsPort)))
|
return
|
||||||
if err != nil {
|
}
|
||||||
log.Errorln("External controller tls listen error: %s", err)
|
|
||||||
return
|
l, err := inbound.Listen("tcp", tlsAddr)
|
||||||
}
|
if err != nil {
|
||||||
serverAddr = l.Addr().String()
|
log.Errorln("External controller tls listen error: %s", err)
|
||||||
log.Infoln("RESTful API tls listening at: %s", serverAddr)
|
return
|
||||||
certificate, err := tls.X509KeyPair([]byte(cert), []byte(privateKey))
|
}
|
||||||
if err != nil {
|
|
||||||
log.Errorln("External controller tls sevre error,%s", err)
|
serverAddr = l.Addr().String()
|
||||||
}
|
log.Infoln("RESTful API tls listening at: %s", serverAddr)
|
||||||
tlsServe := &http.Server{
|
tlsServe := &http.Server{
|
||||||
Handler: r,
|
Handler: r,
|
||||||
TLSConfig: &tls.Config{
|
TLSConfig: &tls.Config{
|
||||||
Certificates: []tls.Certificate{certificate},
|
Certificates: []tls.Certificate{c},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err = tlsServe.ServeTLS(l, "", ""); err != nil {
|
if err = tlsServe.ServeTLS(l, "", ""); err != nil {
|
||||||
log.Errorln("External controller tls serve error: %s", err)
|
log.Errorln("External controller tls serve error: %s", err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -126,7 +125,6 @@ func Start(addr string, secret string, tlsPort int, cert string, privateKey stri
|
|||||||
log.Errorln("External controller serve error: %s", err)
|
log.Errorln("External controller serve error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func authentication(next http.Handler) http.Handler {
|
func authentication(next http.Handler) http.Handler {
|
||||||
|
Loading…
Reference in New Issue
Block a user