sniffing protocol for port forwarding
This commit is contained in:
parent
5f31240e29
commit
2e89811d59
10
chain/hop.go
10
chain/hop.go
@ -103,6 +103,16 @@ func (p *chainHop) Select(ctx context.Context, opts ...chain.SelectOption) *chai
|
||||
if len(filters) == 0 {
|
||||
filters = nodes
|
||||
}
|
||||
} else if protocol := options.Protocol; protocol != "" {
|
||||
filters = nil
|
||||
for _, node := range p.nodes {
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
if node.Options().Protocol == protocol {
|
||||
filters = append(filters, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var nodes []*chain.Node
|
||||
|
@ -261,6 +261,7 @@ type ForwardNodeConfig struct {
|
||||
Name string `yaml:",omitempty" json:"name,omitempty"`
|
||||
Addr string `yaml:",omitempty" json:"addr,omitempty"`
|
||||
Host string `yaml:",omitempty" json:"host,omitempty"`
|
||||
Protocol string `yaml:",omitempty" json:"protocol,omitempty"`
|
||||
Bypass string `yaml:",omitempty" json:"bypass,omitempty"`
|
||||
Bypasses []string `yaml:",omitempty" json:"bypasses,omitempty"`
|
||||
}
|
||||
@ -335,6 +336,7 @@ type NodeConfig struct {
|
||||
Name string `json:"name"`
|
||||
Addr string `yaml:",omitempty" json:"addr,omitempty"`
|
||||
Host string `yaml:",omitempty" json:"host,omitempty"`
|
||||
Protocol string `yaml:",omitempty" json:"protocol,omitempty"`
|
||||
Interface string `yaml:",omitempty" json:"interface,omitempty"`
|
||||
SockOpts *SockOptsConfig `yaml:"sockopts,omitempty" json:"sockopts,omitempty"`
|
||||
Bypass string `yaml:",omitempty" json:"bypass,omitempty"`
|
||||
|
@ -216,6 +216,7 @@ func ParseHop(cfg *config.HopConfig) (chain.Hop, error) {
|
||||
chain.HostMapperNodeOption(registry.HostsRegistry().Get(v.Hosts)),
|
||||
chain.MetadataNodeOption(nm),
|
||||
chain.HostNodeOption(host),
|
||||
chain.ProtocolNodeOption(v.Protocol),
|
||||
)
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
|
@ -250,6 +250,7 @@ func parseForwarder(cfg *config.ForwarderConfig) (chain.Hop, error) {
|
||||
Name: node.Name,
|
||||
Addr: node.Addr,
|
||||
Host: node.Host,
|
||||
Protocol: node.Protocol,
|
||||
Bypass: node.Bypass,
|
||||
Bypasses: node.Bypasses,
|
||||
},
|
||||
|
2
go.mod
2
go.mod
@ -7,7 +7,7 @@ require (
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
|
||||
github.com/gin-contrib/cors v1.3.1
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
github.com/go-gost/core v0.0.0-20221129013900-0f0679a3ecbc
|
||||
github.com/go-gost/core v0.0.0-20221130024727-8effb0b8b971
|
||||
github.com/go-gost/gosocks4 v0.0.1
|
||||
github.com/go-gost/gosocks5 v0.3.1-0.20211109033403-d894d75b7f09
|
||||
github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7
|
||||
|
4
go.sum
4
go.sum
@ -96,8 +96,8 @@ github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gost/core v0.0.0-20221129013900-0f0679a3ecbc h1:LkielnJLsiOAnmgU88bW+73jZ07T4tyNb4jx94upm9g=
|
||||
github.com/go-gost/core v0.0.0-20221129013900-0f0679a3ecbc/go.mod h1:bHVbCS9da6XtKNYMkMUVcck5UqDDUkyC37erVfs4GXQ=
|
||||
github.com/go-gost/core v0.0.0-20221130024727-8effb0b8b971 h1:0AauAKN4J0ueS5yAdpQZEfhmUrPg1MZ/FBrGDmXyJi8=
|
||||
github.com/go-gost/core v0.0.0-20221130024727-8effb0b8b971/go.mod h1:bHVbCS9da6XtKNYMkMUVcck5UqDDUkyC37erVfs4GXQ=
|
||||
github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s=
|
||||
github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
|
||||
github.com/go-gost/gosocks5 v0.3.1-0.20211109033403-d894d75b7f09 h1:A95M6UWcfZgOuJkQ7QLfG0Hs5peWIUSysCDNz4pfe04=
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
xio "github.com/go-gost/x/internal/io"
|
||||
)
|
||||
|
||||
func SniffHost(ctx context.Context, rdw io.ReadWriter) (rw io.ReadWriter, host string, err error) {
|
||||
func Sniffing(ctx context.Context, rdw io.ReadWriter) (rw io.ReadWriter, host string, protocol string, err error) {
|
||||
rw = rdw
|
||||
|
||||
// try to sniff TLS traffic
|
||||
@ -24,7 +24,8 @@ func SniffHost(ctx context.Context, rdw io.ReadWriter) (rw io.ReadWriter, host s
|
||||
if err == nil &&
|
||||
hdr[0] == dissector.Handshake &&
|
||||
binary.BigEndian.Uint16(hdr[1:3]) == tls.VersionTLS10 {
|
||||
return sniffSNI(ctx, rw)
|
||||
rw, host, err = sniffSNI(ctx, rw)
|
||||
return
|
||||
}
|
||||
|
||||
// try to sniff HTTP traffic
|
||||
@ -39,6 +40,8 @@ func SniffHost(ctx context.Context, rdw io.ReadWriter) (rw io.ReadWriter, host s
|
||||
}
|
||||
}
|
||||
|
||||
protocol = sniffProtocol(hdr[:])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -82,3 +85,14 @@ func isHTTP(s string) bool {
|
||||
strings.HasPrefix(http.MethodConnect, s) ||
|
||||
strings.HasPrefix(http.MethodTrace, s)
|
||||
}
|
||||
|
||||
const (
|
||||
SSHv2 = "SSH-2"
|
||||
)
|
||||
|
||||
func sniffProtocol(hdr []byte) string {
|
||||
if string(hdr) == SSHv2 {
|
||||
return "ssh"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -93,15 +93,20 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
||||
|
||||
var rw io.ReadWriter = conn
|
||||
var host string
|
||||
var protocol string
|
||||
if h.md.sniffing {
|
||||
if network == "tcp" {
|
||||
rw, host, _ = forward.SniffHost(ctx, conn)
|
||||
rw, host, protocol, _ = forward.Sniffing(ctx, conn)
|
||||
h.options.Logger.Debugf("sniffing: host=%s, protocol=%s", host, protocol)
|
||||
}
|
||||
}
|
||||
|
||||
var target *chain.Node
|
||||
if h.hop != nil {
|
||||
target = h.hop.Select(ctx, chain.HostSelectOption(host))
|
||||
target = h.hop.Select(ctx,
|
||||
chain.HostSelectOption(host),
|
||||
chain.ProtocolSelectOption(protocol),
|
||||
)
|
||||
}
|
||||
if target == nil {
|
||||
err := errors.New("target not available")
|
||||
|
@ -84,14 +84,18 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
||||
|
||||
var rw io.ReadWriter = conn
|
||||
var host string
|
||||
var protocol string
|
||||
if h.md.sniffing {
|
||||
if network == "tcp" {
|
||||
rw, host, _ = forward.SniffHost(ctx, conn)
|
||||
rw, host, protocol, _ = forward.Sniffing(ctx, conn)
|
||||
}
|
||||
}
|
||||
var target *chain.Node
|
||||
if h.hop != nil {
|
||||
target = h.hop.Select(ctx, chain.HostSelectOption(host))
|
||||
target = h.hop.Select(ctx,
|
||||
chain.HostSelectOption(host),
|
||||
chain.ProtocolSelectOption(protocol),
|
||||
)
|
||||
}
|
||||
if target == nil {
|
||||
err := errors.New("target not available")
|
||||
|
Loading…
Reference in New Issue
Block a user