tunnel: fix tunnel routing for public entrypoint
This commit is contained in:
+5
-3
@@ -406,11 +406,13 @@ type HTTPNodeConfig struct {
|
|||||||
// Deprecated: use requestHeader instead
|
// Deprecated: use requestHeader instead
|
||||||
Header map[string]string `yaml:",omitempty" json:"header,omitempty"`
|
Header map[string]string `yaml:",omitempty" json:"header,omitempty"`
|
||||||
// additional request header
|
// additional request header
|
||||||
RequestHeader map[string]string `yaml:",omitempty" json:"requestHeader,omitempty"`
|
RequestHeader map[string]string `yaml:"requestHeader,omitempty" json:"requestHeader,omitempty"`
|
||||||
// additional response header
|
// additional response header
|
||||||
ResponseHeader map[string]string `yaml:",omitempty" json:"responseHeader,omitempty"`
|
ResponseHeader map[string]string `yaml:"responseHeader,omitempty" json:"responseHeader,omitempty"`
|
||||||
// rewrite URL
|
// Deprecated: use rewriteURL instead
|
||||||
Rewrite []HTTPURLRewriteConfig `yaml:",omitempty" json:"rewrite,omitempty"`
|
Rewrite []HTTPURLRewriteConfig `yaml:",omitempty" json:"rewrite,omitempty"`
|
||||||
|
// rewrite URL
|
||||||
|
RewriteURL []HTTPURLRewriteConfig `yaml:"rewriteURL,omitempty" json:"rewriteURL,omitempty"`
|
||||||
// rewrite response body
|
// rewrite response body
|
||||||
RewriteBody []HTTPBodyRewriteConfig `yaml:"rewriteBody,omitempty" json:"rewriteBody,omitempty"`
|
RewriteBody []HTTPBodyRewriteConfig `yaml:"rewriteBody,omitempty" json:"rewriteBody,omitempty"`
|
||||||
// HTTP basic auth
|
// HTTP basic auth
|
||||||
|
|||||||
@@ -215,7 +215,12 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
|
|||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for _, v := range cfg.HTTP.Rewrite {
|
|
||||||
|
rewriteURL := cfg.HTTP.RewriteURL
|
||||||
|
if rewriteURL == nil {
|
||||||
|
rewriteURL = cfg.HTTP.Rewrite
|
||||||
|
}
|
||||||
|
for _, v := range rewriteURL {
|
||||||
if pattern, _ := regexp.Compile(v.Match); pattern != nil {
|
if pattern, _ := regexp.Compile(v.Match); pattern != nil {
|
||||||
settings.RewriteURL = append(settings.RewriteURL, chain.HTTPURLRewriteSetting{
|
settings.RewriteURL = append(settings.RewriteURL, chain.HTTPURLRewriteSetting{
|
||||||
Pattern: pattern,
|
Pattern: pattern,
|
||||||
|
|||||||
@@ -92,7 +92,10 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
ro.ClientIP = conn.RemoteAddr().String()
|
ro.ClientIP = conn.RemoteAddr().String()
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
||||||
ro.ClientIP = string(clientAddr)
|
ro.ClientIP = string(clientAddr)
|
||||||
|
} else {
|
||||||
|
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(conn.RemoteAddr().String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
||||||
ro.ClientIP = h
|
ro.ClientIP = h
|
||||||
}
|
}
|
||||||
@@ -100,7 +103,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
"remote": conn.RemoteAddr().String(),
|
"remote": conn.RemoteAddr().String(),
|
||||||
"local": conn.LocalAddr().String(),
|
"local": conn.LocalAddr().String(),
|
||||||
"sid": ctxvalue.SidFromContext(ctx),
|
"sid": ro.SID,
|
||||||
"client": ro.ClientIP,
|
"client": ro.ClientIP,
|
||||||
})
|
})
|
||||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/go-gost/x/internal/util/sniffing"
|
"github.com/go-gost/x/internal/util/sniffing"
|
||||||
tls_util "github.com/go-gost/x/internal/util/tls"
|
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||||
|
mdutil "github.com/go-gost/x/metadata/util"
|
||||||
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
stats_wrapper "github.com/go-gost/x/observer/stats/wrapper"
|
||||||
xrecorder "github.com/go-gost/x/recorder"
|
xrecorder "github.com/go-gost/x/recorder"
|
||||||
"github.com/go-gost/x/registry"
|
"github.com/go-gost/x/registry"
|
||||||
@@ -93,7 +94,10 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
ro.ClientIP = conn.RemoteAddr().String()
|
ro.ClientIP = conn.RemoteAddr().String()
|
||||||
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
if clientAddr := ctxvalue.ClientAddrFromContext(ctx); clientAddr != "" {
|
||||||
ro.ClientIP = string(clientAddr)
|
ro.ClientIP = string(clientAddr)
|
||||||
|
} else {
|
||||||
|
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(conn.RemoteAddr().String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
if h, _, _ := net.SplitHostPort(ro.ClientIP); h != "" {
|
||||||
ro.ClientIP = h
|
ro.ClientIP = h
|
||||||
}
|
}
|
||||||
@@ -101,7 +105,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
log := h.options.Logger.WithFields(map[string]any{
|
log := h.options.Logger.WithFields(map[string]any{
|
||||||
"remote": conn.RemoteAddr().String(),
|
"remote": conn.RemoteAddr().String(),
|
||||||
"local": conn.LocalAddr().String(),
|
"local": conn.LocalAddr().String(),
|
||||||
"sid": ctxvalue.SidFromContext(ctx),
|
"sid": ro.SID,
|
||||||
"client": ro.ClientIP,
|
"client": ro.ClientIP,
|
||||||
})
|
})
|
||||||
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
log.Infof("%s <> %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
@@ -137,6 +141,13 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
return rate_limiter.ErrRateLimit
|
return rate_limiter.ErrRateLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var host string
|
||||||
|
if md, ok := conn.(mdata.Metadatable); ok {
|
||||||
|
if v := mdutil.GetString(md.Metadata(), "host"); v != "" {
|
||||||
|
host = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var proto string
|
var proto string
|
||||||
if network == "tcp" && h.md.sniffing {
|
if network == "tcp" && h.md.sniffing {
|
||||||
if h.md.sniffingTimeout > 0 {
|
if h.md.sniffingTimeout > 0 {
|
||||||
@@ -193,6 +204,11 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
|
|||||||
}
|
}
|
||||||
|
|
||||||
var target *chain.Node
|
var target *chain.Node
|
||||||
|
if host != "" {
|
||||||
|
target = &chain.Node{
|
||||||
|
Addr: host,
|
||||||
|
}
|
||||||
|
}
|
||||||
if h.hop != nil {
|
if h.hop != nil {
|
||||||
target = h.hop.Select(ctx,
|
target = h.hop.Select(ctx,
|
||||||
hop.ProtocolSelectOption(proto),
|
hop.ProtocolSelectOption(proto),
|
||||||
|
|||||||
@@ -33,19 +33,35 @@ func (h *tunnelHandler) handleConnect(ctx context.Context, req *relay.Request, c
|
|||||||
|
|
||||||
host, _, _ := net.SplitHostPort(dstAddr)
|
host, _, _ := net.SplitHostPort(dstAddr)
|
||||||
|
|
||||||
// client is a public entrypoint.
|
|
||||||
if tunnelID.Equal(h.md.entryPointID) {
|
|
||||||
resp.WriteTo(conn)
|
|
||||||
return h.ep.Handle(ctx, conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !h.md.directTunnel {
|
|
||||||
var tid relay.TunnelID
|
var tid relay.TunnelID
|
||||||
if ingress := h.md.ingress; ingress != nil && host != "" {
|
if ingress := h.md.ingress; ingress != nil && host != "" {
|
||||||
if rule := ingress.GetRule(ctx, host); rule != nil {
|
if rule := ingress.GetRule(ctx, host); rule != nil {
|
||||||
tid = parseTunnelID(rule.Endpoint)
|
tid = parseTunnelID(rule.Endpoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// visitor is a public entrypoint.
|
||||||
|
if tunnelID.Equal(h.md.entryPointID) {
|
||||||
|
if tid.IsZero() {
|
||||||
|
resp.Status = relay.StatusNetworkUnreachable
|
||||||
|
resp.WriteTo(conn)
|
||||||
|
err := fmt.Errorf("no route to host %s", host)
|
||||||
|
log.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if tid.IsPrivate() {
|
||||||
|
resp.Status = relay.StatusHostUnreachable
|
||||||
|
resp.WriteTo(conn)
|
||||||
|
err := fmt.Errorf("tunnel %s is private for host %s", tid, host)
|
||||||
|
log.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// direct routing
|
||||||
|
if h.md.directTunnel {
|
||||||
|
tid = tunnelID
|
||||||
|
}
|
||||||
if !tid.Equal(tunnelID) {
|
if !tid.Equal(tunnelID) {
|
||||||
resp.Status = relay.StatusHostUnreachable
|
resp.Status = relay.StatusHostUnreachable
|
||||||
resp.WriteTo(conn)
|
resp.WriteTo(conn)
|
||||||
@@ -63,7 +79,7 @@ func (h *tunnelHandler) handleConnect(ctx context.Context, req *relay.Request, c
|
|||||||
timeout: 15 * time.Second,
|
timeout: 15 * time.Second,
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
cc, node, cid, err := d.Dial(ctx, network, tunnelID.String())
|
cc, node, cid, err := d.Dial(ctx, network, tid.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
resp.Status = relay.StatusServiceUnavailable
|
resp.Status = relay.StatusServiceUnavailable
|
||||||
@@ -72,7 +88,7 @@ func (h *tunnelHandler) handleConnect(ctx context.Context, req *relay.Request, c
|
|||||||
}
|
}
|
||||||
defer cc.Close()
|
defer cc.Close()
|
||||||
|
|
||||||
log.Debugf("connected to node=%s tunnel=%s connector=%s", node, tunnelID, cid)
|
log.Debugf("connect to node=%s tunnel=%s connector=%s OK", node, tid, cid)
|
||||||
|
|
||||||
if node == h.id {
|
if node == h.id {
|
||||||
if _, err := resp.WriteTo(conn); err != nil {
|
if _, err := resp.WriteTo(conn); err != nil {
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ func (t *Tunnel) clean() {
|
|||||||
var connectors []*Connector
|
var connectors []*Connector
|
||||||
for _, c := range t.connectors {
|
for _, c := range t.connectors {
|
||||||
if c.IsClosed() {
|
if c.IsClosed() {
|
||||||
c.log.Debugf("remove connector: %s", t.id, c.id)
|
c.log.Debugf("remove connector: %s %s", t.id, c.id)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user