From 815a6841ede179c3fc7047d27037ab818a2795fa Mon Sep 17 00:00:00 2001 From: Lukasz Raczylo Date: Thu, 12 Oct 2023 14:12:03 +0100 Subject: [PATCH] Add ability to set up allowed paths for proxying. --- README.md | 7 +++++++ main.go | 9 +++++++++ proxy.go | 9 ++++++++- server.go | 13 +++++++++++++ struct_config.go | 1 + 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b3ab1e4..03dc429 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ I wanted to monitor the queries and responses of our graphql endpoint. Still, we | security | Blocking schema introspection | | security | Rate limiting queries based on user role | | security | Blocking mutations in read-only mode | +| security | Allow access only to listed URLs | ### Configuration @@ -49,6 +50,7 @@ I wanted to monitor the queries and responses of our graphql endpoint. Still, we | `BLOCK_SCHEMA_INTROSPECTION`| Blocks the schema introspection | `false` | | `ENABLE_ACCESS_LOG` | Enable the access log | `false` | | `READ_ONLY_MODE` | Enable the read only mode | `false` | +| `ALLOWED_URLS` | Allow access only to certain URLs | `/v1/graphql,/v1/version` | ### Caching @@ -101,6 +103,11 @@ If rate limit has been reached - the proxy will return `429 Too Many Requests` e You can enable the read-only mode by setting the `READ_ONLY_MODE` environment variable to `true` - which will block all the `mutation` queries. +### Allowing access to listed URLs + +You can allow access only to certain URLs by setting the `ALLOWED_URLS` environment variable to a comma-separated list of URLs. If enabled - other URLs will return `403 Forbidden` error and request will **not** reach the proxied service. + + ### Monitoring endpoint Example metrics produced by the proxy: diff --git a/main.go b/main.go index 77fc396..22ed081 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,8 @@ package main import ( + "strings" + "github.com/gookit/goutil/envutil" graphql "github.com/lukaszraczylo/go-simple-graphql" libpack_config "github.com/lukaszraczylo/graphql-monitoring-proxy/config" @@ -33,6 +35,13 @@ func parseConfig() { c.Client.GQLClient.SetEndpoint(c.Server.HostGraphQL) c.Server.AccessLog = envutil.GetBool("ENABLE_ACCESS_LOG", false) c.Server.ReadOnlyMode = envutil.GetBool("READ_ONLY_MODE", false) + c.Server.AllowURLs = func() []string { + urls := envutil.Getenv("ALLOWED_URLS", "") + if urls == "" { + return nil + } + return strings.Split(urls, ",") + }() cfg = &c enableCache() // takes close to no resources, but can be used with dynamic query cache loadRatelimitConfig() diff --git a/proxy.go b/proxy.go index bfcc9f4..e815a0f 100644 --- a/proxy.go +++ b/proxy.go @@ -9,8 +9,15 @@ import ( ) func proxyTheRequest(c *fiber.Ctx) error { + if !checkAllowedURLs(c) { + cfg.Logger.Error("Request blocked", map[string]interface{}{"path": c.Path()}) + cfg.Monitoring.Increment(libpack_monitoring.MetricsSkipped, nil) + c.Status(403).SendString("Request blocked - not allowed URL") + return nil + } + c.Request().Header.Add("X-Real-IP", c.IP()) - c.Request().Header.Add("X-Forwarded-For", c.IP()) + c.Request().Header.Add(fiber.HeaderXForwardedFor, string(c.Request().Header.Peek("X-Forwarded-For"))) proxy.WithTlsConfig(&tls.Config{ InsecureSkipVerify: true, diff --git a/server.go b/server.go index a45cf96..9a35811 100644 --- a/server.go +++ b/server.go @@ -31,6 +31,18 @@ func StartHTTPProxy() { } } +func checkAllowedURLs(c *fiber.Ctx) bool { + if len(cfg.Server.AllowURLs) == 0 { + return true + } + for _, allowedURL := range cfg.Server.AllowURLs { + if c.Path() == allowedURL { + return true + } + } + return false +} + func healthCheck(c *fiber.Ctx) error { // query := `{ __typename }` // _, err := cfg.Client.GQLClient.Query(query, nil, nil) @@ -131,6 +143,7 @@ func logAndMonitorRequest(c *fiber.Ctx, userID, opType, opName string, wasCached if cfg.Server.AccessLog { cfg.Logger.Info("Request processed", map[string]interface{}{ "ip": c.IP(), + "fwd-ip": string(c.Request().Header.Peek("X-Forwarded-For")), "user_id": userID, "op_type": opType, "op_name": opName, diff --git a/struct_config.go b/struct_config.go index 82335e3..2e28c56 100644 --- a/struct_config.go +++ b/struct_config.go @@ -19,6 +19,7 @@ type config struct { HostGraphQL string AccessLog bool ReadOnlyMode bool + AllowURLs []string } Client struct {