add service option for plugin

This commit is contained in:
ginuerzh
2025-08-29 23:34:23 +08:00
parent a12ed27dfa
commit c7d16962ec
71 changed files with 227 additions and 88 deletions
+7 -1
View File
@@ -48,9 +48,15 @@ func (p *grpcPlugin) Admit(ctx context.Context, addr string, opts ...admission.O
return false
}
var options admission.Options
for _, opt := range opts {
opt(&options)
}
r, err := p.client.Admit(ctx,
&proto.AdmissionRequest{
Addr: addr,
Service: options.Service,
Addr: addr,
})
if err != nil {
p.log.Error(err)
+9 -2
View File
@@ -12,7 +12,8 @@ import (
)
type httpPluginRequest struct {
Addr string `json:"addr"`
Service string `json:"service"`
Addr string `json:"addr"`
}
type httpPluginResponse struct {
@@ -49,8 +50,14 @@ func (p *httpPlugin) Admit(ctx context.Context, addr string, opts ...admission.O
return
}
var options admission.Options
for _, opt := range opts {
opt(&options)
}
rb := httpPluginRequest{
Addr: addr,
Service: options.Service,
Addr: addr,
}
v, err := json.Marshal(&rb)
if err != nil {
+4 -2
View File
@@ -10,16 +10,18 @@ import (
)
type listener struct {
service string
net.Listener
admission admission.Admission
log logger.Logger
}
func WrapListener(admission admission.Admission, ln net.Listener) net.Listener {
func WrapListener(service string, admission admission.Admission, ln net.Listener) net.Listener {
if admission == nil {
return ln
}
return &listener{
service: service,
Listener: ln,
admission: admission,
}
@@ -45,7 +47,7 @@ func (ln *listener) Accept() (net.Conn, error) {
}
if ln.admission != nil &&
!ln.admission.Admit(ctx, clientAddr.String()) {
!ln.admission.Admit(ctx, clientAddr.String(), admission.WithService(ln.service)) {
c.Close()
continue
}
+1 -1
View File
@@ -35,7 +35,7 @@ func mwBasicAuth(auther auth.Authenticator) gin.HandlerFunc {
return
}
u, p, _ := c.Request.BasicAuth()
if _, ok := auther.Authenticate(c, u, p); !ok {
if _, ok := auther.Authenticate(c, u, p, auth.WithService("@api")); !ok {
c.Writer.Header().Set("WWW-Authenticate", "Basic")
c.JSON(http.StatusUnauthorized, Response{
Code: http.StatusUnauthorized,
+6
View File
@@ -51,12 +51,18 @@ func (p *grpcPlugin) Authenticate(ctx context.Context, user, password string, op
return "", false
}
var options auth.Options
for _, opt := range opts {
opt(&options)
}
var clientAddr string
if v := xctx.SrcAddrFromContext(ctx); v != nil {
clientAddr = v.String()
}
r, err := p.client.Authenticate(ctx,
&proto.AuthenticateRequest{
Service: options.Service,
Username: user,
Password: password,
Client: clientAddr,
+7
View File
@@ -13,6 +13,7 @@ import (
)
type httpPluginRequest struct {
Service string `json:"service"`
Username string `json:"username"`
Password string `json:"password"`
Client string `json:"client"`
@@ -53,12 +54,18 @@ func (p *httpPlugin) Authenticate(ctx context.Context, user, password string, op
return
}
var options auth.Options
for _, opt := range opts {
opt(&options)
}
var clientAddr string
if v := xctx.SrcAddrFromContext(ctx); v != nil {
clientAddr = v.String()
}
rb := httpPluginRequest{
Service: options.Service,
Username: user,
Password: password,
Client: clientAddr,
+1
View File
@@ -56,6 +56,7 @@ func (p *grpcPlugin) Contains(ctx context.Context, network, addr string, opts ..
r, err := p.client.Bypass(ctx,
&proto.BypassRequest{
Service: options.Service,
Network: network,
Addr: addr,
Client: string(ctxvalue.ClientIDFromContext(ctx)),
+2
View File
@@ -13,6 +13,7 @@ import (
)
type httpPluginRequest struct {
Service string `json:"service"`
Network string `json:"network"`
Addr string `json:"addr"`
Client string `json:"client"`
@@ -60,6 +61,7 @@ func (p *httpPlugin) Contains(ctx context.Context, network, addr string, opts ..
}
rb := httpPluginRequest{
Service: options.Service,
Network: network,
Addr: addr,
Client: string(ctxvalue.ClientIDFromContext(ctx)),
+2 -2
View File
@@ -9,10 +9,10 @@ require (
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.10.1
github.com/go-gost/core v0.3.2
github.com/go-gost/core v0.3.3
github.com/go-gost/gosocks4 v0.0.1
github.com/go-gost/gosocks5 v0.4.2
github.com/go-gost/plugin v0.2.0
github.com/go-gost/plugin v0.2.1
github.com/go-gost/relay v0.5.0
github.com/go-gost/tls-dissector v0.1.1
github.com/go-redis/redis/v8 v8.11.5
+4 -6
View File
@@ -49,14 +49,14 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-gost/core v0.3.2 h1:AjmIYWVa5fc172zIupT3e1pdnKx76LxppGiw00uRsSA=
github.com/go-gost/core v0.3.2/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
github.com/go-gost/core v0.3.3 h1:YN15FQptQoNB0MlMR283C99w2EeGql9Cm+4QVlN6zs0=
github.com/go-gost/core v0.3.3/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A=
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.4.2 h1:IianxHTkACPqCwiOAT3MHoMdSUl+SEPSRu1ikawC1Pc=
github.com/go-gost/gosocks5 v0.4.2/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4=
github.com/go-gost/plugin v0.2.0 h1:Xxqq3oJi6d2dZ/PqqEpefrUckT6aVz8JUxQ/sb7tmTM=
github.com/go-gost/plugin v0.2.0/go.mod h1:oN23l+yGDCIP9G3KnDl/I/0zVGOobZUDCB2Z5yYYXts=
github.com/go-gost/plugin v0.2.1 h1:zkkgCZd+/X+jmaDElP7z2fZVTFv+Pjq2DLmnnNWPMFA=
github.com/go-gost/plugin v0.2.1/go.mod h1:oN23l+yGDCIP9G3KnDl/I/0zVGOobZUDCB2Z5yYYXts=
github.com/go-gost/relay v0.5.0 h1:JG1tgy/KWiVXS0ukuVXvbM0kbYuJTWxYpJ5JwzsCf/c=
github.com/go-gost/relay v0.5.0/go.mod h1:lcX+23LCQ3khIeASBo+tJ/WbwXFO32/N5YN6ucuYTG8=
github.com/go-gost/tls-dissector v0.1.1 h1:2zUOTPzCQAUQ54Rpy0UEi3JPMQSYsIFSeFeKrzmkCoU=
@@ -160,8 +160,6 @@ github.com/pion/transport/v2 v2.0.2 h1:St+8o+1PEzPT51O9bv+tH/KYYLMNR5Vwm5Z3Qkjsy
github.com/pion/transport/v2 v2.0.2/go.mod h1:vrz6bUbFr/cjdwbnxq8OdDDzHf7JJfGsIRkxfpZoTA0=
github.com/pion/udp/v2 v2.0.1 h1:xP0z6WNux1zWEjhC7onRA3EwwSliXqu1ElUZAQhUP54=
github.com/pion/udp/v2 v2.0.1/go.mod h1:B7uvTMP00lzWdyMr/1PVZXtV3wpPIxBRd4Wl6AksXn8=
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+2 -1
View File
@@ -9,6 +9,7 @@ import (
"strings"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/chain"
"github.com/go-gost/core/common/bufpool"
"github.com/go-gost/core/handler"
@@ -260,7 +261,7 @@ func (h *dnsHandler) request(ctx context.Context, msg []byte, ro *xrecorder.Hand
}()
if h.options.Bypass != nil && mq.Question[0].Qclass == dns.ClassINET {
if h.options.Bypass.Contains(context.Background(), "udp", strings.Trim(mq.Question[0].Name, ".")) {
if h.options.Bypass.Contains(context.Background(), "udp", strings.Trim(mq.Question[0].Name, "."), bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", mq.Question[0].Name)
mr = (&dns.Msg{}).SetReply(&mq)
b := bufpool.Get(h.md.bufferSize)
+2 -1
View File
@@ -8,6 +8,7 @@ import (
"sync"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
@@ -141,7 +142,7 @@ func (h *fileHandler) handleFunc(w http.ResponseWriter, r *http.Request) {
if auther := h.options.Auther; auther != nil {
u, p, _ := r.BasicAuth()
ro.ClientID = u
if _, ok := auther.Authenticate(r.Context(), u, p); !ok {
if _, ok := auther.Authenticate(r.Context(), u, p, auth.WithService(ro.Service)); !ok {
w.Header().Set("WWW-Authenticate", "Basic")
w.WriteHeader(http.StatusUnauthorized)
return
+2
View File
@@ -179,6 +179,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, conn,
forwarder.WithService(h.options.Service),
forwarder.WithDial(dial),
forwarder.WithHop(h.hop),
forwarder.WithBypass(h.options.Bypass),
@@ -188,6 +189,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, conn,
forwarder.WithService(h.options.Service),
forwarder.WithDial(dial),
forwarder.WithHop(h.hop),
forwarder.WithBypass(h.options.Bypass),
+2
View File
@@ -179,6 +179,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, conn,
forwarder.WithService(h.options.Service),
forwarder.WithDial(dial),
forwarder.WithHop(h.hop),
forwarder.WithBypass(h.options.Bypass),
@@ -188,6 +189,7 @@ func (h *forwardHandler) Handle(ctx context.Context, conn net.Conn, opts ...hand
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, conn,
forwarder.WithService(h.options.Service),
forwarder.WithDial(dial),
forwarder.WithHop(h.hop),
forwarder.WithBypass(h.options.Bypass),
+7 -3
View File
@@ -21,6 +21,8 @@ import (
"time"
"github.com/asaskevich/govalidator"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/limiter/traffic"
@@ -296,7 +298,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID))
if h.options.Bypass != nil &&
h.options.Bypass.Contains(ctx, network, addr) {
h.options.Bypass.Contains(ctx, network, addr, bypass.WithService(h.options.Service)) {
resp.StatusCode = http.StatusForbidden
if log.IsLevelEnabled(logger.TraceLevel) {
@@ -406,6 +408,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -413,6 +416,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -538,7 +542,7 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriteCloser,
ro.HTTP.StatusCode = res.StatusCode
if h.options.Bypass != nil &&
h.options.Bypass.Contains(ctx, "tcp", host) {
h.options.Bypass.Contains(ctx, "tcp", host, bypass.WithService(h.options.Service)) {
res.StatusCode = http.StatusForbidden
if log.IsLevelEnabled(logger.TraceLevel) {
@@ -855,7 +859,7 @@ func (h *httpHandler) authenticate(ctx context.Context, conn net.Conn, req *http
if h.options.Auther == nil {
return "", true
}
if id, ok = h.options.Auther.Authenticate(ctx, u, p); ok {
if id, ok = h.options.Auther.Authenticate(ctx, u, p, auth.WithService(h.options.Service)); ok {
return
}
+1
View File
@@ -74,6 +74,7 @@ func (h *httpHandler) handleUDP(ctx context.Context, conn net.Conn, ro *xrecorde
}
relay := udp.NewRelay(socks.UDPTunServerConn(conn), pc).
WithService(h.options.Service).
WithBypass(h.options.Bypass).
WithBufferSize(h.md.udpBufferSize).
WithLogger(log)
+4 -2
View File
@@ -18,6 +18,8 @@ import (
"strings"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/limiter/traffic"
@@ -241,7 +243,7 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
ctx = xctx.ContextWithClientID(ctx, xctx.ClientID(clientID))
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", host) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", host, bypass.WithService(h.options.Service)) {
resp.StatusCode = http.StatusForbidden
w.WriteHeader(resp.StatusCode)
log.Debug("bypass: ", host)
@@ -383,7 +385,7 @@ func (h *http2Handler) authenticate(ctx context.Context, w http.ResponseWriter,
if h.options.Auther == nil {
return "", true
}
if id, ok = h.options.Auther.Authenticate(ctx, u, p); ok {
if id, ok = h.options.Auther.Authenticate(ctx, u, p, auth.WithService(h.options.Service)); ok {
return
}
+2 -1
View File
@@ -9,6 +9,7 @@ import (
"strings"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/chain"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/hop"
@@ -106,7 +107,7 @@ func (h *http3Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
w.Header().Set(k, h.md.header.Get(k))
}
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "udp", addr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "udp", addr, bypass.WithService(h.options.Service)) {
w.WriteHeader(http.StatusForbidden)
log.Debug("bypass: ", addr)
return nil
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"net/http"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/handler"
md "github.com/go-gost/core/metadata"
xmetrics "github.com/go-gost/x/metrics"
@@ -72,7 +73,7 @@ func (h *metricsHandler) Close() error {
func (h *metricsHandler) handleFunc(w http.ResponseWriter, r *http.Request) {
if auther := h.options.Auther; auther != nil {
u, p, _ := r.BasicAuth()
if _, ok := auther.Authenticate(r.Context(), u, p); !ok {
if _, ok := auther.Authenticate(r.Context(), u, p, auth.WithService(h.options.Service)); !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
+6 -5
View File
@@ -9,6 +9,7 @@ import (
"strings"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/handler"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
@@ -175,7 +176,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
}
if cc == nil {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", dstAddr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", dstAddr.String(), bypass.WithService(h.options.Service)) {
return nil, xbypass.ErrBypass
}
var buf bytes.Buffer
@@ -207,6 +208,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithBypass(h.options.Bypass),
@@ -214,9 +216,8 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
sniffing.WithLog(log),
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx,
ro.Network,
conn,
return sniffer.HandleTLS(ctx, ro.Network, conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithBypass(h.options.Bypass),
@@ -229,7 +230,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
log.Debugf("%s >> %s", conn.RemoteAddr(), dstAddr)
if h.options.Bypass != nil &&
h.options.Bypass.Contains(ctx, dstAddr.Network(), dstAddr.String()) {
h.options.Bypass.Contains(ctx, dstAddr.Network(), dstAddr.String(), bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", dstAddr)
return xbypass.ErrBypass
}
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"net"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/handler"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
@@ -122,7 +123,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
log.Debugf("%s >> %s", conn.RemoteAddr(), dstAddr)
if h.options.Bypass != nil &&
h.options.Bypass.Contains(ctx, dstAddr.Network(), dstAddr.String()) {
h.options.Bypass.Contains(ctx, dstAddr.Network(), dstAddr.String(), bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", dstAddr)
return xbypass.ErrBypass
}
+1
View File
@@ -204,6 +204,7 @@ func (h *relayHandler) bindUDP(ctx context.Context, conn net.Conn, network, addr
log.Infof("bind on %s OK", pc.LocalAddr())
r := udp.NewRelay(relay_util.UDPTunServerConn(conn), pc).
WithService(h.options.Service).
WithBypass(h.options.Bypass).
WithBufferSize(h.md.udpBufferSize).
WithLogger(log)
+4 -1
View File
@@ -10,6 +10,7 @@ import (
"net"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
@@ -77,7 +78,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
return
}
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, network, address) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, network, address, bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", address)
resp.Status = relay.StatusForbidden
resp.WriteTo(conn)
@@ -186,6 +187,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -193,6 +195,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
+1 -1
View File
@@ -37,7 +37,7 @@ func (l *tcpListener) Init(md md.Metadata) (err error) {
ln := l.ln
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
l.ln = ln
return
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"strconv"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/hop"
"github.com/go-gost/core/limiter"
@@ -200,7 +201,7 @@ func (h *relayHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
}
if h.options.Auther != nil {
clientID, ok := h.options.Auther.Authenticate(ctx, user, pass)
clientID, ok := h.options.Auther.Authenticate(ctx, user, pass, auth.WithService(h.options.Service))
if !ok {
resp.Status = relay.StatusUnauthorized
resp.WriteTo(conn)
+3 -2
View File
@@ -13,6 +13,7 @@ import (
"time"
"github.com/go-gost/core/common/bufpool"
"github.com/go-gost/core/ingress"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
@@ -43,9 +44,9 @@ func (h *routerHandler) handleAssociate(ctx context.Context, conn net.Conn, netw
Status: relay.StatusOK,
}
if ingress := h.md.ingress; ingress != nil && host != "" {
if ing := h.md.ingress; ing != nil && host != "" {
var rid relay.TunnelID
if rule := ingress.GetRule(ctx, host); rule != nil {
if rule := ing.GetRule(ctx, host, ingress.WithService(h.options.Service)); rule != nil {
rid = parseRouterID(rule.Endpoint)
}
+2 -1
View File
@@ -8,6 +8,7 @@ import (
"strconv"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/limiter/traffic"
@@ -211,7 +212,7 @@ func (h *routerHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl
}
if h.options.Auther != nil {
clientID, ok := h.options.Auther.Authenticate(ctx, user, pass)
clientID, ok := h.options.Auther.Authenticate(ctx, user, pass, auth.WithService(h.options.Service))
if !ok {
resp.Status = relay.StatusUnauthorized
resp.WriteTo(conn)
+2
View File
@@ -160,6 +160,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithBypass(h.options.Bypass),
@@ -168,6 +169,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithBypass(h.options.Bypass),
+6 -2
View File
@@ -9,6 +9,8 @@ import (
"net"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/limiter/traffic"
@@ -172,7 +174,7 @@ func (h *socks4Handler) Handle(ctx context.Context, conn net.Conn, opts ...handl
conn.SetReadDeadline(time.Time{})
if h.options.Auther != nil {
clientID, ok := h.options.Auther.Authenticate(ctx, string(req.Userid), "")
clientID, ok := h.options.Auther.Authenticate(ctx, string(req.Userid), "", auth.WithService(h.options.Service))
if !ok {
resp := gosocks4.NewReply(gosocks4.RejectedUserid, nil)
log.Trace(resp)
@@ -235,7 +237,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g
conn = xnet.NewReadWriteConn(rw, rw, conn)
}
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", addr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", addr, bypass.WithService(h.options.Service)) {
resp := gosocks4.NewReply(gosocks4.Rejected, nil)
log.Trace(resp)
log.Debug("bypass: ", addr)
@@ -305,6 +307,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -312,6 +315,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
+4 -1
View File
@@ -9,6 +9,7 @@ import (
"net"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/observer/stats"
@@ -54,7 +55,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ
conn = xnet.NewReadWriteConn(rw, rw, conn)
}
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, network, address) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, network, address, bypass.WithService(h.options.Service)) {
resp := gosocks5.NewReply(gosocks5.NotAllowed, nil)
log.Trace(resp)
log.Debug("bypass: ", address)
@@ -124,6 +125,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -131,6 +133,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
+1
View File
@@ -63,6 +63,7 @@ func (h *socks5Handler) Init(md md.Metadata) (err error) {
}
h.selector = &serverSelector{
service: h.options.Service,
Authenticator: h.options.Auther,
TLSConfig: h.options.TLSConfig,
logger: h.options.Logger,
+2 -1
View File
@@ -13,6 +13,7 @@ import (
)
type serverSelector struct {
service string
methods []uint8
Authenticator auth.Authenticator
TLSConfig *tls.Config
@@ -71,7 +72,7 @@ func (s *serverSelector) OnSelected(method uint8, conn net.Conn) (string, net.Co
if s.Authenticator != nil {
var ok bool
ctx := xctx.ContextWithSrcAddr(context.Background(), conn.RemoteAddr())
id, ok = s.Authenticator.Authenticate(ctx, req.Username, req.Password)
id, ok = s.Authenticator.Authenticate(ctx, req.Username, req.Password, auth.WithService(s.service))
if !ok {
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
if err := resp.Write(conn); err != nil {
+1
View File
@@ -127,6 +127,7 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, network st
filterIP: conn.RemoteAddr().(*net.TCPAddr).IP,
},
h.md.udpBufferSize), pc).
WithService(h.options.Service).
WithBypass(h.options.Bypass).
WithBufferSize(h.md.udpBufferSize).
WithLogger(log)
+1
View File
@@ -134,6 +134,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network
}
r := udp.NewRelay(socks.UDPTunServerConn(conn), pc).
WithService(h.options.Service).
WithBypass(h.options.Bypass).
WithBufferSize(h.md.udpBufferSize).
WithLogger(log)
+4 -1
View File
@@ -9,6 +9,7 @@ import (
"net"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/handler"
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/observer/stats"
@@ -153,7 +154,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
log.Debugf("%s >> %s", conn.RemoteAddr(), addr)
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", addr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", addr.String(), bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", addr.String())
return nil
}
@@ -211,6 +212,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -218,6 +220,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
+3 -2
View File
@@ -7,6 +7,7 @@ import (
"net"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/common/bufpool"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/logger"
@@ -175,7 +176,7 @@ func (h *ssuHandler) relayPacket(ctx context.Context, pc1, pc2 net.PacketConn, r
ro.Host = addr.String()
}
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr.Network(), addr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, addr.Network(), addr.String(), bypass.WithService(h.options.Service)) {
log.Warn("bypass: ", addr)
return nil
}
@@ -207,7 +208,7 @@ func (h *ssuHandler) relayPacket(ctx context.Context, pc1, pc2 net.PacketConn, r
return err
}
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, raddr.Network(), raddr.String()) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, raddr.Network(), raddr.String(), bypass.WithService(h.options.Service)) {
log.Warn("bypass: ", raddr)
return nil
}
+4 -1
View File
@@ -12,6 +12,7 @@ import (
"strconv"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
@@ -154,7 +155,7 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti
log.Debugf("%s >> %s", conn.RemoteAddr(), targetAddr)
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", targetAddr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, "tcp", targetAddr, bypass.WithService(h.options.Service)) {
log.Debugf("bypass %s", targetAddr)
return xbypass.ErrBypass
}
@@ -206,6 +207,7 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", xnet.NewReadWriteConn(br, conn, conn),
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -213,6 +215,7 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", xnet.NewReadWriteConn(br, conn, conn),
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
+2 -1
View File
@@ -8,6 +8,7 @@ import (
"net/netip"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/router"
xip "github.com/go-gost/x/internal/net/ip"
@@ -142,7 +143,7 @@ func (h *tunHandler) transportServer(ctx context.Context, tun io.ReadWriter, con
ok := true
key := bytes.TrimRight(b[4:20], "\x00")
for _, ip := range peerIPs {
if _, ok = auther.Authenticate(ctx, ip.String(), string(key)); !ok {
if _, ok = auther.Authenticate(ctx, ip.String(), string(key), auth.WithService(h.options.Service)); !ok {
break
}
}
+2
View File
@@ -111,6 +111,8 @@ func (h *tungoHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
}()
th := &transportHandler{
service: h.options.Service,
tcpQueue: make(chan adapter.TCPConn),
udpQueue: make(chan adapter.UDPConn),
udpTimeout: h.md.udpTimeout,
+6 -1
View File
@@ -12,6 +12,7 @@ import (
"sync"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/common/bufpool"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/observer/stats"
@@ -37,6 +38,8 @@ const (
var _ adapter.TransportHandler = (*transportHandler)(nil)
type transportHandler struct {
service string
// Unbuffered TCP/UDP queues.
tcpQueue chan adapter.TCPConn
udpQueue chan adapter.UDPConn
@@ -229,6 +232,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
switch proto {
case sniffing.ProtoHTTP:
sniffer.HandleHTTP(ctx, network, conn,
sniffing.WithService(h.service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithBypass(h.opts.Bypass),
@@ -238,6 +242,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
return
case sniffing.ProtoTLS:
sniffer.HandleTLS(ctx, network, conn,
sniffing.WithService(h.service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithBypass(h.opts.Bypass),
@@ -249,7 +254,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
}
if h.opts.Bypass != nil &&
h.opts.Bypass.Contains(ctx, network, dstAddr.String()) {
h.opts.Bypass.Contains(ctx, network, dstAddr.String(), bypass.WithService(h.opts.Service)) {
log.Debug("bypass: ", dstAddr)
return
}
+3 -3
View File
@@ -41,7 +41,7 @@ func (h *tunnelHandler) handleBind(ctx context.Context, conn net.Conn, network,
if host == "" || h.md.ingress == nil {
host = endpoint
} else if host != endpoint {
if rule := h.md.ingress.GetRule(ctx, host); rule != nil && rule.Endpoint != tunnelID.String() {
if rule := h.md.ingress.GetRule(ctx, host, ingress.WithService(h.options.Service)); rule != nil && rule.Endpoint != tunnelID.String() {
host = endpoint
}
}
@@ -82,12 +82,12 @@ func (h *tunnelHandler) handleBind(ctx context.Context, conn net.Conn, network,
h.md.ingress.SetRule(ctx, &ingress.Rule{
Hostname: endpoint,
Endpoint: tunnelID.String(),
})
}, ingress.WithService(h.options.Service))
if host != "" {
h.md.ingress.SetRule(ctx, &ingress.Rule{
Hostname: host,
Endpoint: tunnelID.String(),
})
}, ingress.WithService(h.options.Service))
}
}
if h.md.sd != nil {
+5 -3
View File
@@ -6,6 +6,8 @@ import (
"net"
"time"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/ingress"
"github.com/go-gost/core/logger"
"github.com/go-gost/relay"
xnet "github.com/go-gost/x/internal/net"
@@ -24,7 +26,7 @@ func (h *tunnelHandler) handleConnect(ctx context.Context, req *relay.Request, c
Status: relay.StatusOK,
}
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, network, dstAddr) {
if h.options.Bypass != nil && h.options.Bypass.Contains(ctx, network, dstAddr, bypass.WithService(h.options.Service)) {
log.Debug("bypass: ", dstAddr)
resp.Status = relay.StatusForbidden
_, err := resp.WriteTo(conn)
@@ -34,8 +36,8 @@ func (h *tunnelHandler) handleConnect(ctx context.Context, req *relay.Request, c
host, _, _ := net.SplitHostPort(dstAddr)
var tid relay.TunnelID
if ingress := h.md.ingress; ingress != nil && host != "" {
if rule := ingress.GetRule(ctx, host); rule != nil {
if ing := h.md.ingress; ing != nil && host != "" {
if rule := ing.GetRule(ctx, host, ingress.WithService(h.options.Service)); rule != nil {
tid = parseTunnelID(rule.Endpoint)
}
}
+2 -2
View File
@@ -132,7 +132,7 @@ func (ep *entrypoint) Handle(ctx context.Context, conn net.Conn) (err error) {
func (ep *entrypoint) dial(ctx context.Context, network, addr string) (conn net.Conn, err error) {
var tunnelID relay.TunnelID
if ep.ingress != nil {
if rule := ep.ingress.GetRule(ctx, addr); rule != nil {
if rule := ep.ingress.GetRule(ctx, addr, ingress.WithService(ep.service)); rule != nil {
tunnelID = parseTunnelID(rule.Endpoint)
}
}
@@ -731,7 +731,7 @@ func (l *tcpListener) Init(md md.Metadata) (err error) {
ln := l.ln
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.ln = ln
+2 -1
View File
@@ -9,6 +9,7 @@ import (
"strconv"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/handler"
"github.com/go-gost/core/limiter"
"github.com/go-gost/core/limiter/traffic"
@@ -277,7 +278,7 @@ func (h *tunnelHandler) Handle(ctx context.Context, conn net.Conn, opts ...handl
}
if h.options.Auther != nil {
clientID, ok := h.options.Auther.Authenticate(ctx, user, pass)
clientID, ok := h.options.Auther.Authenticate(ctx, user, pass, auth.WithService(h.options.Service))
if !ok {
resp.Status = relay.StatusUnauthorized
resp.WriteTo(conn)
+2
View File
@@ -177,6 +177,7 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
switch proto {
case sniffing.ProtoHTTP:
return sniffer.HandleHTTP(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
@@ -184,6 +185,7 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
)
case sniffing.ProtoTLS:
return sniffer.HandleTLS(ctx, "tcp", conn,
sniffing.WithService(h.options.Service),
sniffing.WithDial(dial),
sniffing.WithDialTLS(dialTLS),
sniffing.WithRecorderObject(ro),
+3 -1
View File
@@ -51,7 +51,9 @@ func (h *unixHandler) handleHTTP(ctx context.Context, rw, cc io.ReadWriteCloser,
})
if h.options.Bypass != nil &&
h.options.Bypass.Contains(ctx, "tcp", host, bypass.WithPathOption(req.RequestURI)) {
h.options.Bypass.Contains(ctx, "tcp", host,
bypass.WithService(h.options.Service),
bypass.WithPathOption(req.RequestURI)) {
log.Debugf("bypass: %s %s", host, req.RequestURI)
return xbypass.ErrBypass
}
+13 -1
View File
@@ -48,9 +48,15 @@ func (p *grpcPlugin) GetRule(ctx context.Context, host string, opts ...ingress.O
return nil
}
var options ingress.Options
for _, opt := range opts {
opt(&options)
}
r, err := p.client.GetRule(ctx,
&proto.GetRuleRequest{
Host: host,
Service: options.Service,
Host: host,
})
if err != nil {
p.log.Error(err)
@@ -70,7 +76,13 @@ func (p *grpcPlugin) SetRule(ctx context.Context, rule *ingress.Rule, opts ...in
return false
}
var options ingress.Options
for _, opt := range opts {
opt(&options)
}
r, _ := p.client.SetRule(ctx, &proto.SetRuleRequest{
Service: options.Service,
Host: rule.Hostname,
Endpoint: rule.Endpoint,
})
+17 -1
View File
@@ -12,7 +12,8 @@ import (
)
type httpPluginGetRuleRequest struct {
Host string `json:"host"`
Service string `json:"service"`
Host string `json:"host"`
}
type httpPluginGetRuleResponse struct {
@@ -20,6 +21,7 @@ type httpPluginGetRuleResponse struct {
}
type httpPluginSetRuleRequest struct {
Service string `json:"service"`
Host string `json:"host"`
Endpoint string `json:"endpoint"`
}
@@ -58,6 +60,11 @@ func (p *httpPlugin) GetRule(ctx context.Context, host string, opts ...ingress.O
return nil
}
var options ingress.Options
for _, opt := range opts {
opt(&options)
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.url, nil)
if err != nil {
return nil
@@ -69,6 +76,9 @@ func (p *httpPlugin) GetRule(ctx context.Context, host string, opts ...ingress.O
q := req.URL.Query()
q.Set("host", host)
if options.Service != "" {
q.Set("service", options.Service)
}
req.URL.RawQuery = q.Encode()
resp, err := p.client.Do(req)
@@ -99,7 +109,13 @@ func (p *httpPlugin) SetRule(ctx context.Context, rule *ingress.Rule, opts ...in
return false
}
var options ingress.Options
for _, opt := range opts {
opt(&options)
}
rb := httpPluginSetRuleRequest{
Service: options.Service,
Host: rule.Hostname,
Endpoint: rule.Endpoint,
}
+8 -2
View File
@@ -14,6 +14,7 @@ const (
)
type Relay struct {
service string
pc1 net.PacketConn
pc2 net.PacketConn
bufferSize int
@@ -28,6 +29,11 @@ func NewRelay(pc1, pc2 net.PacketConn) *Relay {
}
}
func (r *Relay) WithService(service string) *Relay {
r.service = service
return r
}
func (r *Relay) WithBypass(bp bypass.Bypass) *Relay {
r.bypass = bp
return r
@@ -62,7 +68,7 @@ func (r *Relay) Run(ctx context.Context) (err error) {
return err
}
if r.bypass != nil && r.bypass.Contains(ctx, "udp", raddr.String()) {
if r.bypass != nil && r.bypass.Contains(ctx, "udp", raddr.String(), bypass.WithService(r.service)) {
if r.logger != nil {
r.logger.Warn("bypass: ", raddr)
}
@@ -99,7 +105,7 @@ func (r *Relay) Run(ctx context.Context) (err error) {
return err
}
if r.bypass != nil && r.bypass.Contains(ctx, "udp", raddr.String()) {
if r.bypass != nil && r.bypass.Contains(ctx, "udp", raddr.String(), bypass.WithService(r.service)) {
if r.logger != nil {
r.logger.Warn("bypass: ", raddr)
}
+13 -3
View File
@@ -18,6 +18,7 @@ import (
"strings"
"time"
"github.com/go-gost/core/auth"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/chain"
"github.com/go-gost/core/hop"
@@ -51,6 +52,7 @@ var (
)
type HandleOptions struct {
service string
dial func(ctx context.Context, network, address string) (net.Conn, error)
httpKeepalive bool
node *chain.Node
@@ -62,6 +64,12 @@ type HandleOptions struct {
type HandleOption func(opts *HandleOptions)
func WithService(service string) HandleOption {
return func(opts *HandleOptions) {
opts.service = service
}
}
func WithDial(dial func(ctx context.Context, network, address string) (net.Conn, error)) HandleOption {
return func(opts *HandleOptions) {
opts.dial = dial
@@ -241,7 +249,9 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho
})
if ho.bypass != nil &&
ho.bypass.Contains(ctx, "tcp", host, bypass.WithPathOption(req.RequestURI)) {
ho.bypass.Contains(ctx, "tcp", host,
bypass.WithService(ho.service),
bypass.WithPathOption(req.RequestURI)) {
ho.log.Debugf("bypass: %s %s", host, req.RequestURI)
res.StatusCode = http.StatusForbidden
ro.HTTP.StatusCode = res.StatusCode
@@ -426,7 +436,7 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriteCloser,
if httpSettings := node.Options().HTTP; httpSettings != nil {
if auther := httpSettings.Auther; auther != nil {
username, password, _ := req.BasicAuth()
id, ok := auther.Authenticate(ctx, username, password)
id, ok := auther.Authenticate(ctx, username, password, auth.WithService(ho.service))
if !ok {
res.StatusCode = http.StatusUnauthorized
ro.HTTP.StatusCode = res.StatusCode
@@ -807,7 +817,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
}
ro.Host = host
if ho.bypass != nil && ho.bypass.Contains(ctx, "tcp", host) {
if ho.bypass != nil && ho.bypass.Contains(ctx, "tcp", host, bypass.WithService(ho.service)) {
return xbypass.ErrBypass
}
}
+10 -3
View File
@@ -54,6 +54,7 @@ var (
)
type HandleOptions struct {
service string
dial func(ctx context.Context, network, address string) (net.Conn, error)
dialTLS func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error)
@@ -64,6 +65,12 @@ type HandleOptions struct {
type HandleOption func(opts *HandleOptions)
func WithService(service string) HandleOption {
return func(opts *HandleOptions) {
opts.service = service
}
}
func WithDial(dial func(ctx context.Context, network, address string) (net.Conn, error)) HandleOption {
return func(opts *HandleOptions) {
opts.dial = dial
@@ -170,7 +177,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, network string, conn net.Conn,
"host": host,
})
if ho.bypass != nil && ho.bypass.Contains(ctx, network, host) {
if ho.bypass != nil && ho.bypass.Contains(ctx, network, host, bypass.WithService(ho.service)) {
return xbypass.ErrBypass
}
}
@@ -600,7 +607,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, network string, conn net.Conn,
}
ro.Host = host
if ho.bypass != nil && ho.bypass.Contains(ctx, network, host) {
if ho.bypass != nil && ho.bypass.Contains(ctx, network, host, bypass.WithService(ho.service)) {
return xbypass.ErrBypass
}
}
@@ -624,7 +631,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, network string, conn net.Conn,
if host == "" {
host = ro.Host
}
if h.MitmBypass == nil || !h.MitmBypass.Contains(ctx, network, host) {
if h.MitmBypass == nil || !h.MitmBypass.Contains(ctx, network, host, bypass.WithService(ho.service)) {
return h.terminateTLS(ctx, network, xnet.NewReadWriteConn(io.MultiReader(buf, conn), conn, conn), cc, clientHello, &ho)
}
}
+2 -2
View File
@@ -22,12 +22,12 @@ var (
// It authenticates user using a password.
type PasswordCallbackFunc func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error)
func PasswordCallback(au auth.Authenticator) PasswordCallbackFunc {
func PasswordCallback(service string, au auth.Authenticator) PasswordCallbackFunc {
if au == nil {
return nil
}
return func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
if _, ok := au.Authenticate(context.Background(), conn.User(), string(password)); ok {
if _, ok := au.Authenticate(context.Background(), conn.User(), string(password), auth.WithService(service)); ok {
return nil, nil
}
return nil, fmt.Errorf("password rejected for %s", conn.User())
+1 -1
View File
@@ -82,7 +82,7 @@ func (l *dtlsListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
+1 -1
View File
@@ -70,7 +70,7 @@ func (l *grpcListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
+1 -1
View File
@@ -107,7 +107,7 @@ func (l *h2Listener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
+1 -1
View File
@@ -97,7 +97,7 @@ func (l *http2Listener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
ln = tls.NewListener(
+1 -1
View File
@@ -69,7 +69,7 @@ func (l *mtcpListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.ln = ln
+1 -1
View File
@@ -68,7 +68,7 @@ func (l *mtlsListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.Listener = xtls.NewListener(ln, l.options.TLSConfig)
+1 -1
View File
@@ -112,7 +112,7 @@ func (l *mwsListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
+1 -1
View File
@@ -63,7 +63,7 @@ func (l *obfsListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
+1 -1
View File
@@ -63,7 +63,7 @@ func (l *obfsListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
+1 -1
View File
@@ -68,7 +68,7 @@ func (l *redirectListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.ln = ln
+1 -1
View File
@@ -83,7 +83,7 @@ func (l *rtcpListener) Accept() (conn net.Conn, err error) {
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.setListener(ln)
+2 -2
View File
@@ -70,13 +70,13 @@ func (l *sshListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.Listener = ln
config := &ssh.ServerConfig{
PasswordCallback: ssh_util.PasswordCallback(l.options.Auther),
PasswordCallback: ssh_util.PasswordCallback(l.options.Service, l.options.Auther),
PublicKeyCallback: ssh_util.PublicKeyCallback(l.md.authorizedKeys),
}
config.AddHostKey(l.md.signer)
+2 -2
View File
@@ -78,13 +78,13 @@ func (l *sshdListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.Listener = ln
config := &ssh.ServerConfig{
PasswordCallback: ssh_util.PasswordCallback(l.options.Auther),
PasswordCallback: ssh_util.PasswordCallback(l.options.Service, l.options.Auther),
PublicKeyCallback: ssh_util.PublicKeyCallback(l.md.authorizedKeys),
}
config.AddHostKey(l.md.signer)
+1 -1
View File
@@ -66,7 +66,7 @@ func (l *tcpListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.ln = ln
+1 -1
View File
@@ -64,7 +64,7 @@ func (l *tlsListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.ln = xtls.NewListener(ln, l.options.TLSConfig)
+1 -1
View File
@@ -52,7 +52,7 @@ func (l *unixListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
l.ln = ln
+1 -1
View File
@@ -107,7 +107,7 @@ func (l *wsListener) Init(md md.Metadata) (err error) {
ln = proxyproto.WrapListener(l.options.ProxyProtocol, ln, 10*time.Second)
ln = metrics.WrapListener(l.options.Service, ln)
ln = stats.WrapListener(ln, l.options.Stats)
ln = admission.WrapListener(l.options.Admission, ln)
ln = admission.WrapListener(l.options.Service, l.options.Admission, ln)
ln = limiter_wrapper.WrapListener(l.options.Service, ln, l.options.TrafficLimiter)
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
+1 -1
View File
@@ -59,7 +59,7 @@ func NewService(network, addr string, opts ...Option) (service.Service, error) {
mux.Handle(options.path, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if options.auther != nil {
u, p, _ := r.BasicAuth()
if _, ok := options.auther.Authenticate(r.Context(), u, p); !ok {
if _, ok := options.auther.Authenticate(r.Context(), u, p, auth.WithService("@metrics")); !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}
+1 -1
View File
@@ -246,7 +246,7 @@ func (s *defaultService) Serve() error {
}
}
if s.options.admission != nil &&
!s.options.admission.Admit(ctx, srcAddr.String()) {
!s.options.admission.Admit(ctx, srcAddr.String(), admission.WithService(s.name)) {
conn.Close()
log.Debugf("admission: %s is denied", srcAddr)
continue