84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
package network
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
|
|
"forge.cadoles.com/cadoles/bouncer/internal/proxy/director/layer/authn"
|
|
"forge.cadoles.com/cadoles/bouncer/internal/store"
|
|
"github.com/pkg/errors"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"gitlab.com/wpetit/goweb/logger"
|
|
)
|
|
|
|
type Authenticator struct {
|
|
}
|
|
|
|
// Authenticate implements authn.Authenticator.
|
|
func (a *Authenticator) Authenticate(w http.ResponseWriter, r *http.Request, layer *store.Layer) (*authn.User, error) {
|
|
ctx := r.Context()
|
|
|
|
options, err := fromStoreOptions(layer.Options)
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
matches, err := a.matchAnyAuthorizedCIDRs(ctx, r.RemoteAddr, options.AuthorizedCIDRs)
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
user := authn.NewUser(r.RemoteAddr, map[string]any{})
|
|
|
|
if !matches {
|
|
metricForbiddenTotal.With(prometheus.Labels{
|
|
metricLabelLayer: string(layer.Name),
|
|
metricLabelProxy: string(layer.Proxy),
|
|
}).Add(1)
|
|
|
|
return user, errors.WithStack(authn.ErrForbidden)
|
|
}
|
|
|
|
metricAuthorizedTotal.With(prometheus.Labels{
|
|
metricLabelLayer: string(layer.Name),
|
|
metricLabelProxy: string(layer.Proxy),
|
|
}).Add(1)
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (a *Authenticator) matchAnyAuthorizedCIDRs(ctx context.Context, remoteHostPort string, CIDRs []string) (bool, error) {
|
|
remoteHost, _, err := net.SplitHostPort(remoteHostPort)
|
|
if err != nil {
|
|
return false, errors.WithStack(err)
|
|
}
|
|
|
|
remoteAddr := net.ParseIP(remoteHost)
|
|
if remoteAddr == nil {
|
|
return false, errors.Errorf("remote host '%s' is not a valid ip address", remoteHost)
|
|
}
|
|
|
|
for _, rawCIDR := range CIDRs {
|
|
_, net, err := net.ParseCIDR(rawCIDR)
|
|
if err != nil {
|
|
return false, errors.WithStack(err)
|
|
}
|
|
|
|
match := net.Contains(remoteAddr)
|
|
if !match {
|
|
continue
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
logger.Debug(ctx, "comparing remote host with authorized cidrs", logger.F("remoteAddr", remoteAddr))
|
|
|
|
return false, nil
|
|
}
|
|
|
|
var (
|
|
_ authn.Authenticator = &Authenticator{}
|
|
)
|