Skip to content

Commit

Permalink
only allowed can check all status
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthurHlt committed Sep 9, 2023
1 parent 8f1e10c commit 714515c
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 19 deletions.
20 changes: 19 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,24 @@ func (a *App) makeMetricsProxy() *proxmetrics.Fetcher {
)
}

func (a *App) makeStatusHandler() *proxmetrics.StatusHandler {
_, local4, _ := net.ParseCIDR("127.0.0.1/32") // nolint:errcheck
_, local6, _ := net.ParseCIDR("::1/128") // nolint:errcheck
allowed := []*config.CIDR{
{
IpNet: local4,
},
{
IpNet: local6,
},
}
return proxmetrics.NewStatusHandler(
proxmetrics.NewStatusCollector(a.gslocConsul),
append(allowed, a.cnf.MetricsConfig.AllowedInspect...),
a.cnf.MetricsConfig.TrustXFF,
)
}

func (a *App) loadGslocConsul() error {
if a.onlyServeDns {
a.entry.Info("Only serve DNS: no gsloc consul for api")
Expand Down Expand Up @@ -264,7 +282,7 @@ func (a *App) Run() error {
grpcServer := servers.NewHTTPServer(
a.cnf.HTTPServer,
a.hcHandler, a.grpcServer,
a.makeMetricsProxy(), proxmetrics.NewStatusCollector(a.gslocConsul),
a.makeMetricsProxy(), a.makeStatusHandler(),
)
grpcServer.Run(a.ctx)
}()
Expand Down
11 changes: 11 additions & 0 deletions config/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
var validateNameForPath = regexp.MustCompile(`(\s|_)`).MatchString

type MetricsConfig struct {
AllowedInspect []*CIDR `yaml:"allowed_inspect"`
TrustXFF bool `yaml:"trust_xff"`
ProxyMetricsConfig *ProxyMetricsConfig `yaml:"proxy"`
}

Expand All @@ -22,6 +24,15 @@ func (u *MetricsConfig) init() error {
return nil
}

func (u *MetricsConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
type plain MetricsConfig
err := unmarshal((*plain)(u))
if err != nil {
return err
}
return u.init()
}

type ProxyMetricsConfig struct {
Targets []*ProxyMetricsTarget `yaml:"targets"`
}
Expand Down
57 changes: 53 additions & 4 deletions proxmetrics/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,73 @@ package proxmetrics

import (
gslbsvc "github.com/orange-cloudfoundry/gsloc-go-sdk/gsloc/services/gslb/v1"
"github.com/orange-cloudfoundry/gsloc/config"
"github.com/orange-cloudfoundry/gsloc/disco"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"net"
"net/http"
"strings"
)

type StatusCollector struct {
desc *prometheus.Desc
gslocConsul *disco.GslocConsul
}

func StatusHandler(collector *StatusCollector) http.Handler {
type StatusHandler struct {
metricHandler http.Handler
allowedInspect []*config.CIDR
trustXFF bool
}

func NewStatusHandler(collector *StatusCollector, allowedInspect []*config.CIDR, trustXFF bool) *StatusHandler {
registry := prometheus.NewRegistry()
registry.MustRegister(collector)
return promhttp.InstrumentMetricHandler(
registry, promhttp.HandlerFor(registry, promhttp.HandlerOpts{}),
)
return &StatusHandler{
metricHandler: promhttp.InstrumentMetricHandler(
registry, promhttp.HandlerFor(registry, promhttp.HandlerOpts{}),
),
allowedInspect: allowedInspect,
trustXFF: trustXFF,
}
}

func (s *StatusHandler) isAllowedInspect(req *http.Request) bool {
if s.remoteAddrIsAllowed(req.RemoteAddr) {
return true
}
if !s.trustXFF || req.Header.Get("X-Forwarded-For") == "" {
return false
}
allIps := strings.Split(req.Header.Get("X-Forwarded-For"), ",")
if s.remoteAddrIsAllowed(allIps[0]) {
return true
}
return false
}

func (s *StatusHandler) remoteAddrIsAllowed(remoteAddr string) bool {
if strings.Contains(remoteAddr, ":") {
remoteAddr, _, _ = net.SplitHostPort(remoteAddr) // nolint: errcheck
}
remoteAddrIp := net.ParseIP(remoteAddr)
for _, cidr := range s.allowedInspect {
if cidr.IpNet.Contains(remoteAddrIp) {
return true
}
}
return false
}

func (s *StatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !s.isAllowedInspect(r) {
http.Error(w, "Not allowed", http.StatusForbidden)
return
}
s.metricHandler.ServeHTTP(w, r)
return
}

func NewStatusCollector(gslocConsul *disco.GslocConsul) *StatusCollector {
Expand Down
28 changes: 14 additions & 14 deletions servers/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,28 @@ import (
)

type HTTPServer struct {
mux *mux.Router
cnf *config.HTTPServerConfig
hcker *healthchecks.HcHandler
grpcServ *grpc.Server
metricsFetcher *proxmetrics.Fetcher
statusCollector *proxmetrics.StatusCollector
mux *mux.Router
cnf *config.HTTPServerConfig
hcker *healthchecks.HcHandler
grpcServ *grpc.Server
metricsFetcher *proxmetrics.Fetcher
statusHandler *proxmetrics.StatusHandler
}

func NewHTTPServer(
cnf *config.HTTPServerConfig,
hcker *healthchecks.HcHandler,
grpcServ *grpc.Server,
metricsFetcher *proxmetrics.Fetcher,
statusCollector *proxmetrics.StatusCollector,
statusHandler *proxmetrics.StatusHandler,
) *HTTPServer {
return &HTTPServer{
mux: mux.NewRouter(),
cnf: cnf,
hcker: hcker,
grpcServ: grpcServ,
metricsFetcher: metricsFetcher,
statusCollector: statusCollector,
mux: mux.NewRouter(),
cnf: cnf,
hcker: hcker,
grpcServ: grpcServ,
metricsFetcher: metricsFetcher,
statusHandler: statusHandler,
}
}

Expand All @@ -55,7 +55,7 @@ func (s *HTTPServer) ServeHTTP(writer http.ResponseWriter, request *http.Request

func (s *HTTPServer) Run(ctx context.Context) {
s.mux.Path("/metrics").Handler(s.metricsFetcher)
s.mux.Path("/metrics/status").Handler(proxmetrics.StatusHandler(s.statusCollector))
s.mux.Path("/metrics/status").Handler(s.statusHandler)
s.mux.Methods("POST").Path("/hc/{fqdn}/member/{ip}").Handler(s.hcker)

srvTls := &http.Server{
Expand Down

0 comments on commit 714515c

Please sign in to comment.