mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-20 09:00:04 +08:00
chore: cleanup internal ca using
This commit is contained in:
parent
08fc100c85
commit
57e14e5b62
@ -2,7 +2,6 @@ package adapter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
@ -236,6 +235,11 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In
|
|||||||
}
|
}
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
|
tlsConfig, err := ca.GetTLSConfig(ca.Option{})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
DialContext: func(context.Context, string, string) (net.Conn, error) {
|
DialContext: func(context.Context, string, string) (net.Conn, error) {
|
||||||
return instance, nil
|
return instance, nil
|
||||||
@ -245,7 +249,7 @@ func (p *Proxy) URLTest(ctx context.Context, url string, expectedStatus utils.In
|
|||||||
IdleConnTimeout: 90 * time.Second,
|
IdleConnTimeout: 90 * time.Second,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
TLSClientConfig: ca.GetGlobalTLSConfig(&tls.Config{}),
|
TLSClientConfig: tlsConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
client := http.Client{
|
client := http.Client{
|
||||||
|
|||||||
@ -167,10 +167,13 @@ func NewHttp(option HttpOption) (*Http, error) {
|
|||||||
sni = option.SNI
|
sni = option.SNI
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
TLSConfig: &tls.Config{
|
||||||
ServerName: sni,
|
InsecureSkipVerify: option.SkipCertVerify,
|
||||||
}, option.Fingerprint)
|
ServerName: sni,
|
||||||
|
},
|
||||||
|
Fingerprint: option.Fingerprint,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -167,7 +167,7 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
tlsConfig, err = ca.GetTLSConfig(ca.Option{TLSConfig: tlsConfig, Fingerprint: option.Fingerprint, CustomCA: option.CustomCA, CustomCAString: option.CustomCAString})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,7 +148,7 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
tlsConfig, err = ca.GetTLSConfig(ca.Option{TLSConfig: tlsConfig, Fingerprint: option.Fingerprint, CustomCA: option.CustomCA, CustomCAString: option.CustomCAString})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
func NewSocks5(option Socks5Option) (*Socks5, error) {
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *tls.Config
|
||||||
if option.TLS {
|
if option.TLS {
|
||||||
tlsConfig = &tls.Config{
|
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
|
||||||
ServerName: option.Server,
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
|
TLSConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: option.SkipCertVerify,
|
||||||
|
ServerName: option.Server,
|
||||||
|
},
|
||||||
|
Fingerprint: option.Fingerprint,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,14 +100,15 @@ func (t *Trojan) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.
|
|||||||
}
|
}
|
||||||
|
|
||||||
wsOpts.TLS = true
|
wsOpts.TLS = true
|
||||||
tlsConfig := &tls.Config{
|
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
NextProtos: alpn,
|
TLSConfig: &tls.Config{
|
||||||
MinVersion: tls.VersionTLS12,
|
NextProtos: alpn,
|
||||||
InsecureSkipVerify: t.option.SkipCertVerify,
|
MinVersion: tls.VersionTLS12,
|
||||||
ServerName: t.option.SNI,
|
InsecureSkipVerify: t.option.SkipCertVerify,
|
||||||
}
|
ServerName: t.option.SNI,
|
||||||
|
},
|
||||||
wsOpts.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, t.option.Fingerprint)
|
Fingerprint: t.option.Fingerprint,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -363,15 +364,15 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||||
NextProtos: option.ALPN,
|
TLSConfig: &tls.Config{
|
||||||
MinVersion: tls.VersionTLS12,
|
NextProtos: option.ALPN,
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
MinVersion: tls.VersionTLS12,
|
||||||
ServerName: option.SNI,
|
InsecureSkipVerify: option.SkipCertVerify,
|
||||||
}
|
ServerName: option.SNI,
|
||||||
|
},
|
||||||
var err error
|
Fingerprint: option.Fingerprint,
|
||||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,7 +171,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
tlsConfig, err = ca.GetTLSConfig(tlsConfig, option.Fingerprint, option.CustomCA, option.CustomCAString)
|
tlsConfig, err = ca.GetTLSConfig(ca.Option{TLSConfig: tlsConfig, Fingerprint: option.Fingerprint, CustomCA: option.CustomCA, CustomCAString: option.CustomCAString})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,14 +95,15 @@ func (v *Vless) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
|||||||
}
|
}
|
||||||
if v.option.TLS {
|
if v.option.TLS {
|
||||||
wsOpts.TLS = true
|
wsOpts.TLS = true
|
||||||
tlsConfig := &tls.Config{
|
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
MinVersion: tls.VersionTLS12,
|
TLSConfig: &tls.Config{
|
||||||
ServerName: host,
|
MinVersion: tls.VersionTLS12,
|
||||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
ServerName: host,
|
||||||
NextProtos: []string{"http/1.1"},
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -498,10 +499,13 @@ func NewVless(option VlessOption) (*Vless, error) {
|
|||||||
}
|
}
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *tls.Config
|
||||||
if option.TLS {
|
if option.TLS {
|
||||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
TLSConfig: &tls.Config{
|
||||||
ServerName: v.option.ServerName,
|
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||||
}, v.option.Fingerprint)
|
ServerName: v.option.ServerName,
|
||||||
|
},
|
||||||
|
Fingerprint: v.option.Fingerprint,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -123,13 +123,14 @@ func (v *Vmess) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.M
|
|||||||
|
|
||||||
if v.option.TLS {
|
if v.option.TLS {
|
||||||
wsOpts.TLS = true
|
wsOpts.TLS = true
|
||||||
tlsConfig := &tls.Config{
|
wsOpts.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
ServerName: host,
|
TLSConfig: &tls.Config{
|
||||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
ServerName: host,
|
||||||
NextProtos: []string{"http/1.1"},
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -501,10 +502,13 @@ func NewVmess(option VmessOption) (*Vmess, error) {
|
|||||||
}
|
}
|
||||||
var tlsConfig *tls.Config
|
var tlsConfig *tls.Config
|
||||||
if option.TLS {
|
if option.TLS {
|
||||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(&tls.Config{
|
tlsConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
InsecureSkipVerify: v.option.SkipCertVerify,
|
TLSConfig: &tls.Config{
|
||||||
ServerName: v.option.ServerName,
|
InsecureSkipVerify: v.option.SkipCertVerify,
|
||||||
}, v.option.Fingerprint)
|
ServerName: v.option.ServerName,
|
||||||
|
},
|
||||||
|
Fingerprint: v.option.Fingerprint,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/common/once"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,18 +66,6 @@ func ResetCertificate() {
|
|||||||
initializeCertPool()
|
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) {
|
func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error) {
|
||||||
var certificate []byte
|
var certificate []byte
|
||||||
var err error
|
var err error
|
||||||
@ -99,22 +88,40 @@ func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error)
|
|||||||
}
|
}
|
||||||
return certPool, nil
|
return certPool, nil
|
||||||
} else {
|
} else {
|
||||||
return getCertPool(), nil
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
if globalCertPool == nil {
|
||||||
|
initializeCertPool()
|
||||||
|
}
|
||||||
|
return globalCertPool, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTLSConfig specified fingerprint, customCA and customCAString
|
type Option struct {
|
||||||
func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, customCAString string) (_ *tls.Config, err error) {
|
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 {
|
if tlsConfig == nil {
|
||||||
tlsConfig = &tls.Config{}
|
tlsConfig = &tls.Config{}
|
||||||
}
|
}
|
||||||
tlsConfig.RootCAs, err = GetCertPool(customCA, customCAString)
|
|
||||||
if err != nil {
|
if opt.ZeroTrust {
|
||||||
return nil, err
|
tlsConfig.RootCAs = zeroTrustCertPool()
|
||||||
|
} else {
|
||||||
|
tlsConfig.RootCAs, err = GetCertPool(opt.CustomCA, opt.CustomCAString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(fingerprint) > 0 {
|
if len(opt.Fingerprint) > 0 {
|
||||||
tlsConfig.VerifyPeerCertificate, err = NewFingerprintVerifier(fingerprint)
|
tlsConfig.VerifyPeerCertificate, err = NewFingerprintVerifier(opt.Fingerprint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -123,12 +130,12 @@ func GetTLSConfig(tlsConfig *tls.Config, fingerprint string, customCA string, cu
|
|||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSpecifiedFingerprintTLSConfig specified fingerprint
|
var zeroTrustCertPool = once.OnceValue(func() *x509.CertPool {
|
||||||
func GetSpecifiedFingerprintTLSConfig(tlsConfig *tls.Config, fingerprint string) (*tls.Config, error) {
|
if len(_CaCertificates) != 0 { // always using embed cert first
|
||||||
return GetTLSConfig(tlsConfig, fingerprint, "", "")
|
zeroTrustCertPool := x509.NewCertPool()
|
||||||
}
|
if zeroTrustCertPool.AppendCertsFromPEM(_CaCertificates) {
|
||||||
|
return zeroTrustCertPool
|
||||||
func GetGlobalTLSConfig(tlsConfig *tls.Config) *tls.Config {
|
}
|
||||||
tlsConfig, _ = GetTLSConfig(tlsConfig, "", "", "")
|
}
|
||||||
return tlsConfig
|
return nil // fallback to system pool
|
||||||
}
|
})
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -28,11 +27,11 @@ func SetUA(UA string) {
|
|||||||
ua = UA
|
ua = UA
|
||||||
}
|
}
|
||||||
|
|
||||||
func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader) (*http.Response, error) {
|
func HttpRequest(ctx context.Context, url, method string, header map[string][]string, body io.Reader, options ...Option) (*http.Response, error) {
|
||||||
return HttpRequestWithProxy(ctx, url, method, header, body, "")
|
opt := option{}
|
||||||
}
|
for _, o := range options {
|
||||||
|
o(&opt)
|
||||||
func HttpRequestWithProxy(ctx context.Context, url, method string, header map[string][]string, body io.Reader, specialProxy string) (*http.Response, error) {
|
}
|
||||||
method = strings.ToUpper(method)
|
method = strings.ToUpper(method)
|
||||||
urlRes, err := URL.Parse(url)
|
urlRes, err := URL.Parse(url)
|
||||||
if err != nil {
|
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)
|
req, err := http.NewRequest(method, urlRes.String(), body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
for k, v := range header {
|
for k, v := range header {
|
||||||
for _, v := range v {
|
for _, v := range v {
|
||||||
req.Header.Add(k, 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())
|
req.Header.Set("User-Agent", UA())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if user := urlRes.User; user != nil {
|
if user := urlRes.User; user != nil {
|
||||||
password, _ := user.Password()
|
password, _ := user.Password()
|
||||||
req.SetBasicAuth(user.Username(), 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)
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
|
tlsConfig, err := ca.GetTLSConfig(opt.caOption)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
// from http.DefaultTransport
|
// from http.DefaultTransport
|
||||||
DisableKeepAlives: runtime.GOOS == "android",
|
DisableKeepAlives: runtime.GOOS == "android",
|
||||||
@ -69,15 +73,34 @@ func HttpRequestWithProxy(ctx context.Context, url, method string, header map[st
|
|||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
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
|
return conn, nil
|
||||||
} else {
|
} else {
|
||||||
return dialer.DialContext(ctx, network, address)
|
return dialer.DialContext(ctx, network, address)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TLSClientConfig: ca.GetGlobalTLSConfig(&tls.Config{}),
|
TLSClientConfig: tlsConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
client := http.Client{Transport: transport}
|
client := http.Client{Transport: transport}
|
||||||
return client.Do(req)
|
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
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/component/ca"
|
||||||
mihomoHttp "github.com/metacubex/mihomo/component/http"
|
mihomoHttp "github.com/metacubex/mihomo/component/http"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/constant/features"
|
"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) {
|
func (u *CoreUpdater) getLatestVersion(versionURL string) (version string, err error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
defer cancel()
|
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 {
|
if err != nil {
|
||||||
return "", err
|
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) {
|
func (u *CoreUpdater) download(updateDir, packagePath, packageURL string) (err error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
|
||||||
defer cancel()
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("http request failed: %w", err)
|
return fmt.Errorf("http request failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,11 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
|||||||
network = "tcp"
|
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)
|
addr := net.JoinHostPort(c.host, c.port)
|
||||||
conn, err := c.dialer.DialContext(ctx, network, addr)
|
conn, err := c.dialer.DialContext(ctx, network, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -66,7 +71,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
|||||||
ch := make(chan result, 1)
|
ch := make(chan result, 1)
|
||||||
go func() {
|
go func() {
|
||||||
if strings.HasSuffix(c.Client.Net, "tls") {
|
if strings.HasSuffix(c.Client.Net, "tls") {
|
||||||
conn = tls.Client(conn, ca.GetGlobalTLSConfig(c.Client.TLSConfig))
|
conn = tls.Client(conn, tlsConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
dConn := &D.Conn{
|
dConn := &D.Conn{
|
||||||
|
|||||||
14
dns/doh.go
14
dns/doh.go
@ -397,12 +397,14 @@ func (doh *dnsOverHTTPS) createTransport(ctx context.Context) (t http.RoundTripp
|
|||||||
return transport, nil
|
return transport, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig := ca.GetGlobalTLSConfig(
|
tlsConfig, err := ca.GetTLSConfig(ca.Option{TLSConfig: &tls.Config{
|
||||||
&tls.Config{
|
InsecureSkipVerify: doh.skipCertVerify,
|
||||||
InsecureSkipVerify: doh.skipCertVerify,
|
MinVersion: tls.VersionTLS12,
|
||||||
MinVersion: tls.VersionTLS12,
|
SessionTicketsDisabled: false,
|
||||||
SessionTicketsDisabled: false,
|
}})
|
||||||
})
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
var nextProtos []string
|
var nextProtos []string
|
||||||
for _, v := range doh.httpVersions {
|
for _, v := range doh.httpVersions {
|
||||||
nextProtos = append(nextProtos, string(v))
|
nextProtos = append(nextProtos, string(v))
|
||||||
|
|||||||
20
dns/doq.go
20
dns/doq.go
@ -331,15 +331,17 @@ func (doq *dnsOverQUIC) openConnection(ctx context.Context) (conn *quic.Conn, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig := ca.GetGlobalTLSConfig(
|
tlsConfig, err := ca.GetTLSConfig(ca.Option{TLSConfig: &tls.Config{
|
||||||
&tls.Config{
|
ServerName: host,
|
||||||
ServerName: host,
|
InsecureSkipVerify: doq.skipCertVerify,
|
||||||
InsecureSkipVerify: doq.skipCertVerify,
|
NextProtos: []string{
|
||||||
NextProtos: []string{
|
NextProtoDQ,
|
||||||
NextProtoDQ,
|
},
|
||||||
},
|
SessionTicketsDisabled: false,
|
||||||
SessionTicketsDisabled: false,
|
}})
|
||||||
})
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
transport := quic.Transport{Conn: udp}
|
transport := quic.Transport{Conn: udp}
|
||||||
transport.SetCreatedConn(true) // auto close conn
|
transport.SetCreatedConn(true) // auto close conn
|
||||||
|
|||||||
@ -39,7 +39,7 @@ var userUUID = utils.NewUUIDV4().String()
|
|||||||
var tlsCertificate, tlsPrivateKey, tlsFingerprint, _ = ca.NewRandomTLSKeyPair(ca.KeyPairTypeP256)
|
var tlsCertificate, tlsPrivateKey, tlsFingerprint, _ = ca.NewRandomTLSKeyPair(ca.KeyPairTypeP256)
|
||||||
var tlsConfigCert, _ = tls.X509KeyPair([]byte(tlsCertificate), []byte(tlsPrivateKey))
|
var tlsConfigCert, _ = tls.X509KeyPair([]byte(tlsCertificate), []byte(tlsPrivateKey))
|
||||||
var tlsConfig = &tls.Config{Certificates: []tls.Certificate{tlsConfigCert}, NextProtos: []string{"h2", "http/1.1"}}
|
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 realityPrivateKey, realityPublickey string
|
||||||
var realityDest = "itunes.apple.com"
|
var realityDest = "itunes.apple.com"
|
||||||
var realityShortid = "10f897e26c4b9478"
|
var realityShortid = "10f897e26c4b9478"
|
||||||
|
|||||||
@ -57,15 +57,17 @@ func NewGostWebsocket(ctx context.Context, conn net.Conn, option *Option) (net.C
|
|||||||
Headers: header,
|
Headers: header,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
if option.TLS {
|
if option.TLS {
|
||||||
config.TLS = true
|
config.TLS = true
|
||||||
tlsConfig := &tls.Config{
|
config.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
ServerName: option.Host,
|
TLSConfig: &tls.Config{
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
ServerName: option.Host,
|
||||||
NextProtos: []string{"http/1.1"},
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
conn, err = vmess.StreamWebsocketConn(ctx, conn, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@ -33,22 +33,23 @@ type ShadowTLSOption struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewShadowTLS(ctx context.Context, conn net.Conn, option *ShadowTLSOption) (net.Conn, error) {
|
func NewShadowTLS(ctx context.Context, conn net.Conn, option *ShadowTLSOption) (net.Conn, error) {
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||||
NextProtos: option.ALPN,
|
TLSConfig: &tls.Config{
|
||||||
MinVersion: tls.VersionTLS12,
|
NextProtos: option.ALPN,
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
MinVersion: tls.VersionTLS12,
|
||||||
ServerName: option.Host,
|
InsecureSkipVerify: option.SkipCertVerify,
|
||||||
}
|
ServerName: option.Host,
|
||||||
if option.Version == 1 {
|
},
|
||||||
tlsConfig.MaxVersion = tls.VersionTLS12 // ShadowTLS v1 only support TLS 1.2
|
Fingerprint: option.Fingerprint,
|
||||||
}
|
})
|
||||||
|
|
||||||
var err error
|
|
||||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
tlsHandshake := uTLSHandshakeFunc(tlsConfig, option.ClientFingerprint, option.Version)
|
||||||
client, err := shadowtls.NewClient(shadowtls.ClientConfig{
|
client, err := shadowtls.NewClient(shadowtls.ClientConfig{
|
||||||
Version: option.Version,
|
Version: option.Version,
|
||||||
|
|||||||
@ -43,15 +43,17 @@ func NewV2rayObfs(ctx context.Context, conn net.Conn, option *Option) (net.Conn,
|
|||||||
Headers: header,
|
Headers: header,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
if option.TLS {
|
if option.TLS {
|
||||||
config.TLS = true
|
config.TLS = true
|
||||||
tlsConfig := &tls.Config{
|
config.TLSConfig, err = ca.GetTLSConfig(ca.Option{
|
||||||
ServerName: option.Host,
|
TLSConfig: &tls.Config{
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
ServerName: option.Host,
|
||||||
NextProtos: []string{"http/1.1"},
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
conn, err = vmess.StreamWebsocketConn(ctx, conn, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@ -26,14 +26,14 @@ type ECHConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
|
func StreamTLSConn(ctx context.Context, conn net.Conn, cfg *TLSConfig) (net.Conn, error) {
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig, err := ca.GetTLSConfig(ca.Option{
|
||||||
ServerName: cfg.Host,
|
TLSConfig: &tls.Config{
|
||||||
InsecureSkipVerify: cfg.SkipCertVerify,
|
ServerName: cfg.Host,
|
||||||
NextProtos: cfg.NextProtos,
|
InsecureSkipVerify: cfg.SkipCertVerify,
|
||||||
}
|
NextProtos: cfg.NextProtos,
|
||||||
|
},
|
||||||
var err error
|
Fingerprint: cfg.FingerPrint,
|
||||||
tlsConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, cfg.FingerPrint)
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user