added auther option for node http settings

This commit is contained in:
ginuerzh 2024-01-27 21:16:46 +08:00
parent a618998b36
commit 8bdd7ee172
7 changed files with 52 additions and 42 deletions

View File

@ -54,7 +54,7 @@ func getConfig(ctx *gin.Context) {
if ok && ss != nil { if ok && ss != nil {
status := ss.Status() status := ss.Status()
svc.Status = &config.ServiceStatus{ svc.Status = &config.ServiceStatus{
CreateTime: status.CreateTime().UnixNano(), CreateTime: status.CreateTime().Unix(),
State: string(status.State()), State: string(status.State()),
} }
if st := status.Stats(); st != nil { if st := status.Stats(); st != nil {
@ -69,7 +69,7 @@ func getConfig(ctx *gin.Context) {
for _, ev := range status.Events() { for _, ev := range status.Events() {
if !ev.Time.IsZero() { if !ev.Time.IsZero() {
svc.Status.Events = append(svc.Status.Events, config.ServiceEvent{ svc.Status.Events = append(svc.Status.Events, config.ServiceEvent{
Time: ev.Time.UnixNano(), Time: ev.Time.Unix(),
Msg: ev.Message, Msg: ev.Message,
}) })
} }

View File

@ -359,13 +359,15 @@ type ForwardNodeConfig struct {
Bypasses []string `yaml:",omitempty" json:"bypasses,omitempty"` Bypasses []string `yaml:",omitempty" json:"bypasses,omitempty"`
HTTP *HTTPNodeConfig `yaml:",omitempty" json:"http,omitempty"` HTTP *HTTPNodeConfig `yaml:",omitempty" json:"http,omitempty"`
TLS *TLSNodeConfig `yaml:",omitempty" json:"tls,omitempty"` TLS *TLSNodeConfig `yaml:",omitempty" json:"tls,omitempty"`
Auth *AuthConfig `yaml:",omitempty" json:"auth,omitempty"` // DEPRECATED by HTTP.Auth
Metadata map[string]any `yaml:",omitempty" json:"metadata,omitempty"` Auth *AuthConfig `yaml:",omitempty" json:"auth,omitempty"`
Metadata map[string]any `yaml:",omitempty" json:"metadata,omitempty"`
} }
type HTTPNodeConfig struct { type HTTPNodeConfig struct {
Host string `yaml:",omitempty" json:"host,omitempty"` Host string `yaml:",omitempty" json:"host,omitempty"`
Header map[string]string `yaml:",omitempty" json:"header,omitempty"` Header map[string]string `yaml:",omitempty" json:"header,omitempty"`
Auth *AuthConfig `yaml:",omitempty" json:"auth,omitempty"`
} }
type TLSNodeConfig struct { type TLSNodeConfig struct {

View File

@ -168,10 +168,28 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
chain.NetworkNodeOption(cfg.Network), chain.NetworkNodeOption(cfg.Network),
} }
if cfg.HTTP != nil { if cfg.HTTP != nil {
opts = append(opts, chain.HTTPNodeOption(&chain.HTTPNodeSettings{ settings := &chain.HTTPNodeSettings{
Host: cfg.HTTP.Host, Host: cfg.HTTP.Host,
Header: cfg.HTTP.Header, Header: cfg.HTTP.Header,
})) }
auth := cfg.HTTP.Auth
if auth == nil {
auth = cfg.Auth
}
if auth != nil {
settings.Auther = xauth.NewAuthenticator(
xauth.AuthsOption(map[string]string{auth.Username: auth.Password}),
xauth.LoggerOption(log.WithFields(map[string]any{
"kind": "node",
"node": cfg.Name,
"addr": cfg.Addr,
"host": cfg.Host,
"protocol": cfg.Protocol,
})),
)
}
opts = append(opts, chain.HTTPNodeOption(settings))
} }
if cfg.TLS != nil { if cfg.TLS != nil {
tlsCfg := &chain.TLSNodeSettings{ tlsCfg := &chain.TLSNodeSettings{
@ -185,18 +203,5 @@ func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.No
} }
opts = append(opts, chain.TLSNodeOption(tlsCfg)) opts = append(opts, chain.TLSNodeOption(tlsCfg))
} }
if cfg.Auth != nil {
opts = append(opts, chain.AutherNodeOption(
xauth.NewAuthenticator(
xauth.AuthsOption(map[string]string{cfg.Auth.Username: cfg.Auth.Password}),
xauth.LoggerOption(logger.Default().WithFields(map[string]any{
"kind": "node",
"node": cfg.Name,
"addr": cfg.Addr,
"host": cfg.Host,
"protocol": cfg.Protocol,
})),
)))
}
return chain.NewNode(cfg.Name, cfg.Addr, opts...), nil return chain.NewNode(cfg.Name, cfg.Addr, opts...), nil
} }

2
go.mod
View File

@ -7,7 +7,7 @@ require (
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/gin-contrib/cors v1.5.0 github.com/gin-contrib/cors v1.5.0
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
github.com/go-gost/core v0.0.0-20240103125300-5a427b4eaf99 github.com/go-gost/core v0.0.0-20240127130604-04314fa08476
github.com/go-gost/gosocks4 v0.0.1 github.com/go-gost/gosocks4 v0.0.1
github.com/go-gost/gosocks5 v0.4.0 github.com/go-gost/gosocks5 v0.4.0
github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a github.com/go-gost/plugin v0.0.0-20240103125338-9c84e29cb81a

2
go.sum
View File

@ -51,6 +51,8 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-gost/core v0.0.0-20240103125300-5a427b4eaf99 h1:/0hmilnQBEDlOaRcO+TlwaHH8a5ig6nc2aAsU4FGZcw= github.com/go-gost/core v0.0.0-20240103125300-5a427b4eaf99 h1:/0hmilnQBEDlOaRcO+TlwaHH8a5ig6nc2aAsU4FGZcw=
github.com/go-gost/core v0.0.0-20240103125300-5a427b4eaf99/go.mod h1:ndkgWVYRLwupVaFFWv8ML1Nr8tD3xhHK245PLpUDg4E= github.com/go-gost/core v0.0.0-20240103125300-5a427b4eaf99/go.mod h1:ndkgWVYRLwupVaFFWv8ML1Nr8tD3xhHK245PLpUDg4E=
github.com/go-gost/core v0.0.0-20240127130604-04314fa08476 h1:4TA4ErfFw2CsVv5K5oqqYpUn68aZFrV+ONb4aGPJ1QQ=
github.com/go-gost/core v0.0.0-20240127130604-04314fa08476/go.mod h1:ndkgWVYRLwupVaFFWv8ML1Nr8tD3xhHK245PLpUDg4E=
github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s= 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/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
github.com/go-gost/gosocks5 v0.4.0 h1:EIrOEkpJez4gwHrMa33frA+hHXJyevjp47thpMQsJzI= github.com/go-gost/gosocks5 v0.4.0 h1:EIrOEkpJez4gwHrMa33frA+hHXJyevjp47thpMQsJzI=

View File

@ -247,18 +247,19 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, remot
}) })
log.Debugf("find node for host %s -> %s(%s)", req.Host, target.Name, target.Addr) log.Debugf("find node for host %s -> %s(%s)", req.Host, target.Name, target.Addr)
if auther := target.Options().Auther; auther != nil {
username, password, _ := req.BasicAuth()
id, ok := auther.Authenticate(ctx, username, password)
if !ok {
resp.StatusCode = http.StatusUnauthorized
resp.Header.Set("WWW-Authenticate", "Basic")
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)
return resp.Write(rw)
}
ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(id))
}
if httpSettings := target.Options().HTTP; httpSettings != nil { if httpSettings := target.Options().HTTP; httpSettings != nil {
if auther := httpSettings.Auther; auther != nil {
username, password, _ := req.BasicAuth()
id, ok := auther.Authenticate(ctx, username, password)
if !ok {
resp.StatusCode = http.StatusUnauthorized
resp.Header.Set("WWW-Authenticate", "Basic")
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)
return resp.Write(rw)
}
ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(id))
}
if httpSettings.Host != "" { if httpSettings.Host != "" {
req.Host = httpSettings.Host req.Host = httpSettings.Host
} }

View File

@ -248,18 +248,18 @@ func (h *forwardHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, remot
}) })
log.Debugf("find node for host %s -> %s(%s)", req.Host, target.Name, target.Addr) log.Debugf("find node for host %s -> %s(%s)", req.Host, target.Name, target.Addr)
if auther := target.Options().Auther; auther != nil {
username, password, _ := req.BasicAuth()
id, ok := auther.Authenticate(ctx, username, password)
if !ok {
resp.StatusCode = http.StatusUnauthorized
resp.Header.Set("WWW-Authenticate", "Basic")
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)
return resp.Write(rw)
}
ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(id))
}
if httpSettings := target.Options().HTTP; httpSettings != nil { if httpSettings := target.Options().HTTP; httpSettings != nil {
if auther := httpSettings.Auther; auther != nil {
username, password, _ := req.BasicAuth()
id, ok := auther.Authenticate(ctx, username, password)
if !ok {
resp.StatusCode = http.StatusUnauthorized
resp.Header.Set("WWW-Authenticate", "Basic")
log.Warnf("node %s(%s) 401 unauthorized", target.Name, target.Addr)
return resp.Write(rw)
}
ctx = ctxvalue.ContextWithClientID(ctx, ctxvalue.ClientID(id))
}
if httpSettings.Host != "" { if httpSettings.Host != "" {
req.Host = httpSettings.Host req.Host = httpSettings.Host
} }