mirror of
https://github.com/bolucat/Archive.git
synced 2025-10-28 18:44:42 +08:00
Update On Sat Sep 13 20:34:35 CEST 2025
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -1119,3 +1119,4 @@ Update On Tue Sep 9 20:33:51 CEST 2025
|
||||
Update On Wed Sep 10 20:42:57 CEST 2025
|
||||
Update On Thu Sep 11 20:34:24 CEST 2025
|
||||
Update On Fri Sep 12 20:36:01 CEST 2025
|
||||
Update On Sat Sep 13 20:34:27 CEST 2025
|
||||
|
||||
@@ -2,7 +2,6 @@ package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -236,6 +235,11 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
DialContext: func(context.Context, string, string) (net.Conn, error) {
|
||||
return instance, nil
|
||||
@@ -245,7 +249,7 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: ca.GetGlobalTLSConfig(&tls.Config{}),
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
|
||||
client := http.Client{
|
||||
|
||||
@@ -167,10 +167,13 @@ func NewHttp(option HttpOption) (*Http, error) {
|
||||
sni = option.SNI
|
||||
}
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
ServerName: sni,
|
||||
}, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -160,14 +160,16 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) {
|
||||
serverName = option.SNI
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: serverName,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
CustomCA: option.CustomCA,
|
||||
CustomCAString: option.CustomCAString,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -141,14 +141,16 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||
serverName = option.SNI
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: serverName,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
CustomCA: option.CustomCA,
|
||||
CustomCAString: option.CustomCAString,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -193,13 +193,14 @@ func (ss *Socks5) clientHandshakeContext(ctx context.Context, c net.Conn, addr s
|
||||
func NewSocks5(option Socks5Option) (*Socks5, error) {
|
||||
var tlsConfig *tls.Config
|
||||
if option.TLS {
|
||||
tlsConfig = &tls.Config{
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
ServerName: option.Server,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -100,14 +100,15 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.
|
||||
}
|
||||
|
||||
wsOpts.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: alpn,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: t.option.SkipCertVerify,
|
||||
ServerName: t.option.SNI,
|
||||
}
|
||||
|
||||
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: t.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -363,15 +364,15 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: option.ALPN,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
ServerName: option.SNI,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -161,17 +161,20 @@ func (t *Tuic) ProxyInfo() C.ProxyInfo {
|
||||
func NewTuic(option TuicOption) (*Tuic, error) {
|
||||
addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
|
||||
serverName := option.Server
|
||||
tlsConfig := &tls.Config{
|
||||
if option.SNI != "" {
|
||||
serverName = option.SNI
|
||||
}
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: serverName,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
if option.SNI != "" {
|
||||
tlsConfig.ServerName = option.SNI
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
CustomCA: option.CustomCA,
|
||||
CustomCAString: option.CustomCAString,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -95,14 +95,15 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
||||
}
|
||||
if v.option.TLS {
|
||||
wsOpts.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
|
||||
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -498,10 +499,13 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
}
|
||||
var tlsConfig *tls.Config
|
||||
if option.TLS {
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
ServerName: v.option.ServerName,
|
||||
}, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -123,13 +123,14 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
||||
|
||||
if v.option.TLS {
|
||||
wsOpts.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
|
||||
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -501,10 +502,13 @@ func NewVmess(option VmessOption) (*Vmess, error) {
|
||||
}
|
||||
var tlsConfig *tls.Config
|
||||
if option.TLS {
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
ServerName: v.option.ServerName,
|
||||
}, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ import (
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/metacubex/mihomo/common/once"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
)
|
||||
|
||||
var globalCertPool *x509.CertPool
|
||||
@@ -65,18 +67,6 @@ func ResetCertificate() {
|
||||
initializeCertPool()
|
||||
}
|
||||
|
||||
func getCertPool() *x509.CertPool {
|
||||
if globalCertPool == nil {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
if globalCertPool != nil {
|
||||
return globalCertPool
|
||||
}
|
||||
initializeCertPool()
|
||||
}
|
||||
return globalCertPool
|
||||
}
|
||||
|
||||
func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error) {
|
||||
var certificate []byte
|
||||
var err error
|
||||
@@ -99,22 +89,41 @@ func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error)
|
||||
}
|
||||
return certPool, nil
|
||||
} else {
|
||||
return getCertPool(), nil
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
if globalCertPool == nil {
|
||||
initializeCertPool()
|
||||
}
|
||||
return globalCertPool, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetTLSConfig specified fingerprint, customCA and customCAString
|
||||
func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, customCAString string) (_ *tls.Config, err error) {
|
||||
type Option struct {
|
||||
TLSConfig *tls.Config
|
||||
Fingerprint string
|
||||
CustomCA string
|
||||
CustomCAString string
|
||||
ZeroTrust bool
|
||||
}
|
||||
|
||||
func GetTLSConfig(opt Option) (tlsConfig *tls.Config, err error) {
|
||||
tlsConfig = opt.TLSConfig
|
||||
if tlsConfig == nil {
|
||||
tlsConfig = &tls.Config{}
|
||||
}
|
||||
tlsConfig.RootCAs, err = GetCertPool(customCA, customCAString)
|
||||
tlsConfig.Time = ntp.Now
|
||||
|
||||
if opt.ZeroTrust {
|
||||
tlsConfig.RootCAs = zeroTrustCertPool()
|
||||
} else {
|
||||
tlsConfig.RootCAs, err = GetCertPool(opt.CustomCA, opt.CustomCAString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(fingerprint) > 0 {
|
||||
tlsConfig.VerifyPeerCertificate, err = NewFingerprintVerifier(fingerprint)
|
||||
if len(opt.Fingerprint) > 0 {
|
||||
tlsConfig.VerifyPeerCertificate, err = NewFingerprintVerifier(opt.Fingerprint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -123,12 +132,12 @@ func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, cu
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// GetSpecifiedFingerprintTLSConfig specified fingerprint
|
||||
func GetSpecifiedFingerprintTLSConfig(tlsConfig *tls.Config, fingerprint string) (*tls.Config, error) {
|
||||
return GetTLSConfig(tlsConfig, fingerprint, "", "")
|
||||
}
|
||||
|
||||
func GetGlobalTLSConfig(tlsConfig *tls.Config) *tls.Config {
|
||||
tlsConfig, _ = GetTLSConfig(tlsConfig, "", "", "")
|
||||
return tlsConfig
|
||||
}
|
||||
var zeroTrustCertPool = once.OnceValue(func() *x509.CertPool {
|
||||
if len(_CaCertificates) != 0 { // always using embed cert first
|
||||
zeroTrustCertPool := x509.NewCertPool()
|
||||
if zeroTrustCertPool.AppendCertsFromPEM(_CaCertificates) {
|
||||
return zeroTrustCertPool
|
||||
}
|
||||
}
|
||||
return nil // fallback to system pool
|
||||
})
|
||||
|
||||
@@ -2,7 +2,6 @@ package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -28,11 +27,11 @@ func SetUA(UA string) {
|
||||
ua = UA
|
||||
}
|
||||
|
||||
func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader) (*http.Response, error) {
|
||||
return HttpRequestWithProxy(ctx, url, method, header, body, "")
|
||||
}
|
||||
|
||||
func HttpRequestWithProxy(ctx context.Context, url, method string, header map[string][]string, body io.Reader, specialProxy string) (*http.Response, error) {
|
||||
func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader, options ...Option) (*http.Response, error) {
|
||||
opt := option{}
|
||||
for _, o := range options {
|
||||
o(&opt)
|
||||
}
|
||||
method = strings.ToUpper(method)
|
||||
urlRes, err := URL.Parse(url)
|
||||
if err != nil {
|
||||
@@ -40,6 +39,10 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, urlRes.String(), body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range header {
|
||||
for _, v := range v {
|
||||
req.Header.Add(k, v)
|
||||
@@ -50,10 +53,6 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
req.Header.Set("User-Agent", UA())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if user := urlRes.User; user != nil {
|
||||
password, _ := user.Password()
|
||||
req.SetBasicAuth(user.Username(), password)
|
||||
@@ -61,6 +60,11 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(opt.caOption)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
// from http.DefaultTransport
|
||||
DisableKeepAlives: runtime.GOOS == "android",
|
||||
@@ -69,15 +73,34 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
if conn, err := inner.HandleTcp(inner.GetTunnel(), address, specialProxy); err == nil {
|
||||
if conn, err := inner.HandleTcp(inner.GetTunnel(), address, opt.specialProxy); err == nil {
|
||||
return conn, nil
|
||||
} else {
|
||||
return dialer.DialContext(ctx, network, address)
|
||||
}
|
||||
},
|
||||
TLSClientConfig: ca.GetGlobalTLSConfig(&tls.Config{}),
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
|
||||
client := http.Client{Transport: transport}
|
||||
return client.Do(req)
|
||||
}
|
||||
|
||||
type Option func(opt *option)
|
||||
|
||||
type option struct {
|
||||
specialProxy string
|
||||
caOption ca.Option
|
||||
}
|
||||
|
||||
func WithSpecialProxy(name string) Option {
|
||||
return func(opt *option) {
|
||||
opt.specialProxy = name
|
||||
}
|
||||
}
|
||||
|
||||
func WithCAOption(caOption ca.Option) Option {
|
||||
return func(opt *option) {
|
||||
opt.caOption = caOption
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func (h *HTTPVehicle) Read(ctx context.Context, oldHash utils.HashType) (buf []b
|
||||
setIfNoneMatch = true
|
||||
}
|
||||
}
|
||||
resp, err := mihomoHttp.HttpRequestWithProxy(ctx, h.url, http.MethodGet, header, nil, h.proxy)
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, h.url, http.MethodGet, header, nil, mihomoHttp.WithSpecialProxy(h.proxy))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
mihomoHttp "github.com/metacubex/mihomo/component/http"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
@@ -171,7 +172,7 @@ func (u *CoreUpdater) Update(currentExePath string, channel string, force bool)
|
||||
func (u *CoreUpdater) getLatestVersion(versionURL string) (version string, err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, versionURL, http.MethodGet, nil, nil)
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, versionURL, http.MethodGet, nil, nil, mihomoHttp.WithCAOption(ca.Option{ZeroTrust: true}))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -194,7 +195,7 @@ func (u *CoreUpdater) getLatestVersion(versionURL string) (version string, err e
|
||||
func (u *CoreUpdater) download(updateDir, packagePath, packageURL string) (err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
|
||||
defer cancel()
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, packageURL, http.MethodGet, nil, nil)
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, packageURL, http.MethodGet, nil, nil, mihomoHttp.WithCAOption(ca.Option{ZeroTrust: true}))
|
||||
if err != nil {
|
||||
return fmt.Errorf("http request failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -48,6 +48,13 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
network = "tcp"
|
||||
}
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: c.Client.TLSConfig,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := net.JoinHostPort(c.host, c.port)
|
||||
conn, err := c.dialer.DialContext(ctx, network, addr)
|
||||
if err != nil {
|
||||
@@ -66,7 +73,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
ch := make(chan result, 1)
|
||||
go func() {
|
||||
if strings.HasSuffix(c.Client.Net, "tls") {
|
||||
conn = tls.Client(conn, ca.GetGlobalTLSConfig(c.Client.TLSConfig))
|
||||
conn = tls.Client(conn, tlsConfig)
|
||||
}
|
||||
|
||||
dConn := &D.Conn{
|
||||
|
||||
@@ -397,12 +397,16 @@ func (doh *dnsOverHTTPS) createTransport(ctx context.Context) (t http.RoundTripp
|
||||
return transport, nil
|
||||
}
|
||||
|
||||
tlsConfig := ca.GetGlobalTLSConfig(
|
||||
&tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: doh.skipCertVerify,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
SessionTicketsDisabled: false,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var nextProtos []string
|
||||
for _, v := range doh.httpVersions {
|
||||
nextProtos = append(nextProtos, string(v))
|
||||
|
||||
@@ -331,15 +331,19 @@ func (doq *dnsOverQUIC) openConnection(ctx context.Context) (conn *quic.Conn, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := ca.GetGlobalTLSConfig(
|
||||
&tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: doq.skipCertVerify,
|
||||
NextProtos: []string{
|
||||
NextProtoDQ,
|
||||
},
|
||||
SessionTicketsDisabled: false,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
transport := quic.Transport{Conn: udp}
|
||||
transport.SetCreatedConn(true) // auto close conn
|
||||
|
||||
@@ -6,7 +6,7 @@ require (
|
||||
github.com/bahlo/generic-list-go v0.2.0
|
||||
github.com/coreos/go-iptables v0.8.0
|
||||
github.com/dlclark/regexp2 v1.11.5
|
||||
github.com/enfein/mieru/v3 v3.19.1
|
||||
github.com/enfein/mieru/v3 v3.20.0
|
||||
github.com/go-chi/chi/v5 v5.2.3
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/gobwas/ws v1.4.0
|
||||
|
||||
@@ -25,8 +25,8 @@ github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZ
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/enfein/mieru/v3 v3.19.1 h1:19b9kgFC7oJXX9RLEO5Pi1gO6yek5cWlpK7IJVUoE8I=
|
||||
github.com/enfein/mieru/v3 v3.19.1/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
|
||||
github.com/enfein/mieru/v3 v3.20.0 h1:1ob7pCIVSH5FYFAfYvim8isLW1vBOS4cFOUF9exJS38=
|
||||
github.com/enfein/mieru/v3 v3.20.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 h1:kXYqH/sL8dS/FdoFjr12ePjnLPorPo2FsnrHNuXSDyo=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I=
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g=
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/tunnel/statistic"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -201,7 +202,7 @@ func startTLS(cfg *Config) {
|
||||
}
|
||||
|
||||
log.Infoln("RESTful API tls listening at: %s", l.Addr().String())
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
|
||||
tlsConfig.Certificates = []tlsC.Certificate{tlsC.UCertificate(cert)}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/anytls/padding"
|
||||
"github.com/metacubex/mihomo/transport/anytls/session"
|
||||
|
||||
@@ -42,7 +43,7 @@ func New(config LC.AnyTLSServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
}
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
if config.Certificate != "" && config.PrivateKey != "" {
|
||||
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
|
||||
if err != nil {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
)
|
||||
|
||||
type Listener struct {
|
||||
@@ -65,7 +66,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
|
||||
if config.Certificate != "" && config.PrivateKey != "" {
|
||||
|
||||
@@ -39,7 +39,7 @@ var userUUID = utils.NewUUIDV4().String()
|
||||
var tlsCertificate, tlsPrivateKey, tlsFingerprint, _ = ca.NewRandomTLSKeyPair(ca.KeyPairTypeP256)
|
||||
var tlsConfigCert, _ = tls.X509KeyPair([]byte(tlsCertificate), []byte(tlsPrivateKey))
|
||||
var tlsConfig = &tls.Config{Certificates: []tls.Certificate{tlsConfigCert}, NextProtos: []string{"h2", "http/1.1"}}
|
||||
var tlsClientConfig, _ = ca.GetTLSConfig(nil, tlsFingerprint, "", "")
|
||||
var tlsClientConfig, _ = ca.GetTLSConfig(ca.Option{Fingerprint: tlsFingerprint})
|
||||
var realityPrivateKey, realityPublickey string
|
||||
var realityDest = "itunes.apple.com"
|
||||
var realityShortid = "10f897e26c4b9478"
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/metacubex/mihomo/listener/http"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/listener/socks"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/socks4"
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
)
|
||||
@@ -61,7 +62,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
|
||||
if config.Certificate != "" && config.PrivateKey != "" {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
|
||||
"github.com/metacubex/sing-quic/hysteria2"
|
||||
|
||||
@@ -61,6 +62,7 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig := &tlsC.Config{
|
||||
Time: ntp.Now,
|
||||
MinVersion: tlsC.VersionTLS13,
|
||||
}
|
||||
tlsConfig.Certificates = []tlsC.Certificate{tlsC.UCertificate(cert)}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
"github.com/metacubex/mihomo/transport/vless/encryption"
|
||||
mihomoVMess "github.com/metacubex/mihomo/transport/vmess"
|
||||
@@ -75,7 +76,7 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
}()
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
var httpServer http.Server
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ func New(config LC.VmessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
|
||||
sl = &Listener{false, config, nil, service}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
var httpServer http.Server
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/socks4"
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
)
|
||||
@@ -60,7 +61,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
|
||||
if config.Certificate != "" && config.PrivateKey != "" {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
"github.com/metacubex/mihomo/transport/shadowsocks/core"
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
@@ -70,7 +71,7 @@ func New(config LC.TrojanServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
}
|
||||
sl = &Listener{false, config, nil, keys, pickCipher, h}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
var httpServer http.Server
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
"github.com/metacubex/mihomo/transport/tuic"
|
||||
|
||||
@@ -53,6 +54,7 @@ func New(config LC.TuicServer, tunnel C.Tunnel, additions ...inbound.Addition) (
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig := &tlsC.Config{
|
||||
Time: ntp.Now,
|
||||
MinVersion: tlsC.VersionTLS13,
|
||||
}
|
||||
tlsConfig.Certificates = []tlsC.Certificate{tlsC.UCertificate(cert)}
|
||||
|
||||
@@ -23,24 +23,21 @@ type Service struct {
|
||||
ticker *time.Ticker
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
mu sync.RWMutex
|
||||
offset time.Duration
|
||||
offset atomic.Int64 // [time.Duration]
|
||||
syncSystemTime bool
|
||||
running bool
|
||||
}
|
||||
|
||||
func ReCreateNTPService(server string, interval time.Duration, dialerProxy string, syncSystemTime bool) {
|
||||
globalMu.Lock()
|
||||
defer globalMu.Unlock()
|
||||
service := globalSrv.Swap(nil)
|
||||
if service != nil {
|
||||
if service := globalSrv.Swap(nil); service != nil {
|
||||
service.Stop()
|
||||
}
|
||||
if server == "" {
|
||||
if server == "" || interval <= 0 {
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
service = &Service{
|
||||
service := &Service{
|
||||
server: M.ParseSocksaddr(server),
|
||||
dialer: proxydialer.NewByNameSingDialer(dialerProxy, dialer.NewDialer()),
|
||||
ticker: time.NewTicker(interval * time.Minute),
|
||||
@@ -53,38 +50,17 @@ func ReCreateNTPService(server string, interval time.Duration, dialerProxy strin
|
||||
}
|
||||
|
||||
func (srv *Service) Start() {
|
||||
srv.mu.Lock()
|
||||
defer srv.mu.Unlock()
|
||||
log.Infoln("NTP service start, sync system time is %t", srv.syncSystemTime)
|
||||
err := srv.update()
|
||||
if err != nil {
|
||||
log.Errorln("Initialize NTP time failed: %s", err)
|
||||
return
|
||||
}
|
||||
srv.running = true
|
||||
go srv.loopUpdate()
|
||||
}
|
||||
|
||||
func (srv *Service) Stop() {
|
||||
srv.mu.Lock()
|
||||
defer srv.mu.Unlock()
|
||||
if srv.running {
|
||||
srv.ticker.Stop()
|
||||
log.Infoln("NTP service stop")
|
||||
srv.cancel()
|
||||
srv.running = false
|
||||
}
|
||||
}
|
||||
|
||||
func (srv *Service) Offset() time.Duration {
|
||||
if srv == nil {
|
||||
return 0
|
||||
}
|
||||
srv.mu.RLock()
|
||||
defer srv.mu.RUnlock()
|
||||
if srv.running {
|
||||
return srv.offset
|
||||
}
|
||||
return 0
|
||||
return time.Duration(srv.offset.Load())
|
||||
}
|
||||
|
||||
func (srv *Service) update() error {
|
||||
@@ -93,6 +69,9 @@ func (srv *Service) update() error {
|
||||
for i := 0; i < 3; i++ {
|
||||
response, err = ntp.Exchange(srv.ctx, srv.dialer, srv.server)
|
||||
if err != nil {
|
||||
if srv.ctx.Err() != nil {
|
||||
return nil
|
||||
}
|
||||
continue
|
||||
}
|
||||
offset := response.ClockOffset
|
||||
@@ -101,9 +80,7 @@ func (srv *Service) update() error {
|
||||
} else if offset < time.Duration(0) {
|
||||
log.Infoln("System clock is behind NTP time by %s", -offset)
|
||||
}
|
||||
srv.mu.Lock()
|
||||
srv.offset = offset
|
||||
srv.mu.Unlock()
|
||||
srv.offset.Store(int64(offset))
|
||||
if srv.syncSystemTime {
|
||||
timeNow := response.Time
|
||||
syncErr := setSystemTime(timeNow)
|
||||
@@ -120,23 +97,27 @@ func (srv *Service) update() error {
|
||||
}
|
||||
|
||||
func (srv *Service) loopUpdate() {
|
||||
defer srv.offset.Store(0)
|
||||
defer srv.ticker.Stop()
|
||||
for {
|
||||
err := srv.update()
|
||||
if err != nil {
|
||||
log.Warnln("Sync time failed: %s", err)
|
||||
}
|
||||
select {
|
||||
case <-srv.ctx.Done():
|
||||
return
|
||||
case <-srv.ticker.C:
|
||||
}
|
||||
err := srv.update()
|
||||
if err != nil {
|
||||
log.Warnln("Sync time failed: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Now() time.Time {
|
||||
now := time.Now()
|
||||
if offset := globalSrv.Load().Offset(); offset.Abs() > 0 {
|
||||
if service := globalSrv.Load(); service != nil {
|
||||
if offset := service.Offset(); offset.Abs() > 0 {
|
||||
now = now.Add(offset)
|
||||
}
|
||||
}
|
||||
return now
|
||||
}
|
||||
|
||||
@@ -57,15 +57,17 @@ func NewGostWebsocket(ctx context.Context, conn net.Conn, option *Option) (net.C
|
||||
Headers: header,
|
||||
}
|
||||
|
||||
var err error
|
||||
if option.TLS {
|
||||
config.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
config.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: option.Host,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
var err error
|
||||
config.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -75,7 +77,6 @@ func NewGostWebsocket(ctx context.Context, conn net.Conn, option *Option) (net.C
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
conn, err = vmess.StreamWebsocketConn(ctx, conn, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/pool"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -145,7 +145,7 @@ func makeClientHelloMsg(data []byte, server string) []byte {
|
||||
buf.Write([]byte{0x03, 0x03})
|
||||
|
||||
// random with timestamp, sid len, sid
|
||||
binary.Write(buf, binary.BigEndian, uint32(time.Now().Unix()))
|
||||
binary.Write(buf, binary.BigEndian, uint32(ntp.Now().Unix()))
|
||||
buf.Write(random)
|
||||
buf.WriteByte(32)
|
||||
buf.Write(sessionID)
|
||||
|
||||
@@ -33,22 +33,23 @@ type ShadowTLSOption struct {
|
||||
}
|
||||
|
||||
func NewShadowTLS(ctx context.Context, conn net.Conn, option *ShadowTLSOption) (net.Conn, error) {
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: option.ALPN,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
ServerName: option.Host,
|
||||
}
|
||||
if option.Version == 1 {
|
||||
tlsConfig.MaxVersion = tls.VersionTLS12 // ShadowTLS v1 only support TLS 1.2
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if option.Version == 1 {
|
||||
tlsConfig.MaxVersion = tls.VersionTLS12 // ShadowTLS v1 only support TLS 1.2
|
||||
}
|
||||
|
||||
tlsHandshake := uTLSHandshakeFunc(tlsConfig, option.ClientFingerprint, option.Version)
|
||||
client, err := shadowtls.NewClient(shadowtls.ClientConfig{
|
||||
Version: option.Version,
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/pool"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/ssr/tools"
|
||||
|
||||
"github.com/metacubex/randv2"
|
||||
@@ -182,7 +182,7 @@ func packData(buf *bytes.Buffer, data []byte) {
|
||||
}
|
||||
|
||||
func (t *tls12Ticket) packAuthData(buf *bytes.Buffer) {
|
||||
binary.Write(buf, binary.BigEndian, uint32(time.Now().Unix()))
|
||||
binary.Write(buf, binary.BigEndian, uint32(ntp.Now().Unix()))
|
||||
tools.AppendRandBytes(buf, 18)
|
||||
buf.Write(t.hmacSHA1(buf.Bytes()[buf.Len()-22:])[:10])
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/common/pool"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/shadowsocks/core"
|
||||
|
||||
"github.com/metacubex/randv2"
|
||||
@@ -49,7 +49,7 @@ func (a *authData) next() *authData {
|
||||
}
|
||||
|
||||
func (a *authData) putAuthData(buf *bytes.Buffer) {
|
||||
binary.Write(buf, binary.LittleEndian, uint32(time.Now().Unix()))
|
||||
binary.Write(buf, binary.LittleEndian, uint32(ntp.Now().Unix()))
|
||||
buf.Write(a.clientID[:])
|
||||
binary.Write(buf, binary.LittleEndian, a.connectionID)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func (a *authData) putAuthData(buf *bytes.Buffer) {
|
||||
func (a *authData) putEncryptedData(b *bytes.Buffer, userKey []byte, paddings [2]int, salt string) error {
|
||||
encrypt := pool.Get(16)
|
||||
defer pool.Put(encrypt)
|
||||
binary.LittleEndian.PutUint32(encrypt, uint32(time.Now().Unix()))
|
||||
binary.LittleEndian.PutUint32(encrypt, uint32(ntp.Now().Unix()))
|
||||
copy(encrypt[4:], a.clientID[:])
|
||||
binary.LittleEndian.PutUint32(encrypt[8:], a.connectionID)
|
||||
binary.LittleEndian.PutUint16(encrypt[12:], uint16(paddings[0]))
|
||||
|
||||
@@ -43,15 +43,17 @@ func NewV2rayObfs(ctx context.Context, conn net.Conn, option *Option) (net.Conn,
|
||||
Headers: header,
|
||||
}
|
||||
|
||||
var err error
|
||||
if option.TLS {
|
||||
config.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
config.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: option.Host,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
var err error
|
||||
config.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -61,7 +63,6 @@ func NewV2rayObfs(ctx context.Context, conn net.Conn, option *Option) (net.Conn,
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
conn, err = vmess.StreamWebsocketConn(ctx, conn, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -26,14 +26,14 @@ type ECHConfig struct {
|
||||
}
|
||||
|
||||
func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: cfg.Host,
|
||||
InsecureSkipVerify: cfg.SkipCertVerify,
|
||||
NextProtos: cfg.NextProtos,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, cfg.FingerPrint)
|
||||
},
|
||||
Fingerprint: cfg.FingerPrint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.19.13",
|
||||
"mihomo_alpha": "alpha-909729c",
|
||||
"mihomo_alpha": "alpha-4f4f13d",
|
||||
"clash_rs": "v0.9.0",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.9.0-alpha+sha.50f295d"
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2025-09-11T22:20:53.894Z"
|
||||
"updated_at": "2025-09-12T22:20:41.506Z"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,65 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [2.43.0](https://github.com/filebrowser/filebrowser/compare/v2.42.5...v2.43.0) (2025-09-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* "save changes" button to discard changes dialog ([84e8632](https://github.com/filebrowser/filebrowser/commit/84e8632b98e315bfef2da77dd7d1049daec99241))
|
||||
* Translate frontend/src/i18n/en.json in es ([571ce6c](https://github.com/filebrowser/filebrowser/commit/571ce6cb0d7c8725d1cc1a3238ea506ddc72b060))
|
||||
* Translate frontend/src/i18n/en.json in fr ([6b1fa87](https://github.com/filebrowser/filebrowser/commit/6b1fa87ad38ebbb1a9c5d0e5fc88ba796c148bcf))
|
||||
* Updates for project File Browser ([#5427](https://github.com/filebrowser/filebrowser/issues/5427)) ([8950585](https://github.com/filebrowser/filebrowser/commit/89505851414bfcee6b9ff02087eb4cec51c330f6))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* optimize markdown preview height ([783503a](https://github.com/filebrowser/filebrowser/commit/783503aece7fca9e26f7e849b0e7478aba976acb))
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* build(deps): bump github.com/ulikunitz/xz from 0.5.12 to 0.5.14 ([0769265](https://github.com/filebrowser/filebrowser/commit/07692653ffe0ea5e517e6dc1fd3961172e931843))
|
||||
|
||||
|
||||
### Build
|
||||
|
||||
* **deps-dev:** bump vite from 6.1.6 to 6.3.6 in /frontend ([36c6cc2](https://github.com/filebrowser/filebrowser/commit/36c6cc203e10947439519a0413d5817921a1690d))
|
||||
* **deps:** bump github.com/go-viper/mapstructure/v2 in /tools ([280fa56](https://github.com/filebrowser/filebrowser/commit/280fa562a67824887ae6e2530a3b73739d6e1bb4))
|
||||
* **deps:** bump github.com/ulikunitz/xz from 0.5.12 to 0.5.14 ([950028a](https://github.com/filebrowser/filebrowser/commit/950028abebe2898bac4ecfd8715c0967246310cb))
|
||||
|
||||
|
||||
### Refactorings
|
||||
|
||||
* to use strings.Lines ([b482a9b](https://github.com/filebrowser/filebrowser/commit/b482a9bf0d292ec6542d2145a4408971e4c985f1))
|
||||
|
||||
## [2.43.0](https://github.com/filebrowser/filebrowser/compare/v2.42.5...v2.43.0) (2025-09-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* "save changes" button to discard changes dialog ([84e8632](https://github.com/filebrowser/filebrowser/commit/84e8632b98e315bfef2da77dd7d1049daec99241))
|
||||
* Translate frontend/src/i18n/en.json in es ([571ce6c](https://github.com/filebrowser/filebrowser/commit/571ce6cb0d7c8725d1cc1a3238ea506ddc72b060))
|
||||
* Translate frontend/src/i18n/en.json in fr ([6b1fa87](https://github.com/filebrowser/filebrowser/commit/6b1fa87ad38ebbb1a9c5d0e5fc88ba796c148bcf))
|
||||
* Updates for project File Browser ([#5427](https://github.com/filebrowser/filebrowser/issues/5427)) ([8950585](https://github.com/filebrowser/filebrowser/commit/89505851414bfcee6b9ff02087eb4cec51c330f6))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* optimize markdown preview height ([783503a](https://github.com/filebrowser/filebrowser/commit/783503aece7fca9e26f7e849b0e7478aba976acb))
|
||||
|
||||
|
||||
### Build
|
||||
|
||||
* **deps-dev:** bump vite from 6.1.6 to 6.3.6 in /frontend ([36c6cc2](https://github.com/filebrowser/filebrowser/commit/36c6cc203e10947439519a0413d5817921a1690d))
|
||||
* **deps:** bump github.com/go-viper/mapstructure/v2 in /tools ([280fa56](https://github.com/filebrowser/filebrowser/commit/280fa562a67824887ae6e2530a3b73739d6e1bb4))
|
||||
* **deps:** bump github.com/ulikunitz/xz from 0.5.12 to 0.5.14 ([950028a](https://github.com/filebrowser/filebrowser/commit/950028abebe2898bac4ecfd8715c0967246310cb))
|
||||
|
||||
|
||||
### Refactorings
|
||||
|
||||
* to use strings.Lines ([b482a9b](https://github.com/filebrowser/filebrowser/commit/b482a9bf0d292ec6542d2145a4408971e4c985f1))
|
||||
|
||||
### [2.42.5](https://github.com/filebrowser/filebrowser/compare/v2.42.4...v2.42.5) (2025-08-16)
|
||||
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ func (a *HookAuth) GetValues(s string) {
|
||||
s = strings.ReplaceAll(s, "\r\n", "\n")
|
||||
|
||||
// iterate input lines
|
||||
for _, val := range strings.Split(s, "\n") {
|
||||
for val := range strings.Lines(s) {
|
||||
v := strings.SplitN(val, "=", 2)
|
||||
|
||||
// skips non key and value format
|
||||
|
||||
@@ -11,17 +11,26 @@
|
||||
@click="closeHovers"
|
||||
:aria-label="$t('buttons.cancel')"
|
||||
:title="$t('buttons.cancel')"
|
||||
tabindex="2"
|
||||
tabindex="3"
|
||||
>
|
||||
{{ $t("buttons.cancel") }}
|
||||
</button>
|
||||
<button
|
||||
class="button button--flat button--blue"
|
||||
@click="saveAndClose"
|
||||
:aria-label="$t('buttons.saveChanges')"
|
||||
:title="$t('buttons.saveChanges')"
|
||||
tabindex="1"
|
||||
>
|
||||
{{ $t("buttons.saveChanges") }}
|
||||
</button>
|
||||
<button
|
||||
id="focus-prompt"
|
||||
@click="currentPrompt.confirm"
|
||||
class="button button--flat button--red"
|
||||
:aria-label="$t('buttons.discardChanges')"
|
||||
:title="$t('buttons.discardChanges')"
|
||||
tabindex="1"
|
||||
tabindex="2"
|
||||
>
|
||||
{{ $t("buttons.discardChanges") }}
|
||||
</button>
|
||||
@@ -40,6 +49,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useLayoutStore, ["closeHovers"]),
|
||||
saveAndClose() {
|
||||
if (this.currentPrompt?.saveAction) {
|
||||
this.currentPrompt.saveAction();
|
||||
}
|
||||
this.closeHovers();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
.md_preview {
|
||||
overflow-y: auto;
|
||||
max-height: 80vh;
|
||||
padding: 1rem;
|
||||
border: 1px solid #000;
|
||||
font-size: 20px;
|
||||
@@ -9,5 +7,5 @@
|
||||
|
||||
#preview-container {
|
||||
overflow: auto;
|
||||
max-height: 80vh; /* Match the max-height of md_preview for scrolling */
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
"update": "Update",
|
||||
"upload": "Upload",
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard"
|
||||
"discardChanges": "Discard",
|
||||
"saveChanges": "Save changes"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"copy": "Copiar",
|
||||
"copyFile": "Copiar archivo",
|
||||
"copyToClipboard": "Copiar al portapapeles",
|
||||
"copyDownloadLinkToClipboard": "Copy download link to clipboard",
|
||||
"copyDownloadLinkToClipboard": "Copiar enlace de descarga al portapapeles",
|
||||
"create": "Crear",
|
||||
"delete": "Borrar",
|
||||
"download": "Descargar",
|
||||
|
||||
@@ -41,6 +41,7 @@ export const useLayoutStore = defineStore("layout", {
|
||||
prompt: value,
|
||||
confirm: null,
|
||||
action: undefined,
|
||||
saveAction: undefined,
|
||||
props: null,
|
||||
close: null,
|
||||
});
|
||||
@@ -51,6 +52,7 @@ export const useLayoutStore = defineStore("layout", {
|
||||
prompt: value.prompt,
|
||||
confirm: value?.confirm,
|
||||
action: value?.action,
|
||||
saveAction: value?.saveAction,
|
||||
props: value?.props,
|
||||
close: value?.close,
|
||||
});
|
||||
|
||||
1
filebrowser/frontend/src/types/layout.d.ts
vendored
1
filebrowser/frontend/src/types/layout.d.ts
vendored
@@ -2,6 +2,7 @@ interface PopupProps {
|
||||
prompt: string;
|
||||
confirm?: any;
|
||||
action?: PopupAction;
|
||||
saveAction?: () => void;
|
||||
props?: any;
|
||||
close?: (() => Promise<string>) | null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="editor-container" @wheel.prevent.stop>
|
||||
<div id="editor-container">
|
||||
<header-bar>
|
||||
<action icon="close" :label="t('buttons.close')" @action="close()" />
|
||||
<title>{{ fileStore.req?.name ?? "" }}</title>
|
||||
@@ -97,7 +97,6 @@ const isMarkdownFile =
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener("keydown", keyEvent);
|
||||
window.addEventListener("wheel", handleScroll);
|
||||
window.addEventListener("beforeunload", handlePageChange);
|
||||
|
||||
const fileContent = fileStore.req?.content || "";
|
||||
@@ -111,13 +110,6 @@ onMounted(() => {
|
||||
console.error("Failed to convert content to HTML:", error);
|
||||
previewContent.value = "";
|
||||
}
|
||||
|
||||
const previewContainer = document.getElementById("preview-container");
|
||||
if (previewContainer) {
|
||||
previewContainer.addEventListener("wheel", handleScroll, {
|
||||
capture: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -148,7 +140,6 @@ onMounted(() => {
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("keydown", keyEvent);
|
||||
window.removeEventListener("wheel", handleScroll);
|
||||
window.removeEventListener("beforeunload", handlePageChange);
|
||||
editor.value?.destroy();
|
||||
});
|
||||
@@ -166,6 +157,10 @@ onBeforeRouteUpdate((to, from, next) => {
|
||||
event.preventDefault();
|
||||
next();
|
||||
},
|
||||
saveAction: async () => {
|
||||
await save();
|
||||
next();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -186,13 +181,6 @@ const keyEvent = (event: KeyboardEvent) => {
|
||||
save();
|
||||
};
|
||||
|
||||
const handleScroll = (event: WheelEvent) => {
|
||||
const editorContainer = document.getElementById("preview-container");
|
||||
if (editorContainer) {
|
||||
editorContainer.scrollTop += event.deltaY;
|
||||
}
|
||||
};
|
||||
|
||||
const handlePageChange = (event: BeforeUnloadEvent) => {
|
||||
if (!editor.value?.session.getUndoManager().isClean()) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -65,7 +65,7 @@ require (
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.14 // indirect
|
||||
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
|
||||
@@ -232,8 +232,8 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
|
||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.14 h1:uv/0Bq533iFdnMHZdRBTOlaNMdb1+ZxXIlHDZHIHcvg=
|
||||
github.com/ulikunitz/xz v0.5.14/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
|
||||
@@ -7,14 +7,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=erofs-utils
|
||||
PKG_VERSION:=1.8.9
|
||||
PKG_VERSION:=1.8.10
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git
|
||||
PKG_MIRROR_HASH:=dfeeca4e3b1337cf05d2b40f6f3956601b98fba0b6a8d7363071ae366a2020e1
|
||||
PKG_SOURCE_DATE:=2025-06-26
|
||||
PKG_SOURCE_VERSION:=81169bf3cfd26b8f2b3aa3b20da23971168a90a9
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL=https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git/snapshot/
|
||||
PKG_HASH:=05eb4edebe11decce6ecb34e98d2f80c8cd283c2f2967d8ba7efd58418570514
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
|
||||
|
||||
2
mieru/.github/workflows/integration.yaml
vendored
2
mieru/.github/workflows/integration.yaml
vendored
@@ -3,7 +3,7 @@ on: [push, pull_request, workflow_dispatch]
|
||||
jobs:
|
||||
run-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -32,7 +32,7 @@ PROJECT_NAME=$(shell basename "${ROOT}")
|
||||
# - pkg/version/current.go
|
||||
#
|
||||
# Use `tools/bump_version.sh` script to change all those files at one shot.
|
||||
VERSION="3.19.2"
|
||||
VERSION="3.20.0"
|
||||
|
||||
# Build binaries and installation packages.
|
||||
.PHONY: build
|
||||
|
||||
@@ -74,6 +74,10 @@ type ClientNetworkService interface {
|
||||
// DialContext returns a new proxy connection to reach the destination.
|
||||
// It uses the dialer in ClientConfig to connect to a proxy server endpoint.
|
||||
//
|
||||
// If HandshakeMode in ClientConfig is HANDSHAKE_NO_WAIT, handshake is performed
|
||||
// upon the first write to the network connection. Otherwise, handshake is
|
||||
// performed before this method returns.
|
||||
//
|
||||
// This is a streaming based proxy connection. If the destination is a packet
|
||||
// endpoint, packets are encapsulated in the streaming connection.
|
||||
//
|
||||
@@ -84,6 +88,7 @@ type ClientNetworkService interface {
|
||||
|
||||
// ClientConfig stores proxy client configuration.
|
||||
type ClientConfig struct {
|
||||
// Main configuration.
|
||||
Profile *appctlpb.ClientProfile
|
||||
|
||||
// A dialer to connect to proxy server via stream-oriented network connections.
|
||||
|
||||
@@ -246,6 +246,9 @@ func (mc *mieruClient) DialContext(ctx context.Context, addr net.Addr) (net.Conn
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mc.config.Profile.GetHandshakeMode() == appctlpb.HandshakeMode_HANDSHAKE_NO_WAIT {
|
||||
return apicommon.NewEarlyConn(conn, netAddrSpec), nil
|
||||
}
|
||||
return mc.dialPostHandshake(conn, netAddrSpec)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Package: mieru
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: mieru
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy client
|
||||
License: GPLv3+
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Package: mieru
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: mieru
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy client
|
||||
License: GPLv3+
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Package: mita
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: mita
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy server
|
||||
License: GPLv3+
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Package: mita
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: mita
|
||||
Version: 3.19.2
|
||||
Version: 3.20.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy server
|
||||
License: GPLv3+
|
||||
|
||||
@@ -18,32 +18,32 @@ Or you can manually install and configure proxy server using the steps below.
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita_3.19.2_amd64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita_3.20.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita_3.19.2_arm64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita_3.20.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita-3.19.2-1.x86_64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita-3.20.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita-3.19.2-1.aarch64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita-3.20.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
## Install mita package
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
sudo dpkg -i mita_3.19.2_amd64.deb
|
||||
sudo dpkg -i mita_3.20.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
sudo dpkg -i mita_3.19.2_arm64.deb
|
||||
sudo dpkg -i mita_3.20.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
sudo rpm -Uvh --force mita-3.19.2-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-3.20.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
sudo rpm -Uvh --force mita-3.19.2-1.aarch64.rpm
|
||||
sudo rpm -Uvh --force mita-3.20.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
Those instructions can also be used to upgrade the version of mita software package.
|
||||
|
||||
@@ -18,32 +18,32 @@ sudo python3 setup.py --lang=zh
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita_3.19.2_amd64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita_3.20.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita_3.19.2_arm64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita_3.20.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita-3.19.2-1.x86_64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita-3.20.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.19.2/mita-3.19.2-1.aarch64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.20.0/mita-3.20.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
## 安装 mita 软件包
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
sudo dpkg -i mita_3.19.2_amd64.deb
|
||||
sudo dpkg -i mita_3.20.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
sudo dpkg -i mita_3.19.2_arm64.deb
|
||||
sudo dpkg -i mita_3.20.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
sudo rpm -Uvh --force mita-3.19.2-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-3.20.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
sudo rpm -Uvh --force mita-3.19.2-1.aarch64.rpm
|
||||
sudo rpm -Uvh --force mita-3.20.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
上述指令也可以用来升级 mita 软件包的版本。
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
package version
|
||||
|
||||
const (
|
||||
AppVersion = "3.19.2"
|
||||
AppVersion = "3.20.0"
|
||||
)
|
||||
|
||||
@@ -41,6 +41,7 @@ var (
|
||||
serverIP = flag.String("server_ip", "", "IP address of mieru proxy server")
|
||||
serverPort = flag.Int("server_port", 0, "Port number of mieru proxy server")
|
||||
serverProtocol = flag.String("server_protocol", "TCP", "Transport protocol: TCP or UDP")
|
||||
handshakeMode = flag.String("handshake_mode", "HANDSHAKE_STANDARD", "Handshake mode: HANDSHAKE_STANDARD or HANDSHAKE_NO_WAIT")
|
||||
debug = flag.Bool("debug", false, "Display debug messages")
|
||||
)
|
||||
|
||||
@@ -73,6 +74,15 @@ func main() {
|
||||
default:
|
||||
panic(fmt.Sprintf("Transport protocol %q is invalid", *serverProtocol))
|
||||
}
|
||||
var handshakeModeConfig appctlpb.HandshakeMode
|
||||
switch *handshakeMode {
|
||||
case "HANDSHAKE_STANDARD":
|
||||
handshakeModeConfig = appctlpb.HandshakeMode_HANDSHAKE_STANDARD
|
||||
case "HANDSHAKE_NO_WAIT":
|
||||
handshakeModeConfig = appctlpb.HandshakeMode_HANDSHAKE_NO_WAIT
|
||||
default:
|
||||
panic(fmt.Sprintf("Handshake mode %q is invalid", *handshakeMode))
|
||||
}
|
||||
|
||||
c := client.NewClient()
|
||||
if err := c.Store(&client.ClientConfig{
|
||||
@@ -94,6 +104,7 @@ func main() {
|
||||
},
|
||||
},
|
||||
Mtu: proto.Int32(1400),
|
||||
HandshakeMode: &handshakeModeConfig,
|
||||
},
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -35,9 +35,18 @@ sleep 1
|
||||
./mita run &
|
||||
sleep 1
|
||||
|
||||
# Start mieru API client.
|
||||
# Start mieru API clients.
|
||||
./exampleapiclient -port=1081 -username=baozi -password=manlianpenfen \
|
||||
-server_ip=127.0.0.1 -server_port=8964 &
|
||||
-server_ip=127.0.0.1 -server_port=8964 -server_protocol=TCP &
|
||||
sleep 1
|
||||
./exampleapiclient -port=1082 -username=baozi -password=manlianpenfen \
|
||||
-server_ip=127.0.0.1 -server_port=8964 -server_protocol=UDP &
|
||||
sleep 1
|
||||
./exampleapiclient -port=1083 -username=baozi -password=manlianpenfen \
|
||||
-server_ip=127.0.0.1 -server_port=8964 -server_protocol=TCP -handshake_mode=HANDSHAKE_NO_WAIT &
|
||||
sleep 1
|
||||
./exampleapiclient -port=1084 -username=baozi -password=manlianpenfen \
|
||||
-server_ip=127.0.0.1 -server_port=8964 -server_protocol=UDP -handshake_mode=HANDSHAKE_NO_WAIT &
|
||||
sleep 1
|
||||
|
||||
# Run TCP test.
|
||||
|
||||
@@ -105,6 +105,19 @@ if [ "$?" -ne "0" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 UDP associate - TCP with API client - handshake no wait <<<"
|
||||
./socksudpclient -dst_host=127.0.0.1 -dst_port=9090 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1083 \
|
||||
-interval_ms=10 -num_request=100 -num_conn=60
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_client_log
|
||||
print_mieru_client_thread_dump
|
||||
print_mieru_server_thread_dump
|
||||
echo "Test UDP associate - TCP with API client (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Collect profile with UDP associate.
|
||||
./mieru get heap-profile /test/mieru.associate.heap.gz
|
||||
./mita get heap-profile /test/mita.associate.heap.gz
|
||||
|
||||
@@ -149,7 +149,7 @@ fi
|
||||
|
||||
# Start testing.
|
||||
sleep 2
|
||||
echo ">>> socks5 - new connections - TCP <<<"
|
||||
echo ">>> socks5 - new connections - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1080 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
@@ -161,6 +161,16 @@ if [ "$?" -ne "0" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections with API client - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1083 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
echo "TCP - test socks5 new_conn (handshake no wait) with API client failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stop mieru client.
|
||||
./mieru stop
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
|
||||
@@ -55,10 +55,6 @@ if [[ "$?" -ne 0 ]]; then
|
||||
fi
|
||||
./mieru profile cpu start /test/mieru.udp.cpu.gz
|
||||
|
||||
# Start mieru API client.
|
||||
./exampleapiclient -port=1082 -username=baozi -password=manlianpenfen \
|
||||
-server_ip=127.0.0.1 -server_port=8964 -server_protocol=UDP &
|
||||
|
||||
# Start testing.
|
||||
sleep 2
|
||||
echo ">>> socks5 - new connections - UDP <<<"
|
||||
@@ -153,7 +149,7 @@ fi
|
||||
|
||||
# Start testing.
|
||||
sleep 2
|
||||
echo ">>> socks5 - new connections - UDP <<<"
|
||||
echo ">>> socks5 - new connections - UDP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1080 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
@@ -165,6 +161,16 @@ if [ "$?" -ne "0" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections with API client - UDP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1084 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
echo "UDP - test socks5 new_conn (handshake no wait) with API client failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stop mieru client.
|
||||
./mieru stop
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
|
||||
@@ -22,6 +22,7 @@ WORKDIR /test
|
||||
# Copy binaries, data and test script into the container.
|
||||
COPY mihomo mita httpserver sockshttpclient socksudpclient udpserver \
|
||||
test/deploy/mihomo/mihomo-config.yaml \
|
||||
test/deploy/mihomo/mihomo-config-no-wait.yaml \
|
||||
test/deploy/mihomo/server_tcp.json \
|
||||
test/deploy/mihomo/libtest.sh \
|
||||
test/deploy/mihomo/test_tcp.sh \
|
||||
|
||||
19
mieru/test/deploy/mihomo/mihomo-config-no-wait.yaml
Normal file
19
mieru/test/deploy/mihomo/mihomo-config-no-wait.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
dns:
|
||||
enable: true
|
||||
nameserver:
|
||||
- 8.8.8.8
|
||||
log-level: warning
|
||||
mixed-port: 1081
|
||||
mode: rule
|
||||
proxies:
|
||||
- name: mieru
|
||||
type: mieru
|
||||
server: 127.0.0.1
|
||||
port: 8964
|
||||
transport: TCP
|
||||
udp: true
|
||||
username: baozi
|
||||
password: manlianpenfen
|
||||
handshake-mode: HANDSHAKE_NO_WAIT
|
||||
rules:
|
||||
- MATCH,mieru
|
||||
@@ -40,6 +40,8 @@ fi
|
||||
# Start mihomo.
|
||||
./mihomo -f mihomo-config.yaml &
|
||||
sleep 1
|
||||
./mihomo -f mihomo-config-no-wait.yaml &
|
||||
sleep 1
|
||||
|
||||
# Start testing.
|
||||
sleep 2
|
||||
@@ -86,6 +88,50 @@ if [ "$?" -ne "0" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1081 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 new_conn (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> http - new connections - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -proxy_mode=http -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_http_host=127.0.0.1 -local_http_port=1081 \
|
||||
-test_case=new_conn -num_request=1000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test HTTP new_conn (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - reuse one connection - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1081 \
|
||||
-test_case=reuse_conn -test_time_sec=30
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 reuse_conn (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 UDP associate - TCP - handshake no wait <<<"
|
||||
./socksudpclient -dst_host=127.0.0.1 -dst_port=9090 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1081 \
|
||||
-interval_ms=10 -num_request=100 -num_conn=60
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 udp_associate (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Print metrics and memory statistics.
|
||||
print_mieru_server_metrics
|
||||
sleep 1
|
||||
|
||||
@@ -2,7 +2,6 @@ package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -236,6 +235,11 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
DialContext: func(context.Context, string, string) (net.Conn, error) {
|
||||
return instance, nil
|
||||
@@ -245,7 +249,7 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: ca.GetGlobalTLSConfig(&tls.Config{}),
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
|
||||
client := http.Client{
|
||||
|
||||
@@ -167,10 +167,13 @@ func NewHttp(option HttpOption) (*Http, error) {
|
||||
sni = option.SNI
|
||||
}
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
ServerName: sni,
|
||||
}, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -160,14 +160,16 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) {
|
||||
serverName = option.SNI
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: serverName,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
CustomCA: option.CustomCA,
|
||||
CustomCAString: option.CustomCAString,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -141,14 +141,16 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||
serverName = option.SNI
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: serverName,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
CustomCA: option.CustomCA,
|
||||
CustomCAString: option.CustomCAString,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -193,13 +193,14 @@ func (ss *Socks5) clientHandshakeContext(ctx context.Context, c net.Conn, addr s
|
||||
func NewSocks5(option Socks5Option) (*Socks5, error) {
|
||||
var tlsConfig *tls.Config
|
||||
if option.TLS {
|
||||
tlsConfig = &tls.Config{
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
ServerName: option.Server,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -100,14 +100,15 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.
|
||||
}
|
||||
|
||||
wsOpts.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: alpn,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: t.option.SkipCertVerify,
|
||||
ServerName: t.option.SNI,
|
||||
}
|
||||
|
||||
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: t.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -363,15 +364,15 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
NextProtos: option.ALPN,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
ServerName: option.SNI,
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -161,17 +161,20 @@ func (t *Tuic) ProxyInfo() C.ProxyInfo {
|
||||
func NewTuic(option TuicOption) (*Tuic, error) {
|
||||
addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
|
||||
serverName := option.Server
|
||||
tlsConfig := &tls.Config{
|
||||
if option.SNI != "" {
|
||||
serverName = option.SNI
|
||||
}
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: serverName,
|
||||
InsecureSkipVerify: option.SkipCertVerify,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
}
|
||||
if option.SNI != "" {
|
||||
tlsConfig.ServerName = option.SNI
|
||||
}
|
||||
|
||||
var err error
|
||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
||||
},
|
||||
Fingerprint: option.Fingerprint,
|
||||
CustomCA: option.CustomCA,
|
||||
CustomCAString: option.CustomCAString,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -95,14 +95,15 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
||||
}
|
||||
if v.option.TLS {
|
||||
wsOpts.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
|
||||
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -498,10 +499,13 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
}
|
||||
var tlsConfig *tls.Config
|
||||
if option.TLS {
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
ServerName: v.option.ServerName,
|
||||
}, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -123,13 +123,14 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
||||
|
||||
if v.option.TLS {
|
||||
wsOpts.TLS = true
|
||||
tlsConfig := &tls.Config{
|
||||
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
}
|
||||
|
||||
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -501,10 +502,13 @@ func NewVmess(option VmessOption) (*Vmess, error) {
|
||||
}
|
||||
var tlsConfig *tls.Config
|
||||
if option.TLS {
|
||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
||||
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||
ServerName: v.option.ServerName,
|
||||
}, v.option.Fingerprint)
|
||||
},
|
||||
Fingerprint: v.option.Fingerprint,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ import (
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/metacubex/mihomo/common/once"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
)
|
||||
|
||||
var globalCertPool *x509.CertPool
|
||||
@@ -65,18 +67,6 @@ func ResetCertificate() {
|
||||
initializeCertPool()
|
||||
}
|
||||
|
||||
func getCertPool() *x509.CertPool {
|
||||
if globalCertPool == nil {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
if globalCertPool != nil {
|
||||
return globalCertPool
|
||||
}
|
||||
initializeCertPool()
|
||||
}
|
||||
return globalCertPool
|
||||
}
|
||||
|
||||
func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error) {
|
||||
var certificate []byte
|
||||
var err error
|
||||
@@ -99,22 +89,41 @@ func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error)
|
||||
}
|
||||
return certPool, nil
|
||||
} else {
|
||||
return getCertPool(), nil
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
if globalCertPool == nil {
|
||||
initializeCertPool()
|
||||
}
|
||||
return globalCertPool, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetTLSConfig specified fingerprint, customCA and customCAString
|
||||
func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, customCAString string) (_ *tls.Config, err error) {
|
||||
type Option struct {
|
||||
TLSConfig *tls.Config
|
||||
Fingerprint string
|
||||
CustomCA string
|
||||
CustomCAString string
|
||||
ZeroTrust bool
|
||||
}
|
||||
|
||||
func GetTLSConfig(opt Option) (tlsConfig *tls.Config, err error) {
|
||||
tlsConfig = opt.TLSConfig
|
||||
if tlsConfig == nil {
|
||||
tlsConfig = &tls.Config{}
|
||||
}
|
||||
tlsConfig.RootCAs, err = GetCertPool(customCA, customCAString)
|
||||
tlsConfig.Time = ntp.Now
|
||||
|
||||
if opt.ZeroTrust {
|
||||
tlsConfig.RootCAs = zeroTrustCertPool()
|
||||
} else {
|
||||
tlsConfig.RootCAs, err = GetCertPool(opt.CustomCA, opt.CustomCAString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(fingerprint) > 0 {
|
||||
tlsConfig.VerifyPeerCertificate, err = NewFingerprintVerifier(fingerprint)
|
||||
if len(opt.Fingerprint) > 0 {
|
||||
tlsConfig.VerifyPeerCertificate, err = NewFingerprintVerifier(opt.Fingerprint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -123,12 +132,12 @@ func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, cu
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// GetSpecifiedFingerprintTLSConfig specified fingerprint
|
||||
func GetSpecifiedFingerprintTLSConfig(tlsConfig *tls.Config, fingerprint string) (*tls.Config, error) {
|
||||
return GetTLSConfig(tlsConfig, fingerprint, "", "")
|
||||
}
|
||||
|
||||
func GetGlobalTLSConfig(tlsConfig *tls.Config) *tls.Config {
|
||||
tlsConfig, _ = GetTLSConfig(tlsConfig, "", "", "")
|
||||
return tlsConfig
|
||||
}
|
||||
var zeroTrustCertPool = once.OnceValue(func() *x509.CertPool {
|
||||
if len(_CaCertificates) != 0 { // always using embed cert first
|
||||
zeroTrustCertPool := x509.NewCertPool()
|
||||
if zeroTrustCertPool.AppendCertsFromPEM(_CaCertificates) {
|
||||
return zeroTrustCertPool
|
||||
}
|
||||
}
|
||||
return nil // fallback to system pool
|
||||
})
|
||||
|
||||
@@ -2,7 +2,6 @@ package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -28,11 +27,11 @@ func SetUA(UA string) {
|
||||
ua = UA
|
||||
}
|
||||
|
||||
func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader) (*http.Response, error) {
|
||||
return HttpRequestWithProxy(ctx, url, method, header, body, "")
|
||||
}
|
||||
|
||||
func HttpRequestWithProxy(ctx context.Context, url, method string, header map[string][]string, body io.Reader, specialProxy string) (*http.Response, error) {
|
||||
func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader, options ...Option) (*http.Response, error) {
|
||||
opt := option{}
|
||||
for _, o := range options {
|
||||
o(&opt)
|
||||
}
|
||||
method = strings.ToUpper(method)
|
||||
urlRes, err := URL.Parse(url)
|
||||
if err != nil {
|
||||
@@ -40,6 +39,10 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, urlRes.String(), body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range header {
|
||||
for _, v := range v {
|
||||
req.Header.Add(k, v)
|
||||
@@ -50,10 +53,6 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
req.Header.Set("User-Agent", UA())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if user := urlRes.User; user != nil {
|
||||
password, _ := user.Password()
|
||||
req.SetBasicAuth(user.Username(), password)
|
||||
@@ -61,6 +60,11 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(opt.caOption)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
// from http.DefaultTransport
|
||||
DisableKeepAlives: runtime.GOOS == "android",
|
||||
@@ -69,15 +73,34 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
if conn, err := inner.HandleTcp(inner.GetTunnel(), address, specialProxy); err == nil {
|
||||
if conn, err := inner.HandleTcp(inner.GetTunnel(), address, opt.specialProxy); err == nil {
|
||||
return conn, nil
|
||||
} else {
|
||||
return dialer.DialContext(ctx, network, address)
|
||||
}
|
||||
},
|
||||
TLSClientConfig: ca.GetGlobalTLSConfig(&tls.Config{}),
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
|
||||
client := http.Client{Transport: transport}
|
||||
return client.Do(req)
|
||||
}
|
||||
|
||||
type Option func(opt *option)
|
||||
|
||||
type option struct {
|
||||
specialProxy string
|
||||
caOption ca.Option
|
||||
}
|
||||
|
||||
func WithSpecialProxy(name string) Option {
|
||||
return func(opt *option) {
|
||||
opt.specialProxy = name
|
||||
}
|
||||
}
|
||||
|
||||
func WithCAOption(caOption ca.Option) Option {
|
||||
return func(opt *option) {
|
||||
opt.caOption = caOption
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func (h *HTTPVehicle) Read(ctx context.Context, oldHash utils.HashType) (buf []b
|
||||
setIfNoneMatch = true
|
||||
}
|
||||
}
|
||||
resp, err := mihomoHttp.HttpRequestWithProxy(ctx, h.url, http.MethodGet, header, nil, h.proxy)
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, h.url, http.MethodGet, header, nil, mihomoHttp.WithSpecialProxy(h.proxy))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
mihomoHttp "github.com/metacubex/mihomo/component/http"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/features"
|
||||
@@ -171,7 +172,7 @@ func (u *CoreUpdater) Update(currentExePath string, channel string, force bool)
|
||||
func (u *CoreUpdater) getLatestVersion(versionURL string) (version string, err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, versionURL, http.MethodGet, nil, nil)
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, versionURL, http.MethodGet, nil, nil, mihomoHttp.WithCAOption(ca.Option{ZeroTrust: true}))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -194,7 +195,7 @@ func (u *CoreUpdater) getLatestVersion(versionURL string) (version string, err e
|
||||
func (u *CoreUpdater) download(updateDir, packagePath, packageURL string) (err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
|
||||
defer cancel()
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, packageURL, http.MethodGet, nil, nil)
|
||||
resp, err := mihomoHttp.HttpRequest(ctx, packageURL, http.MethodGet, nil, nil, mihomoHttp.WithCAOption(ca.Option{ZeroTrust: true}))
|
||||
if err != nil {
|
||||
return fmt.Errorf("http request failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -48,6 +48,13 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
network = "tcp"
|
||||
}
|
||||
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: c.Client.TLSConfig,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := net.JoinHostPort(c.host, c.port)
|
||||
conn, err := c.dialer.DialContext(ctx, network, addr)
|
||||
if err != nil {
|
||||
@@ -66,7 +73,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
ch := make(chan result, 1)
|
||||
go func() {
|
||||
if strings.HasSuffix(c.Client.Net, "tls") {
|
||||
conn = tls.Client(conn, ca.GetGlobalTLSConfig(c.Client.TLSConfig))
|
||||
conn = tls.Client(conn, tlsConfig)
|
||||
}
|
||||
|
||||
dConn := &D.Conn{
|
||||
|
||||
@@ -397,12 +397,16 @@ func (doh *dnsOverHTTPS) createTransport(ctx context.Context) (t http.RoundTripp
|
||||
return transport, nil
|
||||
}
|
||||
|
||||
tlsConfig := ca.GetGlobalTLSConfig(
|
||||
&tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
InsecureSkipVerify: doh.skipCertVerify,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
SessionTicketsDisabled: false,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var nextProtos []string
|
||||
for _, v := range doh.httpVersions {
|
||||
nextProtos = append(nextProtos, string(v))
|
||||
|
||||
@@ -331,15 +331,19 @@ func (doq *dnsOverQUIC) openConnection(ctx context.Context) (conn *quic.Conn, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := ca.GetGlobalTLSConfig(
|
||||
&tls.Config{
|
||||
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: doq.skipCertVerify,
|
||||
NextProtos: []string{
|
||||
NextProtoDQ,
|
||||
},
|
||||
SessionTicketsDisabled: false,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
transport := quic.Transport{Conn: udp}
|
||||
transport.SetCreatedConn(true) // auto close conn
|
||||
|
||||
@@ -6,7 +6,7 @@ require (
|
||||
github.com/bahlo/generic-list-go v0.2.0
|
||||
github.com/coreos/go-iptables v0.8.0
|
||||
github.com/dlclark/regexp2 v1.11.5
|
||||
github.com/enfein/mieru/v3 v3.19.1
|
||||
github.com/enfein/mieru/v3 v3.20.0
|
||||
github.com/go-chi/chi/v5 v5.2.3
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/gobwas/ws v1.4.0
|
||||
|
||||
@@ -25,8 +25,8 @@ github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZ
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/enfein/mieru/v3 v3.19.1 h1:19b9kgFC7oJXX9RLEO5Pi1gO6yek5cWlpK7IJVUoE8I=
|
||||
github.com/enfein/mieru/v3 v3.19.1/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
|
||||
github.com/enfein/mieru/v3 v3.20.0 h1:1ob7pCIVSH5FYFAfYvim8isLW1vBOS4cFOUF9exJS38=
|
||||
github.com/enfein/mieru/v3 v3.20.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 h1:kXYqH/sL8dS/FdoFjr12ePjnLPorPo2FsnrHNuXSDyo=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I=
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g=
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/tunnel/statistic"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -201,7 +202,7 @@ func startTLS(cfg *Config) {
|
||||
}
|
||||
|
||||
log.Infoln("RESTful API tls listening at: %s", l.Addr().String())
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
|
||||
tlsConfig.Certificates = []tlsC.Certificate{tlsC.UCertificate(cert)}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/anytls/padding"
|
||||
"github.com/metacubex/mihomo/transport/anytls/session"
|
||||
|
||||
@@ -42,7 +43,7 @@ func New(config LC.AnyTLSServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
}
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
if config.Certificate != "" && config.PrivateKey != "" {
|
||||
cert, err := ca.LoadTLSKeyPair(config.Certificate, config.PrivateKey, C.Path)
|
||||
if err != nil {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
authStore "github.com/metacubex/mihomo/listener/auth"
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
)
|
||||
|
||||
type Listener struct {
|
||||
@@ -65,7 +66,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
|
||||
if config.Certificate != "" && config.PrivateKey != "" {
|
||||
|
||||
@@ -39,7 +39,7 @@ var userUUID = utils.NewUUIDV4().String()
|
||||
var tlsCertificate, tlsPrivateKey, tlsFingerprint, _ = ca.NewRandomTLSKeyPair(ca.KeyPairTypeP256)
|
||||
var tlsConfigCert, _ = tls.X509KeyPair([]byte(tlsCertificate), []byte(tlsPrivateKey))
|
||||
var tlsConfig = &tls.Config{Certificates: []tls.Certificate{tlsConfigCert}, NextProtos: []string{"h2", "http/1.1"}}
|
||||
var tlsClientConfig, _ = ca.GetTLSConfig(nil, tlsFingerprint, "", "")
|
||||
var tlsClientConfig, _ = ca.GetTLSConfig(ca.Option{Fingerprint: tlsFingerprint})
|
||||
var realityPrivateKey, realityPublickey string
|
||||
var realityDest = "itunes.apple.com"
|
||||
var realityShortid = "10f897e26c4b9478"
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/metacubex/mihomo/listener/http"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/listener/socks"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/socks4"
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
)
|
||||
@@ -61,7 +62,7 @@ func NewWithConfig(config LC.AuthServer, tunnel C.Tunnel, additions ...inbound.A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
|
||||
if config.Certificate != "" && config.PrivateKey != "" {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
|
||||
"github.com/metacubex/sing-quic/hysteria2"
|
||||
|
||||
@@ -61,6 +62,7 @@ func New(config LC.Hysteria2Server, tunnel C.Tunnel, additions ...inbound.Additi
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig := &tlsC.Config{
|
||||
Time: ntp.Now,
|
||||
MinVersion: tlsC.VersionTLS13,
|
||||
}
|
||||
tlsConfig.Certificates = []tlsC.Certificate{tlsC.UCertificate(cert)}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/reality"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
"github.com/metacubex/mihomo/transport/vless/encryption"
|
||||
mihomoVMess "github.com/metacubex/mihomo/transport/vmess"
|
||||
@@ -75,7 +76,7 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
}()
|
||||
}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
var httpServer http.Server
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ func New(config LC.VmessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
||||
|
||||
sl = &Listener{false, config, nil, service}
|
||||
|
||||
tlsConfig := &tlsC.Config{}
|
||||
tlsConfig := &tlsC.Config{Time: ntp.Now}
|
||||
var realityBuilder *reality.Builder
|
||||
var httpServer http.Server
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user