mirror of
https://github.com/lukaszraczylo/graphql-monitoring-proxy.git
synced 2026-06-05 23:03:48 +00:00
Add ability to set up allowed paths for proxying.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -19,6 +19,7 @@ type config struct {
|
||||
HostGraphQL string
|
||||
AccessLog bool
|
||||
ReadOnlyMode bool
|
||||
AllowURLs []string
|
||||
}
|
||||
|
||||
Client struct {
|
||||
|
||||
Reference in New Issue
Block a user