Add trojan connection fallback

This commit is contained in:
世界 2022-08-20 20:54:20 +08:00
parent f13ecbd9bb
commit 746b5d8be0
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
7 changed files with 48 additions and 14 deletions

View file

@ -20,13 +20,11 @@ func Write(writer io.Writer, domains map[string][]Item) error {
for _, code := range keys { for _, code := range keys {
index[code] = content.Len() index[code] = content.Len()
for _, domain := range domains[code] { for _, domain := range domains[code] {
err := rw.WriteByte(content, domain.Type) content.WriteByte(domain.Type)
err := rw.WriteVString(content, domain.Value)
if err != nil { if err != nil {
return err return err
} }
if err = rw.WriteVString(content, domain.Value); err != nil {
return err
}
} }
} }

View file

@ -1,3 +1,13 @@
#### 2022/08/20
* Attempt to unwrap ip-in-fqdn socksaddr
* Fix read packages in android 12
* Fix route on some android devices
* Improve linux process searcher
* Fix write socks5 username password auth request
* Skip bind connection with private destination to interface
* Add trojan connection fallback
#### 2022/08/19 #### 2022/08/19
* Add Hysteria [Inbound](/configuration/inbound/hysteria) and [Outbund](/configuration/outbound/hysteria) * Add Hysteria [Inbound](/configuration/inbound/hysteria) and [Outbund](/configuration/outbound/hysteria)

View file

@ -20,7 +20,11 @@
"password": "8JCsPssfgS8tiRwiMlhARg==" "password": "8JCsPssfgS8tiRwiMlhARg=="
} }
], ],
"tls": {} "tls": {},
"fallback": {
"server": "127.0.0.0.1",
"server_port": 8080
}
} }
] ]
} }
@ -73,3 +77,11 @@ Trojan users.
#### tls #### tls
TLS configuration, see [TLS inbound structure](/configuration/shared/tls/#inbound-structure). TLS configuration, see [TLS inbound structure](/configuration/shared/tls/#inbound-structure).
#### fallback
!!! error ""
There is no evidence that GFW detects and blocks Trojan servers based on HTTP responses, and opening the standard http/s port on the server is a much bigger signature.
Fallback server configuration. Disabled if empty.

2
go.mod
View file

@ -17,7 +17,7 @@ require (
github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a
github.com/sagernet/netlink v0.0.0-20220820041223-3cd8365d17ac github.com/sagernet/netlink v0.0.0-20220820041223-3cd8365d17ac
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb
github.com/sagernet/sing v0.0.0-20220820042914-5304a2876b82 github.com/sagernet/sing v0.0.0-20220820125206-f0c2e5a0dcc2
github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9 github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
github.com/sagernet/sing-tun v0.0.0-20220820054007-ce3573838b1e github.com/sagernet/sing-tun v0.0.0-20220820054007-ce3573838b1e

4
go.sum
View file

@ -96,8 +96,8 @@ github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb h1:wc0yQ+SBn4TaTY
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4= github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4=
github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.0.0-20220820042914-5304a2876b82 h1:sKYbF5EN2AZXH0owjr4vHjFh/lmN3xHLVO8dm9eSnXE= github.com/sagernet/sing v0.0.0-20220820125206-f0c2e5a0dcc2 h1:9wlER8wPHDjqzDGpqoBWcZ6/MBUL00my7D+hdCCaNiI=
github.com/sagernet/sing v0.0.0-20220820042914-5304a2876b82/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220820125206-f0c2e5a0dcc2/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9 h1:XgXSOJv8e7+98SJvg1f0luuPR33r4yFcmzxb3R//BTI= github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9 h1:XgXSOJv8e7+98SJvg1f0luuPR33r4yFcmzxb3R//BTI=
github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9/go.mod h1:MAHy2IKZAA101t3Gr2x0ldwn6XuAs2cjGzSzHy5RhWk= github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9/go.mod h1:MAHy2IKZAA101t3Gr2x0ldwn6XuAs2cjGzSzHy5RhWk=
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=

View file

@ -14,6 +14,7 @@ import (
"github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/auth"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/protocol/trojan" "github.com/sagernet/sing/protocol/trojan"
) )
@ -22,9 +23,10 @@ var _ adapter.Inbound = (*Trojan)(nil)
type Trojan struct { type Trojan struct {
myInboundAdapter myInboundAdapter
service *trojan.Service[int] service *trojan.Service[int]
users []option.TrojanUser users []option.TrojanUser
tlsConfig *TLSConfig tlsConfig *TLSConfig
fallbackAddr M.Socksaddr
} }
func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrojanInboundOptions) (*Trojan, error) { func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrojanInboundOptions) (*Trojan, error) {
@ -40,7 +42,12 @@ func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLog
}, },
users: options.Users, users: options.Users,
} }
service := trojan.NewService[int](adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound)) var fallbackHandler N.TCPConnectionHandler
if options.Fallback != nil && options.Fallback.Server != "" {
inbound.fallbackAddr = options.Fallback.Build()
fallbackHandler = adapter.NewUpstreamContextHandler(inbound.fallbackConnection, nil, nil)
}
service := trojan.NewService[int](adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound), fallbackHandler)
err := service.UpdateUsers(common.MapIndexed(options.Users, func(index int, it option.TrojanUser) int { err := service.UpdateUsers(common.MapIndexed(options.Users, func(index int, it option.TrojanUser) int {
return index return index
}), common.Map(options.Users, func(it option.TrojanUser) string { }), common.Map(options.Users, func(it option.TrojanUser) string {
@ -104,6 +111,12 @@ func (h *Trojan) newConnection(ctx context.Context, conn net.Conn, metadata adap
return h.router.RouteConnection(ctx, conn, metadata) return h.router.RouteConnection(ctx, conn, metadata)
} }
func (h *Trojan) fallbackConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
h.logger.InfoContext(ctx, "fallback connection to ", h.fallbackAddr)
metadata.Destination = h.fallbackAddr
return h.router.RouteConnection(ctx, conn, metadata)
}
func (h *Trojan) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { func (h *Trojan) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
userIndex, loaded := auth.UserFromContext[int](ctx) userIndex, loaded := auth.UserFromContext[int](ctx)
if !loaded { if !loaded {

View file

@ -2,8 +2,9 @@ package option
type TrojanInboundOptions struct { type TrojanInboundOptions struct {
ListenOptions ListenOptions
Users []TrojanUser `json:"users,omitempty"` Users []TrojanUser `json:"users,omitempty"`
TLS *InboundTLSOptions `json:"tls,omitempty"` TLS *InboundTLSOptions `json:"tls,omitempty"`
Fallback *ServerOptions `json:"fallback,omitempty"`
} }
type TrojanUser struct { type TrojanUser struct {