Skip to content

Commit 71ed0a0

Browse files
committed
feat: 添加自定义HTTPUA
1 parent c59c3fa commit 71ed0a0

File tree

3 files changed

+82
-17
lines changed

3 files changed

+82
-17
lines changed

config/config.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type General struct {
6363
EBpf EBpf `json:"-"`
6464
GlobalClientFingerprint string `json:"global-client-fingerprint"`
6565
GlobalUA string `json:"global-ua"`
66+
HttpUA string `json:"http-ua"`
6667
}
6768

6869
// Inbound config
@@ -302,6 +303,7 @@ type RawConfig struct {
302303
FindProcessMode P.FindProcessMode `yaml:"find-process-mode" json:"find-process-mode"`
303304
GlobalClientFingerprint string `yaml:"global-client-fingerprint"`
304305
GlobalUA string `yaml:"global-ua"`
306+
HttpUA string `yaml:"http-ua"`
305307
KeepAliveInterval int `yaml:"keep-alive-interval"`
306308

307309
Sniffer RawSniffer `yaml:"sniffer" json:"sniffer"`
@@ -384,6 +386,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
384386
UnifiedDelay: false,
385387
Authentication: []string{},
386388
LogLevel: log.INFO,
389+
HttpUA: "",
387390
Hosts: map[string]any{},
388391
Rule: []string{},
389392
Proxy: []map[string]any{},
@@ -482,7 +485,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
482485
if err := yaml.Unmarshal(buf, rawCfg); err != nil {
483486
return nil, err
484487
}
485-
488+
486489
return rawCfg, nil
487490
}
488491

@@ -657,6 +660,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
657660
EBpf: cfg.EBpf,
658661
GlobalClientFingerprint: cfg.GlobalClientFingerprint,
659662
GlobalUA: cfg.GlobalUA,
663+
HttpUA: cfg.HttpUA,
660664
}, nil
661665
}
662666

hub/executor/executor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
114114
tunnel.OnRunning()
115115

116116
log.SetLevel(cfg.General.LogLevel)
117+
tunnel.SetHttpUA(cfg.General.HttpUA)
117118
}
118119

119120
func initInnerTcp() {

tunnel/tunnel.go

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tunnel
22

33
import (
4+
"bytes"
45
"context"
56
"fmt"
67
"net"
@@ -46,13 +47,15 @@ var (
4647

4748
http_cache = cache.New[string, bool](cache.WithAge[string, bool](30))
4849

49-
5050
// default timeout for UDP session
5151
udpTimeout = 60 * time.Second
5252

5353
findProcessMode P.FindProcessMode
5454

5555
fakeIPRange netip.Prefix
56+
57+
// HTTPUA
58+
http_ua string
5659
)
5760

5861
type tunnel struct{}
@@ -211,6 +214,10 @@ func SetMode(m TunnelMode) {
211214
mode = m
212215
}
213216

217+
func SetHttpUA(m string) {
218+
http_ua = m
219+
}
220+
214221
// SetFindProcessMode replace SetAlwaysFindProcess
215222
// always find process info if legacyAlways = true or mode.Always() = true, may be increase many memory
216223
func SetFindProcessMode(mode P.FindProcessMode) {
@@ -449,6 +456,35 @@ func handleUDPConn(packet C.PacketAdapter) {
449456
}()
450457
}
451458

459+
func showConn(conn *N.BufferedConn) {
460+
connByte, err := conn.Peek(conn.Buffered())
461+
if err != nil {
462+
fmt.Println("Error reading:", err)
463+
}
464+
log.Infoln(string(connByte))
465+
}
466+
467+
func replaceHeader(request []byte, key string, value string) ([]byte, string) {
468+
keyBtye := []byte(key)
469+
start := bytes.Index(request, keyBtye)
470+
if start == -1 {
471+
return request, ""
472+
}
473+
start += len(keyBtye)
474+
end := bytes.Index(request[start:], []byte("\r\n"))
475+
if end == -1 {
476+
return request, ""
477+
}
478+
end += start
479+
480+
// 构建新的请求字节数组
481+
var result []byte
482+
result = append(result, request[:start]...)
483+
result = append(result, []byte(value)...)
484+
result = append(result, request[end:]...)
485+
return result, string(request[start:end])
486+
}
487+
452488
func handleTCPConn(connCtx C.ConnContext) {
453489
if !isHandle(connCtx.Metadata().Type) {
454490
_ = connCtx.Conn().Close()
@@ -499,23 +535,37 @@ func handleTCPConn(connCtx C.ConnContext) {
499535
_ = conn.SetReadDeadline(time.Time{})
500536
}()
501537
}
502-
538+
503539
var peekBytes []byte
504-
540+
505541
address := metadata.RemoteAddress()
506-
if http_cache.Exist(address) {
542+
peekBytes, _ = conn.Peek(4)
543+
peekStr := string(peekBytes)
544+
if peekStr == "" {
545+
log.Infoln("[SETUA] 无UA信息")
546+
conn.Close()
547+
}
548+
if isHTTPRequest(peekStr) && http_ua != "" {
549+
log.Infoln("[SETUA] %s --> %s", address, peekStr)
507550
metadata.Http = true
508551
http_cache.Set(address, true)
509-
log.Debugln("[TCP] %s --> %s", address, "HTTP")
510-
} else {
511-
peekBytes, _ = conn.Peek(4)
512-
peekStr := string(peekBytes)
513-
log.Debugln("[TCP] %s --> %s", address, peekStr)
514-
if isHTTPRequest(peekStr) {
515-
metadata.Http = true
516-
http_cache.Set(address, true)
517-
}
518-
}
552+
log.Infoln("发现HTTP")
553+
}
554+
// if http_cache.Exist(address) {
555+
// metadata.Http = true
556+
// http_cache.Set(address, true)
557+
// log.Infoln("[TCP] %s --> %s", address, "HTTP")
558+
// log.Infoln("缓存读取HTTP")
559+
// } else {
560+
// peekBytes, _ = conn.Peek(4)
561+
// peekStr := string(peekBytes)
562+
// log.Infoln("[TCP] %s --> %s", address, peekStr)
563+
// if isHTTPRequest(peekStr) {
564+
// metadata.Http = true
565+
// http_cache.Set(address, true)
566+
// log.Infoln("发现HTTP")
567+
// }
568+
// }
519569

520570
proxy, rule, err := resolveMetadata(metadata)
521571
if err != nil {
@@ -542,11 +592,22 @@ func handleTCPConn(connCtx C.ConnContext) {
542592
remoteConn, err = proxy.DialContext(ctx, dialMetadata)
543593
if err != nil {
544594
conn.Close()
595+
remoteConn.Close()
545596
return
546597
}
547598

548599
peekBytes, _ = conn.Peek(conn.Buffered())
549-
_, err = remoteConn.Write(peekBytes)
600+
if metadata.Http {
601+
if conn.Buffered() == 0 {
602+
conn.Close()
603+
return
604+
}
605+
peekBytes, ua := replaceHeader(peekBytes, "User-Agent: ", "FFF")
606+
log.Infoln("[SETUA] %s --> %s set %s -> %s", metadata.SourceDetail(), metadata.RemoteAddress(), ua, "FFF")
607+
_, err = remoteConn.Write(peekBytes)
608+
} else {
609+
_, err = remoteConn.Write(peekBytes)
610+
}
550611
if N.NeedHandshake(remoteConn) {
551612
defer func() {
552613
for _, chain := range remoteConn.Chains() {
@@ -589,7 +650,6 @@ func handleTCPConn(connCtx C.ConnContext) {
589650
conn.Close()
590651
return
591652
}
592-
593653
remoteConn = statistic.NewTCPTracker(remoteConn, statistic.DefaultManager, metadata, rule, 0, int64(peekLen), true)
594654
defer func(remoteConn C.Conn) {
595655
_ = remoteConn.Close()

0 commit comments

Comments
 (0)