🎨 Add TLS browser fingerprint implementation (#14934)

Resolves: siyuan-note/siyuan#14933
This commit is contained in:
DDD-HHY 2025-05-29 18:04:50 +08:00 committed by GitHub
parent cf8acfa633
commit f535a13372
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 95 additions and 6 deletions

View file

@ -38,7 +38,6 @@ import (
"github.com/88250/lute/html"
"github.com/88250/lute/parse"
"github.com/gabriel-vasile/mimetype"
"github.com/imroc/req/v3"
"github.com/siyuan-note/filelock"
"github.com/siyuan-note/httpclient"
"github.com/siyuan-note/logging"
@ -101,11 +100,8 @@ func NetAssets2LocalAssets(rootID string, onlyImg bool, originalURL string) (err
}
}
browserClient := req.C().
SetUserAgent(util.UserAgent).
SetTimeout(30 * time.Second).
EnableInsecureSkipVerify().
SetProxy(httpclient.ProxyFromEnvironment)
browserClient := util.CreateCustomReqClient().
EnableInsecureSkipVerify() // 添加了自定义TLS指纹, 可以完成对于CDN的资源下载
forbiddenCount := 0
destNodes := getRemoteAssetsLinkDestsInTree(tree, onlyImg)

93
kernel/util/tls.go Normal file
View file

@ -0,0 +1,93 @@
// SiYuan - Refactor your thinking
// Copyright (c) 2020-present, b3log.org
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package util
import (
"crypto/tls"
"net"
"net/http"
"time"
"github.com/imroc/req/v3"
"github.com/siyuan-note/httpclient"
)
// createCustomTLSConfig 创建自定义 TLS 配置
func createCustomTLSConfig() *tls.Config {
return &tls.Config{
InsecureSkipVerify: false,
MinVersion: tls.VersionTLS12,
MaxVersion: tls.VersionTLS13,
// 模拟 Chrome 的密码套件顺序
CipherSuites: []uint16{
tls.TLS_AES_128_GCM_SHA256,
tls.TLS_AES_256_GCM_SHA384,
tls.TLS_CHACHA20_POLY1305_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
},
CurvePreferences: []tls.CurveID{
tls.X25519,
tls.CurveP256,
tls.CurveP384,
},
}
}
// CreateCustomHTTPClient 创建自定义 HTTP 客户端
func CreateCustomHTTPClient() *http.Client {
dialer := &net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}
transport := &http.Transport{
TLSClientConfig: createCustomTLSConfig(),
DialContext: dialer.DialContext,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
ForceAttemptHTTP2: false,
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
}
return &http.Client{
Transport: transport,
Timeout: 60 * time.Second,
}
}
// CreateCustomReqClient 创建自定义 req 客户端
func CreateCustomReqClient() *req.Client {
client := req.C()
client.SetTLSClientConfig(createCustomTLSConfig())
client.SetUserAgent(UserAgent).
SetTimeout(30 * time.Second).
SetProxy(httpclient.ProxyFromEnvironment)
return client
}