refactor: adjust config

This commit is contained in:
Skyxim 2022-12-03 14:14:15 +08:00
parent 2fe271f19f
commit ba884c29bd
5 changed files with 110 additions and 92 deletions

18
common/net/tls.go Normal file
View 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
}

View file

@ -77,12 +77,10 @@ type Inbound struct {
// Controller config
type Controller struct {
ExternalController string `json:"-"`
ExternalUI string `json:"-"`
Secret string `json:"-"`
TLSPort int `json:"-"`
Cert string `json:"-"`
PrivateKey string `json:"-"`
ExternalController string `json:"-"`
ExternalControllerTLS string `json:"-"`
ExternalUI string `json:"-"`
Secret string `json:"-"`
}
// DNS config
@ -130,6 +128,11 @@ type TuicServer struct {
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 {
b, _ := json.Marshal(t)
return string(b)
@ -230,12 +233,10 @@ type Sniffer struct {
ParsePureIp bool
}
// Experimental config
type Experimental struct {
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
@ -254,6 +255,7 @@ type Config struct {
RuleProviders map[string]providerTypes.RuleProvider
Tunnels []Tunnel
Sniffer *Sniffer
TLS *TLS
}
type RawDNS struct {
@ -381,31 +383,32 @@ func (t *Tunnel) UnmarshalYAML(unmarshal func(any) error) error {
}
type RawConfig struct {
Port int `yaml:"port"`
SocksPort int `yaml:"socks-port"`
RedirPort int `yaml:"redir-port"`
TProxyPort int `yaml:"tproxy-port"`
MixedPort int `yaml:"mixed-port"`
ShadowSocksConfig string `yaml:"ss-config"`
VmessConfig string `yaml:"vmess-config"`
InboundTfo bool `yaml:"inbound-tfo"`
Authentication []string `yaml:"authentication"`
AllowLan bool `yaml:"allow-lan"`
BindAddress string `yaml:"bind-address"`
Mode T.TunnelMode `yaml:"mode"`
UnifiedDelay bool `yaml:"unified-delay"`
LogLevel log.LogLevel `yaml:"log-level"`
IPv6 bool `yaml:"ipv6"`
ExternalController string `yaml:"external-controller"`
ExternalUI string `yaml:"external-ui"`
Secret string `yaml:"secret"`
Interface string `yaml:"interface-name"`
RoutingMark int `yaml:"routing-mark"`
Tunnels []Tunnel `yaml:"tunnels"`
GeodataMode bool `yaml:"geodata-mode"`
GeodataLoader string `yaml:"geodata-loader"`
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
EnableProcess bool `yaml:"enable-process" json:"enable-process"`
Port int `yaml:"port"`
SocksPort int `yaml:"socks-port"`
RedirPort int `yaml:"redir-port"`
TProxyPort int `yaml:"tproxy-port"`
MixedPort int `yaml:"mixed-port"`
ShadowSocksConfig string `yaml:"ss-config"`
VmessConfig string `yaml:"vmess-config"`
InboundTfo bool `yaml:"inbound-tfo"`
Authentication []string `yaml:"authentication"`
AllowLan bool `yaml:"allow-lan"`
BindAddress string `yaml:"bind-address"`
Mode T.TunnelMode `yaml:"mode"`
UnifiedDelay bool `yaml:"unified-delay"`
LogLevel log.LogLevel `yaml:"log-level"`
IPv6 bool `yaml:"ipv6"`
ExternalController string `yaml:"external-controller"`
ExternalControllerTLS string `yaml:"external-controller-tls"`
ExternalUI string `yaml:"external-ui"`
Secret string `yaml:"secret"`
Interface string `yaml:"interface-name"`
RoutingMark int `yaml:"routing-mark"`
Tunnels []Tunnel `yaml:"tunnels"`
GeodataMode bool `yaml:"geodata-mode"`
GeodataLoader string `yaml:"geodata-loader"`
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
EnableProcess bool `yaml:"enable-process" json:"enable-process"`
Sniffer RawSniffer `yaml:"sniffer"`
ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
@ -423,6 +426,7 @@ type RawConfig struct {
ProxyGroup []map[string]any `yaml:"proxy-groups"`
Rule []string `yaml:"rules"`
SubRules map[string][]string `yaml:"sub-rules"`
RawTLS TLS `yaml:"tls"`
}
type RawGeoXUrl struct {
@ -572,6 +576,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
config.Experimental = &rawCfg.Experimental
config.Profile = &rawCfg.Profile
config.IPTables = &rawCfg.IPTables
config.TLS=&rawCfg.RawTLS
general, err := parseGeneral(rawCfg)
if err != nil {
@ -640,6 +645,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
return nil, err
}
elapsedTime := time.Since(startTime) / time.Millisecond // duration in ms
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
if externalUI != "" {
externalUI = C.Path.Resolve(externalUI)
if _, err := os.Stat(externalUI); os.IsNotExist(err) {
return nil, fmt.Errorf("external-ui: %s not exist", externalUI)
}
@ -675,9 +680,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
ExternalController: cfg.ExternalController,
ExternalUI: cfg.ExternalUI,
Secret: cfg.Secret,
TLSPort: cfg.Experimental.TLSPort,
Cert: cfg.Experimental.Cert,
PrivateKey: cfg.Experimental.PrivateKey,
ExternalControllerTLS: cfg.ExternalControllerTLS,
},
UnifiedDelay: cfg.UnifiedDelay,
Mode: cfg.Mode,

View file

@ -16,7 +16,7 @@ log-level: debug # 日志等级 silent/error/warning/info/debug
ipv6: true # 开启 IPv6 总开关,关闭阻断所有 IPv6 链接和屏蔽 DNS 请求 AAAA 记录
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}`
# tcp-concurrent: true # TCP并发连接所有IP, 将使用最快握手的TCP
@ -51,29 +51,29 @@ tun:
- 0.0.0.0/1
- 128.0.0.0/1
inet6_route_address: # 启用 auto_route 时使用自定义路由而不是默认路由
- '::/1'
- '8000::/1'
- "::/1"
- "8000::/1"
# endpoint_independent_nat: false # 启用独立于端点的 NAT
# include_uid: # UID 规则仅在 Linux 下被支持,并且需要 auto_route
# - 0
# - 0
# include_uid_range: # 限制被路由的的用户范围
# - 1000-99999
# - 1000-99999
# exclude_uid: # 排除路由的的用户
#- 1000
#- 1000
# exclude_uid_range: # 排除路由的的用户范围
# - 1000-99999
# - 1000-99999
# Android 用户和应用规则仅在 Android 下被支持
# 并且需要 auto_route
# include_android_user: # 限制被路由的 Android 用户
# - 0
# - 10
# - 0
# - 10
# include_package: # 限制被路由的 Android 应用包名
# - com.android.chrome
# - com.android.chrome
# exclude_package: # 排除被路由的 Android 应用包名
# - com.android.captiveportallogin
# - com.android.captiveportallogin
#ebpf配置
ebpf:
auto-redir: # redirect 模式,仅支持 TCP
@ -219,7 +219,8 @@ proxies:
server: server
port: 443
cipher: chacha20-ietf-poly1305
password: "password"
password:
"password"
# udp: true
# udp-over-tcp: false
# ip-version: ipv4 # 设置节点使用 IP 版本可选dualipv4ipv6ipv4-preferipv6-prefer。默认使用 dual
@ -449,7 +450,7 @@ proxies:
path: "/"
headers:
Host: example.com
#hysteria
- name: "hysteria"
type: hysteria
@ -468,7 +469,7 @@ proxies:
# recv_window_conn: 12582912 # 将会在未来某个时候删除
# recv-window-conn: 12582912
# recv_window: 52428800 # 将会在未来某个时候删除
# recv-window: 52428800
# recv-window: 52428800
# ca: "./my.ca"
# ca_str: "xyz" # 将会在未来某个时候删除
# ca-str: "xyz"
@ -657,3 +658,7 @@ sub-rules:
- IP-CIDR,1.1.1.1/32,REJECT
- IP-CIDR,8.8.8.8/32,ss1
- DOMAIN,dns.alidns.com,REJECT
tls:
certificate: string # 证书 PEM 格式,或者 证书的路径
private-key: string # 证书对应的私钥 PEM 格式,或者私钥路径

View file

@ -1,8 +1,6 @@
package hub
import (
"errors"
"github.com/Dreamacro/clash/config"
"github.com/Dreamacro/clash/hub/executor"
"github.com/Dreamacro/clash/hub/route"
@ -44,12 +42,8 @@ func Parse(options ...Option) error {
}
if cfg.General.ExternalController != "" {
if cfg.General.TLSPort != 0 && (len(cfg.General.PrivateKey) == 0 || len(cfg.General.Cert) == 0) {
return errors.New("Must be provided certificates and keys, for tls controller")
}
go route.Start(cfg.General.ExternalController, cfg.General.Secret, cfg.General.TLSPort,
cfg.General.Cert, cfg.General.PrivateKey)
go route.Start(cfg.General.ExternalController,cfg.General.ExternalControllerTLS,
cfg.General.Secret,cfg.TLS.Certificate,cfg.TLS.PrivateKey)
}
executor.ApplyConfig(cfg, true)

View file

@ -4,15 +4,14 @@ import (
"bytes"
"crypto/tls"
"encoding/json"
"net"
"net/http"
"strconv"
"strings"
"time"
"github.com/Dreamacro/clash/adapter/inbound"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
CN "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/tunnel/statistic"
"github.com/go-chi/chi/v5"
@ -43,7 +42,8 @@ func SetUIPath(path string) {
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 != "" {
return
}
@ -58,7 +58,6 @@ func Start(addr string, secret string, tlsPort int, cert string, privateKey stri
AllowedHeaders: []string{"Content-Type", "Authorization"},
MaxAge: 300,
})
r.Use()
r.Use(corsM.Handler)
r.Group(func(r chi.Router) {
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() {
if host, _, err := net.SplitHostPort(addr); err != nil {
log.Errorln("External controller tls serve error,%s", err)
} else {
l, err := inbound.Listen("tcp", net.JoinHostPort(host, strconv.Itoa(tlsPort)))
if err != nil {
log.Errorln("External controller tls listen error: %s", err)
return
}
serverAddr = l.Addr().String()
log.Infoln("RESTful API tls listening at: %s", serverAddr)
certificate, err := tls.X509KeyPair([]byte(cert), []byte(privateKey))
if err != nil {
log.Errorln("External controller tls sevre error,%s", err)
}
tlsServe := &http.Server{
Handler: r,
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{certificate},
},
}
if err = tlsServe.ServeTLS(l, "", ""); err != nil {
log.Errorln("External controller tls serve error: %s", err)
}
c, err := CN.ParseCert(certificat, privateKey)
if err != nil {
log.Errorln("External controller tls listen error: %s", err)
return
}
l, err := inbound.Listen("tcp", tlsAddr)
if err != nil {
log.Errorln("External controller tls listen error: %s", err)
return
}
serverAddr = l.Addr().String()
log.Infoln("RESTful API tls listening at: %s", serverAddr)
tlsServe := &http.Server{
Handler: r,
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{c},
},
}
if err = tlsServe.ServeTLS(l, "", ""); err != nil {
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)
}
}
func authentication(next http.Handler) http.Handler {