traefik_modsecurity_plugin

package module
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2024 License: Apache-2.0 Imports: 16 Imported by: 0

README

Traefik Modsecurity Plugin

Banner

this is a fork of the original: https://github.com/acouvreur/traefik-modsecurity-plugin

This fork introduces alpine images, and a custom http.transport, and a caching layer once mod-security has processed a request

see: https://github.com/traefik/plugindemo#troubleshooting


Traefik plugin to proxy requests to owasp/modsecurity-crs:apache

Github Actions Go Report Go Version Latest Release

Demo

Demo with WAF intercepting relative access in query param.

Demo

Usage (docker-compose.yml)

See docker-compose.yml

  1. docker-compose up
  2. Go to http://localhost/website, the request is received without warnings
  3. Go to http://localhost/website?test=../etc, the request is intercepted and returned with 403 Forbidden by owasp/modsecurity
  4. You can you bypass the WAF and check attacks at http://localhost/bypass?test=../etc

How it works

This is a very simple plugin that proxies the query to the owasp/modsecurity apache container.

The plugin checks that the response from the waf container hasn't an http code > 400 before forwarding the request to the real service.

If it is > 400, then the error page is returned instead.

The dummy service is created so the waf container forward the request to a service and respond with 200 OK all the time.

NEW: Caching modsecurity responses helps to minimize the overhead of processing every request and improves performance. By generating cache keys based on various factors like the request method, host, request URI, headers, and remote address, we can ensure that different requests are treated uniquely, while similar requests can be served from the plugins modsecurity response cache. This approach helps in reducing the load on the modsecurity instance and improves response times for requests. You can tune this to your liking but we recommend the following options:

Configuration

This plugin supports these configuration:

  • modSecurityUrl: (mandatory) it's the URL for the owasp/modsecurity container.

  • timeoutMillis: (optional) timeout in milliseconds for the http client to talk with modsecurity container. (default 2 seconds)

  • maxBodySize: (optional) it's the maximum limit for requests body size. Requests exceeding this value will be rejected using HTTP 413 Request Entity Too Large. The default value for this parameter is 10MB. Zero means "use default value".

  • cacheConditionsMethods: (optional) An array of HTTP methods for which caching is allowed. (default ["GET"])

  • cacheConditionsNoBody: (optional) Specifies if requests with no body (content-length of 0) should be cached. ( default true)

  • cacheKeyIncludeHost: (optional) Specifies if the host should be included in the cache key. (default true)

  • cacheKeyIncludeRemoteAddress: (optional) Speifics if the remote request address should be included in the cache key (default true)

  • cacheKeyIncludeHeaders: (optional) Specifies if the headers should be included in the cache key. (default true)

  • cacheKeyHeaders: (optional) An array of specific headers to be included in the cache key when CacheKeyIncludeHeaders is true. (ie: the default ["User-Agent"])

Note: some headers are ALWAYS blacklisted, and even if you list them here, they will still not be cached:

Authorization: *, Set-Cookie: *, Cache-Control: no-store, Pragma: no-cache, Expires: -1 (date in the past)

Note: body of every (non-cached) request will be buffered in memory while the request is in-flight (i.e.: during the security check and during the request processing by traefik and the backend), so you may want to tune maxBodySize depending on how much RAM you have.

Local development (docker-compose.local.yml)

See docker-compose.local.yml

docker-compose -f docker-compose.local.yml up to load the local plugin

Documentation

Overview

Package traefik_modsecurity_plugin is a plugin for the Traefik reverse proxy that integrates ModSecurity, a widely-used Web Application Firewall (WAF).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error)

New create a new Modsecurity plugin with the given configuration. It returns an HTTP handler that can be integrated into the Traefik middleware chain.

Types

type CacheKeyConditions

type CacheKeyConditions struct {
	Methods []string
	NoBody  *bool
}

CacheKeyConditions contains the conditions for generating a cache key.

func (*CacheKeyConditions) Check

func (c *CacheKeyConditions) Check(req *http.Request) bool

Check evaluates if the current request meets the caching conditions.

type CacheKeyOptions

type CacheKeyOptions struct {
	IncludeHeaders       *bool
	Headers              []string
	IncludeHost          *bool
	IncludeRemoteAddress *bool
}

CacheKeyOptions contains the options for generating a cache key.

type Config

type Config struct {
	TimeoutMillis  int64  `json:"timeoutMillis"`            // Timeout for HTTP requests to the ModSecurity server.
	ModSecurityUrl string `json:"modSecurityUrl,omitempty"` // The URL of the ModSecurity server.
	MaxBodySize    int64  `json:"maxBodySize"`              // Maximum allowed size of the request body.

	// Enable or disable cache globally.
	CacheEnabled *bool `json:"cacheEnabled,omitempty"`

	// CacheConditionsMethods specifies the HTTP methods for which caching is allowed.
	CacheConditionsMethods []string `json:"cacheConditionsMethods,omitempty"`

	// CacheConditionsNoBody specifies if requests with no body (content-length of 0) should be cached.
	CacheConditionsNoBody *bool `json:"cacheConditionsNoBody,omitempty"`

	// CacheKeyIncludeHeaders specifies if the headers should be included in the cache key.
	CacheKeyIncludeHeaders *bool `json:"cacheKeyIncludeHeaders,omitempty"`

	// CacheKeyHeaders lists the specific headers to be included in the cache key when CacheKeyIncludeHeaders is true.
	CacheKeyHeaders []string `json:"cacheKeyHeaders,omitempty"`

	// CacheKeyIncludeHost specifies if the host should be included in the cache key.
	CacheKeyIncludeHost *bool `json:"cacheKeyIncludeHost,omitempty"`

	// CacheKeyIncludeRemoteAddress specifies if the remote address should be included in the cache key.
	CacheKeyIncludeRemoteAddress *bool `json:"cacheKeyIncludeRemoteAddress,omitempty"`

	// CacheConditions and CacheKey are structs to store parsed configurations for easy access.
	CacheConditions CacheKeyConditions
	CacheKey        CacheKeyOptions
}

Config holds the plugin configuration.

func CreateConfig

func CreateConfig() *Config

CreateConfig creates a default plugin configuration with predefined values.

type Modsecurity

type Modsecurity struct {
	// contains filtered or unexported fields
}

func (*Modsecurity) GetCachedResponse

func (a *Modsecurity) GetCachedResponse(req *http.Request, options CacheKeyOptions) (*http.Response, error)

func (*Modsecurity) HandleCacheAndForwardRequest

func (a *Modsecurity) HandleCacheAndForwardRequest(req *http.Request) (*http.Response, error)

func (*Modsecurity) HandleRequestBodyMaxSize

func (a *Modsecurity) HandleRequestBodyMaxSize(rw http.ResponseWriter, req *http.Request) error

HandleRequestBodyMaxSize - handle request body max size

func (*Modsecurity) PrepareForwardedRequest

func (a *Modsecurity) PrepareForwardedRequest(req *http.Request) (*http.Response, error)

PrepareForwardedRequest prepares the request to be forwarded to modsecurity.

func (*Modsecurity) ServeHTTP

func (a *Modsecurity) ServeHTTP(rw http.ResponseWriter, req *http.Request)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL