diff --git a/adapter/outbound/trojan.go b/adapter/outbound/trojan.go index 3390c577..b868eb8d 100644 --- a/adapter/outbound/trojan.go +++ b/adapter/outbound/trojan.go @@ -356,6 +356,7 @@ func NewTrojan(option TrojanOption) (*Trojan, error) { t.gunTLSConfig = tlsConfig t.gunConfig = &gun.Config{ ServiceName: option.GrpcOpts.GrpcServiceName, + UserAgent: option.GrpcOpts.GrpcUserAgent, Host: option.SNI, ClientFingerprint: option.ClientFingerprint, } diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index 3ca1bb9f..603d433e 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -462,6 +462,7 @@ func NewVless(option VlessOption) (*Vless, error) { gunConfig := &gun.Config{ ServiceName: v.option.GrpcOpts.GrpcServiceName, + UserAgent: v.option.GrpcOpts.GrpcUserAgent, Host: v.option.ServerName, ClientFingerprint: v.option.ClientFingerprint, } diff --git a/adapter/outbound/vmess.go b/adapter/outbound/vmess.go index 5654cd7c..c9656bd9 100644 --- a/adapter/outbound/vmess.go +++ b/adapter/outbound/vmess.go @@ -86,6 +86,7 @@ type HTTP2Options struct { type GrpcOptions struct { GrpcServiceName string `proxy:"grpc-service-name,omitempty"` + GrpcUserAgent string `proxy:"grpc-user-agent,omitempty"` } type WSOptions struct { @@ -467,6 +468,7 @@ func NewVmess(option VmessOption) (*Vmess, error) { gunConfig := &gun.Config{ ServiceName: v.option.GrpcOpts.GrpcServiceName, + UserAgent: v.option.GrpcOpts.GrpcUserAgent, Host: v.option.ServerName, ClientFingerprint: v.option.ClientFingerprint, } diff --git a/docs/config.yaml b/docs/config.yaml index 5ea5b323..d46f3024 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -669,6 +669,7 @@ proxies: # socks5 # skip-cert-verify: true grpc-opts: grpc-service-name: "example" + # grpc-user-agent: "grpc-go/1.36.0" # ip-version: ipv4 # vless @@ -757,6 +758,8 @@ proxies: # socks5 servername: testingcf.jsdelivr.net grpc-opts: grpc-service-name: "grpc" + # grpc-user-agent: "grpc-go/1.36.0" + reality-opts: public-key: CrrQSjAG_YkHLwvM2M-7XkKJilgL5upBKCp0od0tLhE short-id: 10f897e26c4b9478 @@ -825,6 +828,7 @@ proxies: # socks5 udp: true grpc-opts: grpc-service-name: "example" + # grpc-user-agent: "grpc-go/1.36.0" - name: trojan-ws server: server diff --git a/transport/gun/gun.go b/transport/gun/gun.go index 3ac548dd..7ca1f061 100644 --- a/transport/gun/gun.go +++ b/transport/gun/gun.go @@ -60,6 +60,7 @@ type Conn struct { type Config struct { ServiceName string + UserAgent string Host string ClientFingerprint string } @@ -347,6 +348,12 @@ func StreamGunWithTransport(transport *TransportWrap, cfg *Config) (net.Conn, er path := ServiceNameToPath(serviceName) reader, writer := io.Pipe() + + header := defaultHeader.Clone() + if cfg.UserAgent != "" { + header["user-agent"] = []string{cfg.UserAgent} + } + request := &http.Request{ Method: http.MethodPost, Body: reader, @@ -360,7 +367,7 @@ func StreamGunWithTransport(transport *TransportWrap, cfg *Config) (net.Conn, er Proto: "HTTP/2", ProtoMajor: 2, ProtoMinor: 0, - Header: defaultHeader, + Header: header, } request = request.WithContext(transport.ctx)